Skip to content

Update advanced form styling for accent-color, file pickers and number inputs - #45453

Merged
chrisdavidmills merged 5 commits into
mdn:mainfrom
natiD1:advanced-form-styling-updates
Sep 3, 2026
Merged

Update advanced form styling for accent-color, file pickers and number inputs#45453
chrisdavidmills merged 5 commits into
mdn:mainfrom
natiD1:advanced-form-styling-updates

Conversation

@natiD1

@natiD1 natiD1 commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Description

Three fixes to the Advanced form styling page, which @Josh-Cena asked to be handled together in #36090, #24304 and #42946, plus one related note on Styling web forms.

Motivation

All three are cases where the page tells a learner something that is no longer true, or steers them toward a workaround with a cost the page doesn't mention.

The tel suggestion is the one I would single out. Swapping the input type to get rid of a spinner changes what the field means and what the browser validates, which is a lot to trade for an appearance problem. The replacement recommends inputmode="numeric" with a pattern attribute, which is what the Accessibility section of <input type="number"> already recommends, so this brings the Learn page in line with the reference page rather than introducing new advice.

Additional details

  • The approach for Advanced form styling: Don't suggest replacing numeric input with telephone input #42946 follows @AhamadAlii's suggestion in that thread. @bhargavikondaka also offered to take it in March. I hope picking it up now is welcome rather than stepping on toes, and I can step back if either would rather carry it.
  • On placement of the accent-color section: I put it immediately before the appearance one, so a reader meets the cheaper option first. That does mean the heading sits under the ## appearance: controlling OS-level styling parent, which is a slightly awkward fit. I can move it out to its own ## section, or after the appearance one, if you prefer.
  • The Styling web forms change is easy to drop. File selector can be styled #36090 notes that page carries the same wrong impression, since it lists <input type="file"> under "having internals that can't be styled in CSS alone". Rather than recategorizing it, given the button is stylable but the file name text still isn't, I added a note in the style of the existing <select> one. Let me know if you would rather handle that page separately.
  • The new live sample tints more than one control type, so the shared effect is visible in a single example.

Related issues and pull requests

Fixes #24304
Fixes #36090
Fixes #42946

…r inputs

Addresses three issues on the Advanced form styling page, which a maintainer
asked to be fixed together.

Adds an accent-color section for checkboxes and radio buttons. The page went
straight to `appearance: none` and rebuilding the control by hand, with no
mention of the one-property option that covers the common case of only wanting
a different color.

Corrects the claim that the file picker button is "completely unstylable". It
has been stylable with ::file-selector-button for some years. The label
technique the page already described is kept, since it is still the way to
control the text beside the button, which CSS cannot reach.

Replaces the note suggesting `<input type="tel">` as a way to avoid the number
spinner. Switching type to lose a spinner changes the meaning of the field and
what the browser validates. Recommends `inputmode="numeric"` with a pattern
attribute instead, matching the guidance already on the `<input type="number">`
page.

Also notes on Styling web forms that the file picker button is stylable, since
that page lists `<input type="file">` among the controls whose internals CSS
cannot reach.
@natiD1
natiD1 requested a review from a team as a code owner September 2, 2026 07:14
@natiD1
natiD1 requested review from chrisdavidmills and removed request for a team September 2, 2026 07:14
@github-actions github-actions Bot added Content:Learn Learning area docs (outside of one of the Learn:* subtags) size/m [PR only] 51-500 LoC changed labels Sep 2, 2026
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Preview URLs (2 pages)

External URLs (1)

URL: /en-US/docs/Learn_web_development/Extensions/Forms/Advanced_form_styling
Title: Advanced form styling

(comment last updated: 2026-09-03 12:11:15)

