By · Updated

Custom Select CSS

Custom Arrow, Border and Colours for a Native Select, No JavaScript

No ratings yet

Content

Layout

Colours

OneTask is free, with no sign-up, and built by one person.
If this tool saved you time, a coffee helps keep new ones coming.

How the Select Dropdown Builder works

This custom select CSS builder styles the native dropdown. The native select is the most reliable dropdown there is — keyboard, screen reader and mobile support all built in — but its default arrow and chrome rarely match a design. This builder restyles the closed control and swaps the arrow while leaving the open list to the browser. Pick your options and copy the HTML and CSS.

Custom select CSS: styling without replacing

A <select> has two parts: the closed box you see on the page, and the popup list of options. CSS can fully style the first and barely touch the second. This generator embraces that split: you get a box that matches your form fields and a list that behaves exactly as users expect on their platform, including the wheel picker on iOS and the native dropdown on Android.

Removing the platform look. appearance: none strips the operating system styling and, with it, the default arrow. From there the select accepts padding, border, radius, height and background like any other box. The ::-ms-expand rule hides the arrow in old Edge, which ignores appearance.

The custom arrow. The arrow is an inline SVG data URI set as background-image, positioned at the right and sized relative to the control height. Encoding it in CSS means no extra element, no icon font and no wrapper div, and the arrow colour is baked into the URL. The right padding is increased so the selected text never overlaps it. Choose Chevron for a thin stroked arrow or Caret for a solid triangle.

Placeholder styling. A select has no placeholder attribute. The generated markup uses a first option with an empty value that is disabled and selected, combined with required on the select. While the placeholder is chosen the select is invalid, so select:invalid can colour the text grey. As soon as a real option is picked the colour returns to normal. The option rule resets the colour so the list itself is not grey in browsers that let you style options.

Focus and hover. Hover changes the border colour; :focus-visible adds a soft ring using the accent colour with 20 percent alpha. The default outline is removed only because the ring replaces it.

Line height and height. Selects ignore line-height for vertical centring in some browsers, so the generated CSS sets an explicit height and lets the browser centre the text. If you need the control to grow with long labels, swap height for min-height.

What you cannot style. Option padding, hover colour and the list's border radius are set by the browser and mostly ignore CSS. Chrome is rolling out appearance: base-select which opens the list to full styling, but until it is widely supported, a custom-styled list means a custom component such as the Autocomplete UI.

FAQ

Why keep the native select instead of building a custom dropdown?

Because the native one already handles typing to jump to an option, arrow keys, Escape, screen reader announcements, form submission, autofill and the mobile picker. A custom dropdown has to reimplement every one of those and usually gets some wrong. Restyle the box, keep the list.

Can I style the options in the dropdown list?

Barely. Font size, colour and background on option work in Firefox and partly in Chrome, and not at all on iOS. Padding and hover states are ignored almost everywhere. Treat the list as the browser's and design the closed control only.

How do I make the arrow rotate when the list is open?

There is no reliable open state for a native select in CSS. :focus fires on open but stays after closing, so a rotating arrow ends up stuck. If a rotating arrow matters, that is a sign you want a custom component rather than a select.

Does the placeholder option get submitted if nothing is chosen?

With required on the select, the form will not submit while the placeholder is selected and the browser shows its validation message. Without required, an empty string is submitted, which is also fine if your backend treats it as "not chosen".

Why is the text not vertically centred in Safari?

Safari centres select text itself once appearance: none is set, but a line-height that is larger than the control height can push it down. The generated CSS uses a small line-height and an explicit height, which centres cleanly across browsers.

See also: all Forms & Inputs tools, Layout & Spacing, Shadows & Motion, Shapes & SVG, UI Components, Colour.

Related tools