Most browser-generated UI can be customized to some extent using CSS. Even if it requires modern features, it degrades gracefully in older browsers, and thus often does not require a polyfill or fallback.
Before re-creating browser UI (form controls, scrollbars, selections, error messages, etc), first verify that:
- the browser UI cannot be customized enough for your needs, even with modern CSS,
- the desired customization is sufficiently critical to justify the tradeoffs of re-creating built-in UI — most notably losing accessible semantics, keyboard handling, IME, and AT integration that the native UI provides for free.
Example customizations that are possible:
- Use
::selectionto customize highlighted text colors. - DON'T apply
user-select: noneto content text — breaks copy-paste, translation tools, and AT "read from here" gestures. Limit it to chrome (drag handles, toolbars, redundant button labels). - Use
accent-colorto apply the page's accent color to any browser-generated UI. - Use
color-schemeto have browser UI adapt to light/dark mode. - Use
scrollbar-colorto customize scrollbar colors andscrollbar-widthto control scrollbar thickness — keep the thumb visibly distinct from the track (≥3:1), and don't setscrollbar-width: noneon scrollable regions (use it only when scrolling is fully replaced by another affordance). - Use
:user-invalid/:user-validfor validity styling, not:invalid/:valid— they only match after the user has interacted with the field, avoiding the hostile default of flagging required-empty fields as errors on page load. Exclude range sliders when targetinginputbroadly (e.g.,input:not(input[type="range"]):user-valid) so adjusting a slider does not apply field validity borders or backgrounds to it. - Buttons and text fields (including
<textarea>) can generally be styled as normal elements. - Use
font-sizeto scale and other textual properties to control typography
Styling textual fields (<input> & <textarea>)
For most styling purposes (e.g. colors, borders, backgrounds, typography, etc) treat these elements as normal text containers.
- Use
:placeholder-shownand::placeholderto style input placeholders. - Use
field-sizing: contentto make text fields size to content. - For
<textarea>elements, useresize: verticalto disable horizontal resizing orresize: noneto disable all resizing.
Multiple choice controls (select, radios, checkboxes)
- To select one among many options presented in a dropdown: Use a
<select>+appearance: base-select+::picker(select). For more info see Branded Select Styling - Selecting one or more among multiple options laid out inline in the page: Use a
<input type=checkbox>or<input type=radio>inside a<label>for each option. Style vialabel:has(:checked). - Style checkboxes, radios and switches via
appearance: none+ generated content (::before/::after) or background images to draw the checked state.
Non-textual <input>s (buttons, sliders, file inputs etc.)
- File inputs: Use
::file-selector-buttonto style the button. - Do not use
<input>with atypeofbutton,submitorreset. Use<button>instead and style it as a regular element. - Sliders: Use
appearance: none+ thumb pseudo-elements (::-webkit-slider-thumb,::-moz-range-thumb, etc) and track pseudo-elements (::-webkit-slider-runnable-track,::-moz-range-track, etc) for more granular control.