@chrisdavidmills chrisdavidmills left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @natiD1; this seems like a reasonable effort. I've made several suggestions for improving the text and improving the continuity with what's already there.

}
```

### Styling checkboxes and radio buttons using `accent-color`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### Styling checkboxes and radio buttons using `accent-color`
### Setting form control color tints using `accent-color`

Because it doesn't only affect checkboxes and radios. It affects others too.


### Styling checkboxes and radio buttons using `accent-color`

If the only thing you want to change is the color, {{cssxref("accent-color")}} will do it without taking the control apart. The browser carries on drawing the checkbox or radio button itself, and tints it:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If the only thing you want to change is the color, {{cssxref("accent-color")}} will do it without taking the control apart. The browser carries on drawing the checkbox or radio button itself, and tints it:
If you only want to style the primary tint color of checkboxes, radio buttons, or range sliders, the {{cssxref("accent-color")}} will do it without requiring `appearance: none`. This is useful for basic styling cases, as the controls maintain their OS-level styling, but with an altered main color.


If the only thing you want to change is the color, {{cssxref("accent-color")}} will do it without taking the control apart. The browser carries on drawing the checkbox or radio button itself, and tints it:

```html live-sample___checkboxes-accent-color

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: change the identifier to accent-color, since the example includes a radio button and a checkbox.

</form>
```

```css live-sample___checkboxes-accent-color

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, "accent-color"?


{{EmbedLiveSample("checkboxes-accent-color", '100%', 160)}}

Because the control keeps its native appearance, it goes on following platform conventions — including forced-colors modes — with no further work on your part. Reach for the `appearance: none` approach below when you need to change more than the color.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Because the control keeps its native appearance, it goes on following platform conventions — including forced-colors modes — with no further work on your part. Reach for the `appearance: none` approach below when you need to change more than the color.
Because the control keeps its native appearance, it follows platform conventions — including forced-colors modes — with no further work on your part. In addition, the browser automatically chooses a complementary secondary color with enough contrast to the `accent-color` to keep the control accessible. Play with the above live example and set some light and dark `accent-color` values to see the effects.


> [!NOTE]
> It is worth mentioning [`<input type="number">`](/en-US/docs/Web/HTML/Reference/Elements/input/number) here too — this also has a spinner that you can use to increment/decrement values, so potentially suffers from the same problem. However, in the case of the `number` type the data being collected is simpler, and it is easy to just use a `tel` input type instead, which has the appearance of `text`, but displays the numeric keypad in devices with touch keyboards.
> [`<input type="number">`](/en-US/docs/Web/HTML/Reference/Elements/input/number) has a spinner too, and its internal parts are no easier to style. If the spinner is the part you want to be rid of, don't reach for `tel`: that changes what the field means, and the browser will validate it as a telephone number rather than as a number. Use [`<input type="text">`](/en-US/docs/Web/HTML/Reference/Elements/input/text) with [`inputmode="numeric"`](/en-US/docs/Web/HTML/Reference/Global_attributes/inputmode) and a [`pattern`](/en-US/docs/Web/HTML/Reference/Attributes/pattern) attribute instead. You still get the numeric keypad on devices with touch keyboards, without the spinner and without claiming the value is a phone number. See [Accessibility](/en-US/docs/Web/HTML/Reference/Elements/input/number#accessibility) on the `<input type="number">` page.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> [`<input type="number">`](/en-US/docs/Web/HTML/Reference/Elements/input/number) has a spinner too, and its internal parts are no easier to style. If the spinner is the part you want to be rid of, don't reach for `tel`: that changes what the field means, and the browser will validate it as a telephone number rather than as a number. Use [`<input type="text">`](/en-US/docs/Web/HTML/Reference/Elements/input/text) with [`inputmode="numeric"`](/en-US/docs/Web/HTML/Reference/Global_attributes/inputmode) and a [`pattern`](/en-US/docs/Web/HTML/Reference/Attributes/pattern) attribute instead. You still get the numeric keypad on devices with touch keyboards, without the spinner and without claiming the value is a phone number. See [Accessibility](/en-US/docs/Web/HTML/Reference/Elements/input/number#accessibility) on the `<input type="number">` page.
> [`<input type="number">`](/en-US/docs/Web/HTML/Reference/Elements/input/number) has a spinner too, and its internal parts are no easier to style. If you want to remove the spinner, use [`<input type="text">`](/en-US/docs/Web/HTML/Reference/Elements/input/text) with [`inputmode="numeric"`](/en-US/docs/Web/HTML/Reference/Global_attributes/inputmode) set to display a numeric keypad on devices with touch keyboards and a [`pattern`](/en-US/docs/Web/HTML/Reference/Attributes/pattern) attribute that limits input values to a number. See also [`<input type="number">` > Accessibility](/en-US/docs/Web/HTML/Reference/Elements/input/number#accessibility).

@@ -595,9 +630,21 @@ However, a custom solution is the only way to get anything significantly differe

Inputs of type file are generally OK — as you saw in our example, it is fairly easy to create something that fits in OK with the rest of the page — the output line that is part of the control will inherit the parent font if you tell the input to do so, and you can style the custom list of file names and sizes in any way you want; we created it after all.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Inputs of type file are generally OK — as you saw in our example, it is fairly easy to create something that fits in OK with the rest of the page — the output line that is part of the control will inherit the parent font if you tell the input to do so, and you can style the custom list of file names and sizes in any way you want; we created it after all.
Inputs of type file are generally OK — it is fairly easy to create something that fits in OK with the rest of the page. The output line that is part of the control will inherit the parent font if you tell the input to do so, and you can style the custom list of file names and sizes in any way you want.

The button you press to open the file picker can be styled with the {{cssxref("::file-selector-button")}} pseudo-element, which accepts the same properties as any other button:

```css
input[type="file"]::file-selector-button {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good for you to show this as a live example, so people can see the effect of the declaration you've shown. Also, the way it is written, people might think this is part of the live example further down, which is not the case.

}
```

What you can't reach this way is the text beside the button — the "no file chosen" message, and the name of the file once one has been picked. The browser generates that text and doesn't expose it to CSS.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
What you can't reach this way is the text beside the button — the "no file chosen" message, and the name of the file once one has been picked. The browser generates that text and doesn't expose it to CSS.
You can't style the text beside the button — the "no file chosen" message — or the displayed filename once chosen. The browser generates that text and doesn't expose it to CSS. To work around this problem, you can use the control's label and the fact that clicking the label activates the control.
You could hide the actual form input using something like this:

What you can't reach this way is the text beside the button — the "no file chosen" message, and the name of the file once one has been picked. The browser generates that text and doesn't expose it to CSS.

One way around this is to take advantage of the fact that if you have a label associated with a form control, clicking the label will activate the control. So you could hide the actual form input using something like this:
If you need control over that part as well, you can take advantage of the fact that if you have a label associated with a form control, clicking the label will activate the control. So you could hide the actual form input using something like this:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete this line, as I merged it with the paragraph above.

Suggested change
If you need control over that part as well, you can take advantage of the fact that if you have a label associated with a form control, clicking the label will activate the control. So you could hide the actual form input using something like this:

natiD1 and others added 4 commits September 2, 2026 14:17
Renames the accent-color heading to cover form controls generally rather than
just checkboxes and radio buttons, since the property also tints range sliders,
and renames the live sample to match. Adds a range slider to that sample so it
demonstrates the three controls the text now names.

Rewrites the accent-color intro and closing paragraphs, the opening of the
appearance section, the number input note and the file input opening, following
the suggestions on the pull request.

Turns the ::file-selector-button snippet into a live example of its own, so the
declaration can be seen taking effect and is no longer mistakable for part of
the styled file picker example further down.
Reworded the explanation regarding styling checkboxes and radio buttons for clarity.

@chrisdavidmills chrisdavidmills left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This all looks good; thanks, @natiD1!

@chrisdavidmills
chrisdavidmills merged commit 0daae80 into mdn:main Sep 3, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Content:Learn Learning area docs (outside of one of the Learn:* subtags) size/m [PR only] 51-500 LoC changed

Projects

None yet

3 participants