Skip to content

[css-pseudo] [css-selectors] Clarification: do ::placeholder/:placeholder-shown apply to <select>s’ “placeholder label option”? #2517

Closed
@tigt

Description

@tigt

The ::placeholder and :placeholder-shown selectors apply to elements with explicit placeholder attributes, like <input> and <textarea>. Should they also match <select> elements with a “placeholder label option”?

HTML Standard / Form Elements / §4.10.7 The select element / #placeholder-label-option:

If a select element has a required attribute specified, does not have a multiple attribute specified, and has a display size of 1; and if the value of the first option element in the select element's list of options (if any) is the empty string, and that option element's parent node is the select element (and not an optgroup element), then that option is the select element's placeholder label option.

My intuition suggests that the following would be true:

  • :placeholder-shown matches a <select> where its currently selected <option> is a placeholder label option
  • ::placeholder matches said <option> (or a pseudo-element inside it)

It’s sort of possible to emulate this today:

/* Rough, not-100% alternative to select:placeholder-shown */
select:required:invalid {
  /* … */
}

/* Fairly close but v. ugly equivalent to select::placeholder */
select:required:not([multiple]):matches(:not([size]), [size="1"]) > 
  option:first-child:matches([value=""], :empty:not([value]) {
    /* … */
}

But the constraints outlined in the HTML spec aren’t perfectly expressible with other selectors*, so having the placeholder-related selectors apply to this case would be useful.

* In no particular order, and I’m sure not a complete list:

  • Weird values in the size attribute (zero, negative numbers, floats, non-numeric characters) can still cause the display size to become 1

  • A :required <select> can be :invalid for other reasons, such as setCustomValidity()

  • There may be other elements in front of the first direct-child <option>, like <script> and <template>

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions