Styling Select-Option (almost) without JavaScript

Styling some standard elements is a pretty non-trivial task.

Of course, a good specialist can stylize anything, but everything depends on the complexity of this action.

It will take quite a bit of time to stylize radio buttons and checkboxes - the idea of ​​styling a label with hidden input is not new, and has been used everywhere for a long time.

To stylize the rest - there is JavaScript.

Today I want to tell you about how it is relatively simple to style drop-down lists with minimal JavaScript code (from 0 to 26 lines) and minimal additional HTML markup.

Easy selects withoud JavaScript (almost)

The other day, as often happens, I had a need to style a drop-down list. However, it became a drop-down list only in the mobile version, before that it behaved like the most ordinary group of radio buttons.

And so, when I was almost finished writing another creepy construction designed to replace the unfortunate Select, I had a question:

Why?

Usually this question leads to wise procrastination, a rethinking of life, etc., but this time something went wrong, and I realized that the question was really good, and most importantly - useful.



A small educational program:

So, for those who are in the tank, as well as those to whom the drop-down lists cause so much pain that they decided to forget about them as a nightmare, I will slightly (really) remind you what it is.

Drop-down lists consist of 2 main elements :

  1. Select - container for the entire list
  2. Option - list item

Sometimes OptGroup is also used (a group of list items), but its implementation so far remains in JavaScript.

The main functionality of the drop-down list is sending information about the selected item (s) to the server.

For completeness, here is a list of element attributes (so that you can estimate how many of them will be implemented):

  1. Select - disabled , form , multiple , name , required , size
  2. Option - disabled , label , selected , value

On this, perhaps, we will finish with the description, and move on to implementation .



Many words have already been written, therefore - closer to the code:

<form>
  <div class="content">
    <h3 class="title"> 0 </h3>

    <input id="selectName0" type="radio" value="0" name="selectName" />
    <label for="selectName0"> 0 </label>
    <input id="selectName1" type="radio" value="1" name="selectName" />
    <label for="selectName1"> 1 </label>
    <input id="selectName2" type="radio" value="2" name="selectName" />
    <label for="selectName2"> 2 </label>
  </div>
</form>

So what is this code good for? (everything that can be dispensed with when explaining is removed specially)

Let's note which items from the Select and Option functionality have automatically become possible due to the use of input + label:

  1. Select - form, name, required
  2. Option - disabled, label, selected, value

And that’s all that remains to be implemented:

  1. Select - disabled, multiple, size
  2. Option - fully implemented

Just by adding the input + label bundles, we reduced the list of necessary functionality from 10 points to 3. Not bad, but this is not the end, right?

To implement the item Select.multiple (multiple choice) - just do this:

<form>
  <div class="content">
    <input id="selectName0" type="checkbox" value="0" name="selectName" />
    <label for="selectName0"> 0 </label>
    <input id="selectName1" type="checkbox" value="1" name="selectName" />
    <label for="selectName1"> 1 </label>
    <input id="selectName2" type="checkbox" value="2" name="selectName" />
    <label for="selectName2"> 2 </label>
  </div>
</form>

We just change the type of inputs from Radio to Checkbox , and get an almost complete analog of multiple .

The difference is that for multiple selection you do not need to hold down ctrl (well, if someone wants to completely imitate the functionality - JavaScript to help).

What is left?

  1. Select - disabled, size
  2. Option - fully implemented

Well, both Select.disabled and Select.size are extremely simple to implement using CSS:

  • Select.size - what size you set will be. You just need to add the container.
  • Select.disabled - for the container, you need to add pointer-events: none to cancel the reaction to any user actions (hover, clicks, etc.), well, you can make it a little transparent.

So, the main functionality is. What is missing?

You also need to add the header autocomplete for the drop-down menu with the only choice, and there will also be a problem when resetting the form ( Reset button ), because the title will not be reset. But even this is completely solvable (using JavaScript).



And now - examples:

A little implementation (drop-down menu with a single choice):


And a little more (not a drop-down menu with multiple choices):


Bonus: I don’t know why I did this, but ... a drop-down menu with a single choice and a CSS-based header reset:






Why is this needed?

Due to the fact that judging by the comments, not everyone understands why this code will be useful, I consider it necessary to give some clarification.

When styling drop-down lists of the form:
<select>
  <option> 1</option>
  <option> 2</option>
</select>

There are serious styling limitations. Therefore, they are replaced with simple lists:
<ul>
  <li> 1</li>
  <li> 2</li>
</ul>

with which all the necessary functionality is hung using JavaScript.

Since the lists initially do not interact with forms in any way , this causes problems.

Not only is it necessary to implement all the basic functionality:

  • switching points and their interaction
  • state (checked, disabled)
  • binding to the form and sending data to the server
  • initialization of initial data (autofill)
  • form reset (when you click on the "reset" button, the list must be returned to the state during initialization)


In fact, if something breaks in JavaScript, it doesn’t matter, because the script didn’t load, a bug arose, made corrections - if any problem occurs, the drop-down list turns into ... something that looks like a drop-down list, but does not work.
Generally. No way.


For the user, it will look like this: there is a drop-down list, but you cannot work with it.

For the server, this will look even “more fun” - a form has arrived in which there is not enough data. It’s good that such a situation was foreseen in advance during the development ... After all, it was foreseen, right?



Pros of the resulting solution:

  • ( ), . JavaScript ( ). , — . , — / — html ( JS), .
  • . , , ( ). ulli , .




(. , , JavaScript' / ):

  • tab
  • ( select -)
  • ( , )
  • select ( select . select)
  • , (JS )
  • ( OptGroup) (, )


As you can see, none of the above disadvantages is critical for the vast majority of lists, and if necessary is implemented using JavaScript, and therefore ...



Welcome to the world where your libraries for styling Select-Option-like lists will become a little smaller, and working with these lists without libraries will be almost comfortable!




UPD: as it turned out, in the case of checkboxes, the required attribute does not work correctly, and it also needs to be emulated using JavaScript (at the moment, all checkboxes marked as required become mandatory, and only they)

All Articles