Selects — everything you want to know
What is the select tag for?
Select is an HTML tag used usually in forms. It allows the user to choose one or more options from the list.
The HTML select element represents a control that provides a menu of options. Each menu option is defined by an option element nested inside the select. You can further nest option elements inside optgroup elements to create separate groups of options inside the dropdown.
Simple select code:
But how often do we get such simple requirements, hm? Usually, it needs a lot of customization. For example:
- the control should have a label,
- options should be displayed in groups,
- the second option should be available only after checking the box — I want it disabled until that time,
- I want Wild Thyme to be picked as default, cause it’s fabulous,
- it should display in the top of the document while the form will be at the bottom,
- it should get focus right when the page loads,
- it should send different values than given in content,
- and the user is obligated to make a choice before sending the form.
I also love tomatoes, so my widget code may look like that:
Which gives this result in the browser:
In this example single option was disabled, but we can disable the widget as well.
Select, as default, allows picking only one option. To allow multiple choice, we can use multiple attribute. In that case, the control appears already open with a scroll on the side. The number of visible options can be set by using size attribute.
If we do not set option value it will send text content.
So what about styling?
The MDN refers to selects as “the ugly” remainings of time before CSS was created. That means it is rendered not by the browser but by the operating system, and it cannot be easily styled by CSS.
At best, CSS can change a few properties, but it will not be reliable across browsers, and it will never be possible to fully control their appearance.
It looks like that:
What to do if we have to take control over select appearance? There are three options, depending on how advanced changes are needed:
- Style it with CSS
- Build a custom widget
- Use library
I would like to focus on some pros and cons of these three.
Styling select with CSS
The first thing that is recommended is to remove default system appearance, especially arrow, by using the code below:
Then we can replace it with whatever we want, but we have to remember that select does not allow :before /:after pseudoelements. We can go around and add it to the parent element.
Next, we can add some styling using the box model, font options, background and color. Selects, like buttons, inputs or textarea elements, do not inherit font-family and font-size from parents. We have set it separately:
As for the select options, we do not have much choice. We can change font, background and color, but nothing more.
The saddest thing is that, despite the efforts, every browser still can display it differently.
- it can be done
- styling options are limited
- we don’t have full control over the element
- styling changes may be not consistent across browsers
- you have to know the tricks
Altogether it’s nice to know how to style selects with CSS, but this approach can be useful only if we don’t have any particular requirements for the control appearance.
Building a custom widget
The next approach is focused on having full control over the element. It can be done by replacing control with a custom widget, that looks like we want and behaves as select should.
It can be a dropdown, a simple list, a list of inputs etc. All methods allowed.
The important thing is to clearly define what it should do and how it should do it. That means states (initial, active, open), behaviours (hover, focus), interactions with mouse and keyboard, value changes and many more. It all depends on design and functionality.
When we have everything figured out, it’s time to define HTML structure to mimic select element. It’s highly possible that we will need to make some changes to the code in the future, so it is important to have it in mind and use class names carefully.
Now, there’s time for some styling ;)
- full control of the element
- hight extensibility (if well prepared)
- it’s time-consuming
- require advanced knowledge
- making reusable widgets can be tricky
- js can be disabled in the browser
Another way to have full control of select behaviour and appearance is to use one of many jquery libraries. An easy and time-saving solution. All you have to do is to choose the library and implement it. They do everything I wrote before and more.
Full control is a little bit too much because it has limits, the same the chosen library has. And sometimes implementing changes can be really challenging, especially when the project has a few years and there is no way to change libraries.
Choose your libraries wisely and test them before use.
- ready to use
- easy implementation
- problematic extensibility
Using selects can be challenging on any level. Each project requires a different approach. There is no universal answer, how to do it. Choose your tools wisely and test them well. And always be prepared for surprises.
Resources and useful links: