The open list on a select element stayed out of CSS reach for a long time. Chrome 135 changed that when it went stable on 1 April 2025 (Chrome for Developers announced it on 24 March 2025), and Safari 27 followed on 14 September 2026.
appearance: none still restyles the closed field in every browser. appearance: base-select is the newer property, and it opens the picker, options and arrow to normal CSS. Firefox doesn’t have it, so those visitors get a classic select that works fine.
Older guides haven’t caught up. Sentry’s 2023 answer, for one, still says option elements cannot be styled in any way.
What can CSS style on a select element?
Less than you’d want, and more than it used to be. A select is really two controls glued together. The closed field styles like any other form control, while the list that opens below it is drawn by the browser or the operating system.
MDN’s form styling guide files select, option and optgroup under the controls that cannot be styled thoroughly, then makes one exception: customizable select.
The classic route means setting appearance: none and styling whatever the browser leaves behind. It works everywhere, but the open list stays mostly out of reach. The opt-in route is appearance: base-select on the select and its picker, which turns the button, list, options and checkmark into normal stylable parts. Supporting browsers only.
Here is where each part stands.
- Select box (border, padding, font, background): both routes
- Arrow: removable in the classic route, restyled with ::picker-icon in the opt-in route
- Option text: font inheritance only in the classic route, full styling in the opt-in route
- Checkmark, optgroup layout and picker position: opt-in route only
Styling a native dropdown without JavaScript was a closed-box job for two decades.
How to style the closed select box
The usual box and text properties all work on the closed field: border, border-radius, padding, background-color, font, width and height.
Box and typography properties
- font: inherit, so the field matches the surrounding text
- box-sizing: border-box, so width: 100% fits its container
- padding and height set together, since browsers size the field differently by default
- border-radius plus a soft inset box-shadow for the usual rounded-field look
MDN’s form styling guide applies one normalizing block to every control, selects included, so the fields end up the same size across browsers.
A shared block is easier to maintain when form styles live in one place, and the walkthrough on styling forms with CSS shows that pattern.
border-radius reshapes the closed box only. In classic mode the open list stays with the browser.
Hover, focus and disabled states
Keep a visible outline on focus. A select with appearance: none and no replacement focus style is invisible to keyboard users.
Hover needs very little. A background shift is enough, with a short transition so it doesn’t flicker. Disabled selects get dimmed text and background through the :disabled pseudo-class, plus cursor: not-allowed.
How to remove and replace the dropdown arrow
See the Pen
SELECT right-arrow with CSS by Veiko (@vkjgr)
on CodePen.
Set appearance: none on the select to remove the native arrow, then draw a new one with a wrapper pseudo-element or a background image.
The property has been available across browsers since March 2022 (MDN), so removing the arrow carries no support risk.
Old tutorials still add -webkit-appearance, -moz-appearance and a select::-ms-expand rule for Internet Explorer. Current browsers need only the unprefixed property.
Wrapper with a pseudo-element
A wrapper is needed because ::before and ::after do not work on select elements, since the browser controls their content (MDN).
- Wrap the select in a div with position: relative
- Place the arrow on the wrapper’s ::after, absolutely positioned at the right edge
- Set pointer-events: none on the arrow so clicks reach the select
- Add padding-right to the select so long labels never run under the arrow
This is the pattern MDN uses. The native icon also differs between browsers and shifts when the box is resized, which is the problem the wrapper avoids.
OpenReplay draws the arrow as a triangle with clip-path, which keeps image files out of the stylesheet. A clip-path generator saves the coordinate math.
Define the border color once as a custom property and reuse it for the arrow. When the focus state changes the border, the arrow follows.
Background image on the select
The markup is simpler this way, but you get less control.
Set background-image to an inline SVG data URI, background-repeat to no-repeat, and background-position to the right edge, with padding-right on the select.
Codemia lists drawing the arrow on the select itself among the common mistakes. It holds up when the field has a fixed size and the markup cannot change.
Recoloring means editing the SVG string, since custom properties do not reach inside a data URI. That is the main reason to prefer the wrapper.
Selects in base-select mode skip all of this, because the arrow is a real pseudo-element, ::picker-icon.
Can you style option elements in a classic select?
Only partly. In classic mode the open list inherits the parent font, but colors, spacing and the list box itself stay with the browser (MDN, Advanced form styling).
Published guides disagree on the details. MDN says font inheritance works while spacing and colors do not. Sentry (2023) goes further and says option elements cannot be styled in any way. LogRocket reports that font-style set on the select reaches list items in Chrome but not in Firefox, and GeeksforGeeks shows background and text color rules written directly on option elements.
The positions differ because engines draw the open list differently. A rule that works in one browser on one platform can do nothing in another, and that is a cross-browser compatibility problem, not a bug in your stylesheet.
Treat option color and background rules as cosmetic extras, never as the design.
Ways around the limit
Adding the multiple attribute gets you out of the problem, since every option renders on the page and there is no closed list to fight with (MDN). Opting in with appearance: base-select is the other clean way, because option, optgroup and the picker then take normal CSS.
Replacing the control with a JavaScript library works too. It costs accessibility work and bundle weight, though.
What does appearance: base-select change?
A lot, mostly on the picker side. It opts a select and its picker out of OS-drawn rendering, so the button, option list, checkmark and arrow become ordinary stylable parts.
Chrome shipped it first and Safari 27 followed. Firefox has not shipped it, so MDN and the web-features data still list it as limited availability.
What the opt-in switches on
- A changed HTML parser, so option elements accept rich content such as images and SVG
- New internal parts and states: a button as first child, selectedcontent, ::picker-icon, ::checkmark and :open
- A picker rendered in the top layer like a popover, through an implicit invoker and popover link between select and picker (Popover API), so transitions can animate it
- Implicit CSS anchor positioning, which places the picker below the button by default
- Browser-defined position-try fallbacks for pickers that would overflow
- A minimal base look built for customization
Those fallbacks reposition the picker when it would overflow the viewport, so a select near the bottom of the screen opens upward instead of clipping.
Both the select and the picker need the value. Opting in only the select leaves the picker with OS styling, and the picker cannot be opted in alone (MDN).
::picker(select) targets everything inside the select except the first button child, so one rule styles the whole list.
What the opt-in switches off
Chrome for Developers documented what you give up in its 24 March 2025 announcement. The select no longer renders outside the browser pane, and the built-in mobile operating system components stop appearing.
It also stops taking the width of the longest option, which catches layouts by surprise. Set the width explicitly.
Where the feature stands
Chrome 135 was the first stable version (stable on 1 April 2025, announced by Chrome for Developers on 24 March 2025), and Safari 27 was released on 14 September 2026. Firefox does not support it in stable releases as of October 2026.
MDN’s feature list names 9 building blocks, from the plain select, option and optgroup elements to ::checkmark. Its availability status is limited, not Baseline (page last modified 13 August 2026), and the web-features data lists Firefox as the browser blocking Baseline.
How to build a customizable select step by step
Every selector below comes from MDN’s customizable select walkthrough.
- Write the markup: a label tied to the select by for and id, then the select with a button as its first child holding selectedcontent, then option elements with value attributes
- Opt in with appearance: base-select on both the select and ::picker(select)
- Style the select box like any block: border, background, padding, and a short transition on hover and focus
- Style ::picker-icon: set its color, then rotate it 180deg on select:open
- Strip the default picker border with ::picker(select), then pad and round the options
- Mark the chosen option with :checked (a heavier font-weight works), and move or hide ::checkmark
- Hide decorative icons inside selectedcontent so the closed button keeps a stable height
The label and select pair in step 1 is the same pattern covered in guides to accessible forms. Skip it and the control loses its name.
The arrow rotation in step 4 is a small micro-interaction. MDN’s example transitions the rotate property over 0.4s, which is slow enough to read and fast enough to feel instant.
Selected content inside the button
selectedcontent holds a clone of the chosen option’s content, made with cloneNode under the hood (MDN).
Leave it out and the browser prints the chosen option’s text in the default button, which is harder to style. Extra content inside the button can change the accessible value the select exposes, and the button is inert by default, so links or buttons placed inside it are neither focusable nor clickable.
Put display: none on the icon span inside selectedcontent. The option keeps its icon in the picker, and the closed field stays one line high.
Optgroups and legends
In base-select mode an optgroup acts like any block container, so border, radius, background and margin all apply.
A legend child replaces the label attribute text and gives you an element to target. Center it and add a bottom margin. Give the last option in each group the same bottom radius as the group, or square corners poke through.
Mark decorative icon spans aria-hidden=”true”. Without it, screen readers announce each option twice, as in “cat cat” (MDN).
Which browsers support customizable select, and how should the fallback work?
Chromium browsers and Safari 27 or later support base-select. Firefox has not shipped it in a stable release, so Firefox and older versions of Safari and Chromium need a fallback to a classic select that still works.
Support by engine
Chrome and Edge 135 and later render the opt-in route. So does Safari 27, released 14 September 2026, though its default base styles differ from Chrome’s, so test the unstyled defaults in both. Earlier Safari versions get classic styling.
Firefox gets classic styling as well. Mozilla’s standards-position issue for the feature is positive, but the feature is not available in stable releases as of October 2026.
Engine status moves faster than articles do. Check Can I use before launch.
Third-party posts also disagree on the first stable Chrome version. SitePoint says 133, Modern CSS says 134 and later, and OpenReplay says 135 and later.
The Chrome for Developers announcement is the primary source, and it sides with the 135 group.
How the fallback renders
The select element has been available across browsers since July 2015 (MDN), so a working control always sits underneath the new styles.
The button child and selectedcontent are ignored or removed, and rich option content gets stripped down to its text. Selection, keyboard use and form submission stay intact.
SitePoint adds a warning: parsers without the new behavior can eject the button child from the select. MDN’s select reference confirms the mechanism, since older parsers keep only option, optgroup and hr.
Layering with @supports
Write the classic route first: appearance: none, the wrapper arrow, the closed-box styles. Then wrap only the base-select rules in @supports (appearance: base-select).
Rules that touch ::picker(select), ::picker-icon or ::checkmark belong inside that block.
The feature query tests the property, not the parser. Older browsers still receive the new markup, so keep the classic select styled defensively.
Where the specs stand
Customizable select sat at stage 2 in WHATWG when Chrome filed its intent to ship, and Open UI hosts the component design for the select.
::picker is specified in CSS Form Control Styling Level 1, and appearance in CSS Basic User Interface Module Level 4 (MDN specification tables).
How to keep a styled select accessible
Keep the native element, a visible focus indicator, a label, and contrast of at least 3:1 on every part a user needs to see.
That 3:1 figure comes from WCAG 2.2 SC 1.4.11 for user interface components and their states (W3C Understanding docs, updated September 2026). The dropdown arrow counts, because W3C’s own examples treat it as required to show that a menu exists.
Run the box border, the arrow and the focus indicator through a color contrast check before shipping.
Disabled controls are exempt from the 3:1 rule, so dimming them is allowed. W3C names selects among the controls where pointer position is the hover indicator, which means extra hover styling doesn’t need 3:1 either. An untouched browser focus ring is exempt too, but restyle it and the exemption ends.
Focus
SC 2.4.7 Focus Visible (Level AA) requires a visible keyboard focus indicator. W3C lists removing it through outline or border styling as failure F78.
A focus style that only recolors the border fails when the new color does not contrast with the component’s own background. A two-color indicator (W3C technique C40) passes on any background.
Labels, roles and keyboard
- Tie the label to the select with for and id
- Single selects expose the combobox role, while selects with multiple or a size above 1 expose listbox (MDN)
- appearance changes the look and not the functionality, so native keyboard behavior survives appearance: none
- Chrome’s announcement calls the opt-in route accessible, because the browser’s own select keeps the interaction
- ::checkmark and ::picker-icon sit outside the accessibility tree, so generated content on them is never announced
A hand-built replacement carries the whole burden. MDN says it needs JavaScript and ARIA roles and states to supply the semantics a native select gives for free.
When does CSS select styling stop working?
Forgetting the opt-in is the easiest way to break it. A ::picker(select) rule only styles the picker when both the select and the picker have appearance: base-select. Without that, the rule has no effect (MDN).
Frameworks can get in the way too. MDN warns that some JavaScript frameworks block these features, and that others cause hydration failures when server-side rendering is on. MDN names no frameworks, so test your own server render.
Older parsers strip everything but option, optgroup and hr. Script that looks for the button or selectedcontent then finds nothing, so guard those queries (MDN).
A select with the multiple attribute renders a scrolling list box with no open state, so :open never matches (MDN). Listboxes get their own customizable select guide there.
If options carry images or SVG, test the selected value in JavaScript. Chrome changed how the selected content string is determined, and options with a value attribute are safe (Chrome for Developers).
Cases where restyling is the wrong call
Touch-first forms often do better with the native picker. Scope the opt-in with @media (pointer: fine) to leave touch devices on it.
Long lists that need search are another case, and so are forms where the design gains nothing from a custom picker, since leaving appearance: auto costs nothing.
No CSS adds search or filtering. That is a library job.
Should you use a native select or a JavaScript replacement?
Use the native select unless the control needs search, tagging or remote data. A closed-box restyle needs no library, and the opt-in route covers a styled picker.
| Option | What you can style | JavaScript | Support and accessibility |
|---|---|---|---|
| Classic select, appearance: none | Closed box and arrow | None | Every browser, native keyboard and roles |
| Customizable select, appearance: base-select | Box, picker, options, checkmark, arrow | None | Limited availability, falls back to classic select |
| Library (Tom Select, Choices.js, Select2) | Whatever the library exposes | Required | Same look everywhere, accessibility depends on the library |
What the libraries cost
Tom Select weighs about 16kb gzipped (project site) and is framework agnostic. It was forked from selectize.js to drop jQuery, and it adds autocomplete and native-feeling keyboard navigation.
Choices.js comes in at about 20kb gzipped (project README) with no jQuery dependency. Setting labelId adds aria-labelledby to the generated element.
Select2 is built on jQuery, with search, tagging, remote data and over 40 built-in languages. Its documentation also lists Internet Explorer 11 support.
How to pick
If only the closed field needs branding, stay with a classic select and skip the library. If the picker has to match the design and a fallback is acceptable, use base-select behind @supports. Searching long lists, creating tags or loading options from a server is where a library earns its place.
MDN’s legacy advice for full control points to a library or a hand-built dropdown. The opt-in route now adds a third path, and for plain styling it is the cheaper one.
Libraries shift accessibility from the browser to a package, so budget screen reader and keyboard testing as part of your wider web accessibility work.
CSS Select Examples To Check Out
Pure CSS, No JS? Check This Out!

Branding with CSS3 Card Deck Drop

Purely CSS. Utterly Stunning.

Vivid Dreams of a Full Height Select Box

Dropdowns that Don’t Suck. Period.

Behold the Selectionator

When Regular Just Doesn’t Cut It

Add Some Color with a CSS Select Twist

Boost Your Display Game

Select. Share. Shine.

Fully Stylized. Fully CSS.

Feedback Ready with the CSS Review Select

Maps + Select Box = Pure Gold

The All-in-One CSS Select Box

A Dash of CSS Select Style

Select? Make it Horizontal!

Visual Treat with Image Selection

Smooth Scroll with a Responsive Touch

Keep it Flat and Fab

PTransformative Select Box with a Placeholder

Select in Material Design Vibes

Select-Boxes that Turn Heads

Keeping it Straightforward with HTML & CSS

Turn Heads with this Pretty Select Dropdown

Filterable and Stylish CSS Select Dropdown

Box of Wonders with Only CSS

Tailored to Perfection: CSS Only Dropdown

CSS Select FAQ
How do you style a select with the multiple attribute?
Treat it as a scrolling list box, not a dropdown. Style the select itself with border, padding, font and height, and set size to control how many rows show (the default is 4). MDN covers the base-select version in its customizable select listboxes guide.
Can you style the placeholder option in a select?
Only indirectly. The placeholder is the first option with an empty value, and with the required attribute the select matches :invalid while it is selected. Use select:required:invalid to gray out the closed box, since rules on the option itself are unreliable in a classic select.
How do you make a select as wide as its longest option?
Leave the width unset. A classic select sizes itself to its widest option by default, and a fixed width overrides that. Add max-width: 100% to stop overflow in narrow containers, and check MDN’s field-sizing property if you need more control.
Does a styled select follow dark mode?
Not automatically once appearance: none is set. You own the colors then, so define them as custom properties and swap the values inside a prefers-color-scheme: dark query. For an unstyled select, color-scheme: dark switches the native control and its open list to dark system colors.
Can you animate the select dropdown opening and closing?
Yes, but only the base-select picker. Add a transition on opacity and transform to ::picker(select), define the entry state with @starting-style, and set transition-behavior: allow-discrete so the exit animates too. The open list of a classic select cannot be animated.
Testing a CSS Select Before Release
Test the classic route first, since that styling reaches every visitor. The base-select route comes second, because only Chromium and Safari 27 or later render it.
The order that works best goes from the failures that hide best to the ones that show on screen:
- Keyboard pass: Tab, arrow keys, visible focus
- Fallback pass in Firefox and an older Safari
- Touch pass on a real phone
Keyboard comes first because a missing focus indicator gives no visible sign to mouse users, so nobody on the team notices it by accident. The fallback pass comes second because it covers every browser without base-select.
Firefox visitors, and anyone on an older Safari or Chromium, see the classic select, so build that fallback as the finished product.
This position was verified on 14 October 2026. A stable base-select release in Firefox would shrink the fallback pass to a spot check.
- What is Backend in Web Development? - September 13, 2026
- What is Frontend Development? - September 11, 2026
- How to Make a Button in Figma: Design Best Practices - September 10, 2026









