Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define :blank pseudo-class behavior #8451

Open
annevk opened this issue Oct 28, 2022 · 22 comments
Open

Define :blank pseudo-class behavior #8451

annevk opened this issue Oct 28, 2022 · 22 comments

Comments

@annevk
Copy link
Member

annevk commented Oct 28, 2022

Through web-platform-tests/interop#179 I learned about the :blank pseudo-class. It would be good if we defined how it works for HTML elements.

cc @whatwg/css

@brandonmcconnell
Copy link

brandonmcconnell commented Oct 28, 2022

@annevk Good thoughts! As far as I can tell from the current spec (MDN | spec), this is intended to only work on form elements. You pose some really important questions re how this works for "non-text-inputable" fields.

I didn't have any role in the spec writing, so I'd like to invite the current editors of selectors-4, @tabatkins and @fantasai, to join this conversation as their opinions hold exceedingly more weight than my own.

I've broken this up into an itemized list below, but the gist imo is that :blank would match any field which meets these criteria:

  • empty input
  • no whitespace
  • value is ""/null (not 0)

Naturally, this will exclude certain field types and other form-related elements. For example, range and color inputs cannot actually have a nullish value, for color input will default to a value of #000000 without a default input, and a range input will default to a value of '50' even if the min and max attributes are omitted and equal ''. There are plenty of others fields or related fields that also would not meet the required criteria, all broken out below.

There are also a few special cases I think it might help to provide custom functionality for, those being form, fieldset, and label.

These would be my expectations/guesses as to the function of :blank, broken out by :blank-matching criteria:

represented as a table
tag attribute :blank-matching criteria
input (w/o type attr) ✅ empty input, no whitespace, value is ""/null (not 0)
input type="text" ✅ 〃
input type="tel" ✅ 〃
input type="email" ✅ 〃
input type="number" ✅ 〃
input type="password" ✅ 〃
input type="search" ✅ 〃
input type="url" ✅ 〃
textarea ✅ 〃
input type="date" ✅ empty/cleared input (no selection, even if initial value)
input type="time" ✅ 〃
input type="datetime-local" ✅ 〃
input type="week" ✅ 〃
input type="file" ✅ 〃
input type="month" ✅ 〃
select multiple ✅ 〃
select size (when size > 1) ✅ 〃
select (w/o multiple attr and when size < 2) ✅ set to submit an empty string
form ✅ any associated field(s) are blank
fieldset ✅ 〃
label ✅ 〃
input type="checkbox" ❌ no function (does not match)
input type="radio" ❌ 〃
input type="color" ❌ 〃
input type="range" ❌ 〃
input type="hidden" ❌ 〃
input type="button" ❌ 〃
input type="submit" ❌ 〃
input type="image" ❌ 〃
input type="reset" ❌ 〃
input type="datetime" (deprecated) ❌ 〃
button ❌ 〃
datalist ❌ 〃
legend ❌ 〃
meter ❌ 〃
optgroup ❌ 〃
option ❌ 〃
output ❌ 〃
progress ❌ 〃
represented as a list
  • WILL MATCH:
    • empty/cleared input, no whitespace, value is ""/null (not 0)
      • input (w/o type attr)
      • input[type="text"]
      • input[type="tel"]
      • input[type="email"]
      • input[type="number"]
      • input[type="password"]
      • input[type="search"]
      • input[type="url"]
      • textarea
    • empty/cleared input (no selection, even if initial value)
      • input[type="date"]
      • input[type="time"]
      • input[type="datetime-local"]
      • input[type="week"]
      • input[type="file"]
      • input[type="month"]
      • select[multiple]
      • select[size] (when size > 1)
    • set to submit an empty string
      • select (w/o multiple attr and when size < 2)
    • any associated field(s) are blank
      • form
      • fieldset
      • label
  • WILL NOT MATCH: (:blank will have no function)
    • input[type="checkbox"]
    • input[type="radio"]
    • input[type="color"]
    • input[type="range"]
    • input[type="hidden"]
    • input[type="button"]
    • input[type="submit"]
    • input[type="image"]
    • input[type="reset"]
    • input[type="datetime"] (deprecated)
    • button
    • datalist
    • legend
    • meter
    • optgroup
    • option
    • output
    • progress

@domenic domenic added the agenda+ To be discussed at a triage meeting label Nov 10, 2022
@past past removed the agenda+ To be discussed at a triage meeting label Nov 11, 2022
@mfreed7
Copy link
Contributor

mfreed7 commented Nov 11, 2022

@brandonmcconnell thanks for the great enumeration of the controls and specific proposal. I agree with most of what you've proposed. My questions would be:

empty/cleared input (no selection, even if initial value)

  • input[type="date"]
  • input[type="time"]
  • input[type="datetime-local"]
  • input[type="week"]
  • input[type="file"]
  • input[type="month"]

Date controls on at least some platforms can be partially filled out. E.g.

Screen Shot 2022-11-11 at 3 47 21 PM

In that case, input.value still returns "", but the control is clearly not "blank". I'm not sure what to do in that case. It makes me think :blank might not apply to date inputs, in the same way that it doesn't apply to color and range?

  • select base (w/o multiple attr)
  • select[multiple]

Select controls don't really have the concept of "empty", do they? I.e. even a select menu without any <option selected> elements is displayed to the user as if the first option is selected. I think it might actively cause confusion if :blank matches initially, and then the user picks the first option and :blank stops matching, even though the starting and final displayed state are the same.

  • form (if all fields under it match :blank)
  • fieldset (if all fields under it match :blank)

This feels problematic. What if the <form> or <fieldset> contains a control that doesn't support :blank? Should these match if any control within the control matches :blank, instead?

  • output

I must admit I've never quite wrapped my head around <output>, but it certainly seems like it can be blank. I'm really ok either way here.

@annevk
Copy link
Member Author

annevk commented Nov 12, 2022

As @smaug---- notes in the originating issue we also need to deal with placeholder somehow. My intuition would be that it doesn't influence :blank, but others might feel differently about that.

@smaug----
Copy link

Select controls don't really have the concept of "empty", do they?

<select> with size greater than 1 can be empty

@annevk
Copy link
Member Author

annevk commented Nov 14, 2022

cc @zcorpan @whatwg/forms

@mfreed7
Copy link
Contributor

mfreed7 commented Nov 16, 2022

As @smaug---- notes in the originating issue we also need to deal with placeholder somehow. My intuition would be that it doesn't influence :blank, but others might feel differently about that.

I think I also agree - a control that is showing a placeholder seems like it should be considered ":blank".

Select controls don't really have the concept of "empty", do they?

<select> with size greater than 1 can be empty

Right, yes. I shouldn't have included this line in my comment:

select[multiple]

I agree that select[multiple] can be :empty.

@brandonmcconnell
Copy link

brandonmcconnell commented Nov 16, 2022

I agree that select[multiple] can be :empty.

Yep! Just to clarify, I think select[multiple] would be considered…

  • :blank if no option is selected
  • :empty if it contains no HTML

I can see how my loose use of the word "empty" could easily cause confusion with :empty vs. :blank. My apologies 😄

@brandonmcconnell
Copy link

brandonmcconnell commented Nov 16, 2022

@mfreed7 I agree. Good thoughts across the board.

Responding to each—

  • select base (w/o multiple attr) would NEVER match :blank
  • select[multiple] COULD match :blank if no options are selected
  • input[type=date] should only match if we can detect when it has no input whatsoever (would not match, partial input as you pointed out). Otherwise, should not support :blank
  • form should not support :blank, any special need for this should already be covered by :has() support
  • fieldset should not support :blank, any special need for this should already be covered by :has() support
  • label should not support :blank, any special need for this should already be covered by :has() support
  • output should not support :blank, probably better suited for :empty, currently being discussed here: (API, interop)


Updated my previous comment to reflect the same

@smaug----
Copy link

  • select base (w/o multiple attr) would NEVER match :blank

I don't know what _base means, but why wouldn't select size > 1 match :blank?

@brandonmcconnell
Copy link

  • select base (w/o multiple attr) would NEVER match :blank

I don't know what _base means, but why wouldn't select size > 1 match :blank?

@smaug---- Could you clarify what you mean by "select size > 1"? :blank has more to do with a form field that has no user input yet, so I'm trying to understand how that could match a select without the multiple attribute set (aka select base (w/o multiple attr)).

@annevk
Copy link
Member Author

annevk commented Nov 17, 2022

@smaug---- means this case: <select size=2><option>A<option>B</select>.

@brandonmcconnell
Copy link

brandonmcconnell commented Nov 17, 2022

@annevk @smaug---- Ahh well TIL 😆 I had no idea that attribute even existed and that it worked like that. Yes, that should probably be supported as well, when size > 1

Thanks for calling that out, @smaug---- 🙌🏼

So re :blank support for select:

  • select (w/o multiple attr and when size < 2) NEVER matches :blank
  • select[multiple] CAN match :blank when no option(s) are selected ✅
  • select[size] CAN match :blank when size > 1 and no option(s) are selected ✅


Updated my previous comment to reflect the same

@domenic
Copy link
Member

domenic commented Nov 18, 2022

/cc @tabatkins @fantasai as editors of Selectors, to see if the proposal inside the <details> elements in #8451 (comment) makes sense to you and would be something we can put into HTML eventually.

@fantasai
Copy link
Contributor

fantasai commented Dec 13, 2022

Not speaking for the CSS Working Group, but @tabatkins and I more or less agree with the outline in #8451 (comment) with a few extra comments:

  • We think <select> should be blank if it's set to submit an empty string. Using a blank value as the default is a common pattern, and should match :blank.
  • We think unchecked checkboxes and radio button should also match :blank, as these are commonly considered “blank”; if I was talking about a “blank checkbox” on a page this would not be an unusual turn of phrase. (While this is technically redundant with a :not(:checked), this seems to match likely author expectations and is a trivial addition.)
  • If we want to enable :blank on form or fieldset, it should match that element when all elements associated with it that are capable of being blank are :blank. (Think about paper forms: a blank form is one that's completely empty, other than the outline of the form itself.) Note that this behavior cannot easily be duplicated with :has() selectors.

The rule of thumb is, “if it always submits, and would do so with an empty string, it's :blank; if it sometimes submits, and is set to not submit, it's :blank”. Action buttons (rather than toggle buttons that represent a state) such as <input type=reset>, <button>, <input type=submit>, etc., never match :blank.

@brandonmcconnell
Copy link

brandonmcconnell commented Dec 13, 2022

@fantasai Really good thoughts all around. Those are great clarifications, and I'd love to move the :blank def forward with those mods if/when the CSSWG agrees on that.

For the time being, I'll go ahead and make those adjustments to my outline above.

If we're going to enable form and fieldset, it may be worth also supporting label. I'll make that change above, but please let me know if you disagree with that notion.

@annevk
Copy link
Member Author

annevk commented Dec 14, 2022

:blank should probably not be quite the same as :not(:checked) as we wouldn't want it to match when :indeterminate matches I think.

@tabatkins
Copy link
Contributor

Good point! Okay that removes my own weak "technically redundant" objection.

@brandonmcconnell
Copy link

I adjusted my outline above to match that change as well.

@jacobrask
Copy link

jacobrask commented Dec 18, 2022

As @smaug---- notes in the originating issue we also need to deal with placeholder somehow. My intuition would be that it doesn't influence :blank, but others might feel differently about that.

I would definitely expect :blank to apply in the same circumstances as :placeholder-shown for any of the elements that support it with a non-empty placeholder attribute.

@brandonmcconnell
Copy link

brandonmcconnell commented Dec 19, 2022

Yeah, good point. I would definitely vote for :placeholder-shown having no effect on :blank.

That way, anyone who needs to target a hybrid between the two can do so like this:

*:blank:not(:placeholder-shown) {
  /* ... */
}

@tabatkins
Copy link
Contributor

Yes, an element showing a placeholder should still be blank (basically by definition; we show placeholders when the input is blank!).

@brandonmcconnell
Copy link

The discussion here seems pretty conclusive, but there are still some unanswered questions in this related CSSWG thread, if some of you wouldn't mind chiming in there as well: w3c/csswg-drafts#1967

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

9 participants