csswg-drafts icon indicating copy to clipboard operation
csswg-drafts copied to clipboard

[css-ui] appearance: base to enable interoperable styling of controls/components

Open gregwhitworth opened this issue 5 years ago • 52 comments

The below comment is in reference to an explainer level proposal regarding a new pseudo element and a way for an author to opt-in to a standardized DOM and styles, currently being proposed is appearance: base.

@gregwhitworth why not make the proposed behavior for appearance: base be the behavior for appearance: none for radio buttons and checkboxes? Would it not be web compatible? There are likely some sites that use appearance: none plus a background image to show the checkmark, so this would show a double checkmark, though I don't know how common it is. Maybe it's even an acceptable change? The content would still work, just not rendered as originally intended. When styling form controls, that shouldn't come as a huge surprise I would think.

CSS UI says that widgets should be usable even with appearance: none, but checkboxes and radio buttons as implemented today aren't. https://drafts.csswg.org/css-ui/#appearance-semantics

(Feel free to split this into a new issue if you want to separate the discussion around appearance from ::indicator.)

cc @frivoal

Originally posted by @zcorpan in https://github.com/w3c/csswg-drafts/issues/5914#issuecomment-778089292

gregwhitworth avatar Feb 16 '21 01:02 gregwhitworth

@zcorpan I had not considered that given that appearance: base takes the step of requiring a defined DOM and styles. You're correct at the definition that the behavior should remain but without that required DOM & styles we don't take a step towards the goal of this which is to enable styling of the built-in control/component without having to replace it.

I don't have a strong opinion regarding the switch that enables that DOM & styles, @frivoal recommended over on the explainer repo a base attribute on the control/component that would likewise enable this and would also not conflate appearance which some people think will lead to author confusion.

You both have more history investigating the appearance property so I'll happily take guidance to ensure that the following goals are met:

  1. Requires defined DOM & styles to enable an author to style the control/component
  2. Doesn't introduce author confusion
  3. Allows user agents & the CSSWG to incrementally enhance more controls & components without compat concerns

@fantasai brought up item 3 with the current proposal of appearance: base as authors may apply it to many controls and thus hindering our future additions. @tabatkins recommended a appearance: base-checkbox style approach to the problem and as noted @frivoal recommended a similar approach but with a HTML attribute.

cc: @tantek as he had opinions on this aspect as well

Also: Thank you all so much for the thoughtful engagement and help on this

gregwhitworth avatar Feb 16 '21 01:02 gregwhitworth

To sum up the possible options for a switch to a defined anatomy and UA styles we have:

  • appearance keyword of base-<control> (eg: base-checkbox)
  • A base attribute on the control (eg: <input type="checkbox" base>)

With regards to next steps - @tabatkins @frivoal @tantek @jensimmons am I missing any other possible solutions?

gregwhitworth avatar Mar 05 '21 23:03 gregwhitworth

Don't we want to have a defined DOM and styles for appearance: none?

zcorpan avatar Mar 06 '21 12:03 zcorpan

Does using SVG allow more CSS animation than html? Why not use clip path and a background instead?

While I applaud the idea of having standardized stylable component parts in the presence of appearance: base (especially for things like file upload controls), I’m not a fan of that being a single design for all eternity. I would rather allow for platforms to vary it somewhat and update in the future, but perhaps sticking to a limited set of properties, so that authors know which ones they will need to overwrite. Or just let the authors use all: initial.

I am also not against using glyphs, even if different platforms have different fonts. They don’t all have to look identical for this proposal of standardized component parts to be valuable. As long as the author can apply a different font, or use content: "" and a clipping path and background for that part, then it is just as customizable.

bradkemper avatar Mar 06 '21 16:03 bradkemper

appearance: base-checkbox on something other than a checkbox would not be good. I thought we were trying to get away from that. appearance: base seems better.

Also, I would prefer to keep this all in CSS. I often can only edit the CSS for a project, not the HTML or JavaScript. Perhaps we could have an at-rule for styles that only apply to elements that have appearance: base. appearance Property values inside the at-rule would be ignored.

bradkemper avatar Mar 06 '21 16:03 bradkemper

Don't we want to have a defined DOM and styles for appearance: none?

When initially discussing this with @fantasai and @frivoal in the fall 2020 they didn't want overload appearance: none for compat reasons; although that was the initial direction I was heading which is why I actually extend appearance: none with the base solution. The defined DOM structure I think is actually the least of the concerns for compat in this scenario though because properties that wouldn't have worked prior may begin working due to the standardization of base styles. I'm not entirely sure of a concrete scenario however given how appearance: none is most commonly used however. @fantasai @frivoal do you all have one?

Does using SVG allow more CSS animation than html? Why not use clip path and a background instead?

It provides greater flexibility on the parts (eg: paths) with strokes, joint, etc. Also, the minute you have to reach for background assets you've removed one of the key demos for this base solution which isn't to have to reach for any graphics software. It's also important to note that while SVG is currently being proposed for the checkmark that probably won't be the case for all control/component parts much in the same way that when authors create their own today they don't use SVG for the entire control.

I am also not against using glyphs, even if different platforms have different fonts. They don’t all have to look identical for this proposal of standardized component parts to be valuable. As long as the author can apply a different font, or use content: "" and a clipping path and background for that part, then it is just as customizable.

I am due to the limitations of styling to text as outlined in the explainer in comparison to SVG.

I’m not a fan of that being a single design for all eternity

I agree to an extent, this is commonly brought up but if one looks at many of the controls in the platform the models and base UX has remained the same since the webs inception. Upon looking into <select>, checkbox, radio, there are some that have existed prior in the same manner prior to browsers in native OSes and some (eg: checkbox/radio) prior to graphical UI. Some even exist well before mass access to computers existed, here's an example from 1963 with checkboxes, text inputs, date, date-time, etc. The important part to note is that this "design" will be a base but with the standardized DOM & styles they can adjust the look and feel utilizing the powerful layout capabilities we have today provided to us on the web. It will be purposefully plain and simple to give authors a starting point with the expectation that they will/can adjust it interoperably. So while I agree with your position I feel that cow paths are very well trodden in Graphical UI to be able to take a host of controls/components and define their parts and base styles.

appearance: base-checkbox on something other than a checkbox would not be good.

This is a good point and one we'll need to ensure is accurately informed to authors as well in spec text as it will only apply to an HTMLInputElement with a state of checkbox; or other elements as we make progress with others. As appearance: none works today it removes the native styling but doesn't enforce a DOM nor base styles for that DOM. Does that clarify it?

gregwhitworth avatar Mar 09 '21 18:03 gregwhitworth

The CSS Working Group just discussed appearance: base to enable interoperable styling of controls/components, and agreed to the following:

  • RESOLVED: This feature should be solved with an attribute rather than a CSS value
The full IRC log of that discussion <Rossen_> Topic: appearance: base to enable interoperable styling of controls/components
<Rossen_> github: https://github.com/w3c/csswg-drafts/issues/5998
<myles> gregwhitworth: The context is that we're trying to start down the path of standardizing form controls and components. We'll need an agreed-upon DOM and styles.
<myles> gregwhitworth: Last time I presented on this, I presented about the base appearance keyword and the pseudo element for checkbox. I want to de-tangle them. I've had requests for input type=range
<myles> gregwhitworth: I want to move forward with the base keyword.
<myles> gregwhitworth: For more context, the base keyword would be a toggle that informs the browser that you want to have a standardized dom and styles for a given element. That would allow you to style interoperably.
<myles> gregwhitworth: UAs want to provide their own defaults. Authors need to opt-in.
<emilio> q+
<myles> gregwhitworth: I'm looking for feedback. questions, thoughts.
<Rossen_> ack emilio
<florian> q+
<myles> emilio: If we want this to change the shadow dom that UAs create, this is better as an attribute, despite that option sucking.
<myles> emilio: for gecko, it's kind of okay to create a lot of dom during layout. it's not amazing. I'd like to get rid of that mechanism. Blink generates the shadow dom at the DOM level, not depending on layout.
<myles> emilio: Making CSS changes affect DOM for them, i suspect it would be more of an issue.
<myles> emilio: Conceptually, it feels wrong
<myles> gregwhitworth: Sure. I'm primarily .... not that that's bikeshedding .... I want to get at the more meta-issue. If implementors say they prefer the attribute, I can bring this to WHATWG. I'm asking if this group accepts standardized styles and standarized DOM
<myles> emilio: I'm definitely okay in getting more interop in form controls.
<myles> emilio: This detail probably matters.
<myles> emilio: Can chrishtr weigh in?
<hober> q+
<myles> emilio: Is CSS the right place for this toggle?
<tantek> +1 emilio
<myles> hober: My understanding is that we're also pretty reluctant to add more mechanisms in CSS that cause DOM to get created.
<myles> hober: So, I think, this does seem like a problem we should be trying to solve. An attribute would be less weird.
<myles> hober: ... on the implementation side of things.
<Rossen_> ack florian
<myles> florian: In addition to the implementation complexity, I have 2 other reasons for why attributes are probably better.
<Rossen_> ack hober
<myles> florian: 1. If we got with a CSS property with a single bas keyword, we need to introduce it simultaneously on all the elements that accept it, or have a bunch of values so people can detect their way into doing the right thing. That problem isn't true if we do it as an attribute.
<myles> florian: 2. Depending on whether an element is base or not base, you want to style it differently. If you cause it to be base or not base through CSS, then you can't select on it.
<tantek> +1 florian about what you want to style differently
<myles> florian: The UA stylesheet needs to be different for a regular checkbox vs a base checkbox, if the switch is in CSS, all that solves itself if the switch is done via an attributre.
<Rossen_> ack fantasai
<myles> florian: We have multiple things pointing in this direction. All of these work better if we got with an attribute vs a CSS property.
<myles> fantasai: Just to throw a wrench into that, florian, you want to style them differently based on the attribute, but also on whether or not the browser supports that attribute
<myles> florian: We should have an attribute an attribute AND a pseudoclass.
<myles> fantasai: We can also add an @supports query.
<myles> fantasai: We need a way to answer the question "is this implemented"
<myles> florian: The base pseudoclass would mean "is it present AND implemented"
<fremy> +1 to the pseudo-class suggested by florian
<myles> florian: pseudoclasses are simpler
<tantek> +1 to considering pseudoclass
<myles> fantasai: For style vs content vs behavior, this belongs more in CSS than HTML. But emilio and florian gave good arguments for why it might have to end up in HTML regardless.
<myles> fantasai: If we add appearance: value, I would go for appearance: basic
<tantek> in general I'm opposed to any extension to the 'appearance' property, but that's a lower level concern
<heycam> `input[type=checkbox]:custom`
<myles> Rossen_: Most of the conversation leans toward attribute. gregwhitworth, does that work?
<myles> gregwhitworth: I want a resolution, as ammunition for going to WHATWG
<myles> gregwhitworth: Also for adding styles to checkbox. I'm looking for a resolution.
<myles> florian: 2 resolutions: 1. to use an attribute, and 2. to add a pseudoclass
<myles> fantasai: proposed resolution: This functionality be pursued as an attribute, and CSS adds a mechanism to detect an element in this mode in a browser that has support for it
<myles> gregwhitworth: I'm fine working on that BTW
<fantasai> "CSS Working Group recommends that"
<myles> bkardell_: Wouldn't existing "define" work?
<myles> bkardell_: the "define" pseudoclass
<myles> bkardell_: should work
<myles> bkardell_: I guess not, because it's already defined. never mind
<myles> emilio: It almost works, because you can't extend form controls. But maybe you can. If you can, then it doesn't work
<myles> gregwhitworth: I don't want to go down that rabbit hole
<myles> emilio: It seems cleaner to use a different thing
<myles> Proposed resolution: This functionality be pursued as an attribute instead of a CSS property, and CSS adds a mechanism to detect an element in this mode in a browser that has support for it
<bkardell_> it woudl already be true, is the real problem I think
<myles> florian: I support the resolution as it stands. But I would also support a more specific resolution: the mechanism is a pseduclass. @supports would be awkward. Psedudoclass would make it easy. If we do a pseudoclass, we have to figure out which element you're testing against. Would look like a selector
<bkardell_> 0 specificity pseudo please?
<myles> fantasai: Yeah, this is element-by-element
<myles> florian: It's also applied element-by-element
<myles> fantasai: yeah.
<myles> fantasai: I guess that what it's going to have to be. I can't think of a name that makes sense
<myles> florian: We should match the name that HTML sues
<myles> bkardell_: Can it be 0 specficity?
<myles> gregwhitworth: Can we figure this out after I open the issue?
<myles> bkardell_: yes.
<myles> fantasai: I support greg investigating whether or not it should be 0 specificity
<myles> s/greg/gregwhitworth/
<myles> Rossen: We were leaning toward using an attribute. Second resolution: Adding a mechanism to detect the state of the feature. Is this right?
<myles> RESOLVED: This feature should be solved with an attribute rather than a CSS value
<fantasai> [I would like to note that it's not great that, in order to change the styling of the form element, it's necessary to change the markup. But it seems we're constrained by practical considerations.]
<myles> ACTION gregwhitworth: Create an issue about adding a mechanism in CSS to determine if this feature is enabled

css-meeting-bot avatar Apr 08 '21 23:04 css-meeting-bot

The reasons given for handling this as an attribute rather than in CSS (even though it is about presentation and otherwise would belong in CSS):

  • DOM modifications that depend on CSS computed values are messy/difficult to implement
  • We need to be able to style differently depending on whether the element is basic or not, and an attribute allows for selecting against that.
  • An attribute is less likely to create the forwards-compatibility problem that rules like * { appearance: base } would create if only some form elements supported basic rendering and others didn't.

fantasai avatar Apr 09 '21 00:04 fantasai

I get the reasoning of not using CSS for DOM building, but I think the end result of doing an attribute is that instead of doing this:

* { appearance: base; /* etc. */ }

Authors will just do this instead:

*[base]:base { /* etc. */ }

And if they have control over the HTML, they will add the base attribute to every form element whether it is currently supported or not.

And those without control over the HTML won't be able to take advantage of this feature.

I'd still rather have just a pseudo be the switch for whether or not to use the alternate DOM, when it is supported on that element.

Sorry I missed the meeting. It sounds like it was a very interesting conversation.

bradkemper avatar Apr 09 '21 15:04 bradkemper

DOM modifications that depend on CSS computed values are messy/difficult to implement

I wonder if we need this aspect. If we provide sufficient pseudo-elements web developers should have their styling needs addressed as well.

annevk avatar Aug 25 '23 07:08 annevk

So the resolution above was initially this:

Proposed resolution: This functionality be pursued as an attribute instead of a CSS property, and CSS adds a mechanism to detect an element in this mode in a browser that has support for it

and I think the second part got accidentally (based on the detailed notes) left off the resolution. Does that sound right?

If so, we need to add a new attribute to HTML that enables interoperable styling on controls that wear it. And we need to add a pseudo class to CSS that matches when an element supports interoperable styling. That leaves a few questions:

  1. What should the name of the attribute be? By itself, base seems wrong. It made sense when it was appearance:base, but just base as an attribute feels hard to understand. How about something like interoperable? That feels too long, but at least it explains what it's trying to do.
  2. What should the name of the pseudo class be? Perhaps just the same as the name of the attribute? E.g. input[interoperable]:interoperable?
  3. How does this attribute interact with appearance? There would seem to be two possibilities. One is that input[interoperable] {appearance:auto} and input[interoperable] {appearance:none} both render the same way, with an interoperable spec-defined set of styles and DOM structure. The other is that only appearance:none does that, and appearance:auto is still up to the UA to define. I think I prefer the former, but I'm not sure.

mfreed7 avatar Dec 01 '23 21:12 mfreed7

  1. I don't like either base (could refer to base URLs or other) or interoperable (things should generally be interoperable). Maybe something like basestyle or stylable?
  2. Why is a pseudo-class needed if it only checks the presence of an attribute?
  3. It seems to me the former has to be chosen, or it was moot to use an attribute.

zcorpan avatar Dec 21 '23 14:12 zcorpan

  1. interoperable sound great! Basestyle as a second favorite
  2. I would ecpect pseudo is needed to know that basestyle is actually supported for that element and was applied.

kbrilla avatar Dec 21 '23 14:12 kbrilla

  • I don't like either base (could refer to base URLs or other) or interoperable (things should generally be interoperable). Maybe something like basestyle or stylable?

I kind of like basestyle - it says that it's related to styles, and it has "base" which I like for some reason. I don't like stylable for two reasons - there are two spellings (also styleable) and all controls are stylable in some ways even if they don't have interoperable styling which is what this attribute implies.

  • Why is a pseudo-class needed if it only checks the presence of an attribute?

The pseudo class allows for feature detection - it should only match when the attribute is actually supported on a given element. I.e. const supported = document.createElement('select').matches(':basestyle');. If there's a better way to do feature detection element-by-element, I think that'd be fine too.

  • It seems to me the former has to be chosen, or it was moot to use an attribute.

I don't understand this comment, sorry.

mfreed7 avatar Dec 21 '23 19:12 mfreed7

@mfreed7 wrote:

I kind of like basestyle - it says that it's related to styles, and it has "base" which I like for some reason.

I do so as well. Though note, in CSS, names are generally dash-separated, so it should be base-style.

Sebastian

SebastianZ avatar Dec 22 '23 22:12 SebastianZ

Maybe unstyled could work as the name of this attribute, implying that authors would have to style these controls themselves?

SelenIT avatar Dec 23 '23 15:12 SelenIT

I like unstyled also, maybe better actually.

I do so as well. Though note, in CSS, names are generally dash-separated, so it should be base-style.

But this is the name of an HTML attribute, which typically don’t have dashes. Perhaps you’re talking about the pseudo class for feature detection?

mfreed7 avatar Dec 23 '23 16:12 mfreed7

I do so as well. Though note, in CSS, names are generally dash-separated, so it should be base-style.

But this is the name of an HTML attribute, which typically don’t have dashes. Perhaps you’re talking about the pseudo class for feature detection?

I did talk about the pseudo-class, yes. I didn't realize before the resolution was to add an HTML attribute and make it detectable in CSS. But given that, the HTML attribute may still be called basestyle. Generally, I believe the attribute name and the name in CSS should be aligned with each other.

Maybe unstyled could work as the name of this attribute, implying that authors would have to style these controls themselves?

Form elements with that attribute will still have some basic styling, right? So "unstyled" may not be fully true. Though as we are searching for something that fits for both HTML and CSS, it might make sense to use a single word to avoid the issue of the names being different due to the different word separation rules in both languages. So "unstyled" sounds ok.

Sebastian

SebastianZ avatar Dec 23 '23 22:12 SebastianZ

I don't think we should add a new HTML attribute for this. Although it is a bit janky and CSS should probably support it better, it's possible to implement this without a new HTML attribute and adding an HTML attribute for this would be mixing styling and semantics, something which we've managed to avoid doing for a very long time now.

annevk avatar Jan 08 '24 12:01 annevk

I don't think we should add a new HTML attribute for this. Although it is a bit janky and CSS should probably support it better, it's possible to implement this without a new HTML attribute and adding an HTML attribute for this would be mixing styling and semantics, something which we've managed to avoid doing for a very long time now.

Would you mind suggesting an alternative, rather than just saying "no"? This was discussed at length in CSSWG and the conclusion was that an attribute was the best solution.

mfreed7 avatar Jan 08 '24 19:01 mfreed7

I'm not sure that was an "at length" discussion, but it's been discussed a number of times since then as well, including in this thread. And the alternative is using a new appearance value and branching code on that. WebKit at least hasn't fully ruled out that option and I wouldn't really want to consider HTML-based alternatives until we're sure we cannot solve this through styling.

annevk avatar Jan 09 '24 09:01 annevk

Ok, sounds like we're back to needing a CSS solution. That's appearance:base and an :appearance-base-supported pseudo-class (name TBD) to detect support on each element. Right?

@hober and @emilio were concerned about changing DOM structure based on CSS property values, I'm not sure if that's still an issue?

I'm still concerned about forward compat issues. While they were possible with a base attribute, it seems a lot less likely for someone to add base to every element on the page than it does for someone to add * {appearance:base} to a stylesheet.

mfreed7 avatar Jan 09 '24 16:01 mfreed7

I think the details of the CSS-based solution are still up for debate. Perhaps as a start we introduce one-off values for each control and once we've covered all controls we can add a catch-all and new controls would have to support it out-of-the-box once you support the catch-all. That might allow us to get somewhere incrementally. E.g., we could start by adding appearance:base-radio that would only work on <input type=radio>.

annevk avatar Jan 09 '24 17:01 annevk

I appreciate the continued discourse. Since we resolved on using <select> over introducing a new element (eg: selectlist) I would still prefer a CSS based solution even if we have to do the control by control approach that @annevk outlined. Only concern with the CSS approach is the potential performance implications going back to adjust the tree after style calc.

I think for new elements we should follow the resolution of them being interoperable by default and opt in to native UA styling/tree/external control. This is what we resolved on in Open UI when first discussing this which can be found here.

gregwhitworth avatar Jan 09 '24 23:01 gregwhitworth

I had not heard of that before. The WebKit team strongly believes that the defaults should be consistent across controls and thus disagrees with that Open UI resolution.

annevk avatar Jan 10 '24 10:01 annevk

@annevk yeah, I added this topic to our agenda to discuss tomorrow because since Open UI resolved to use select rather than selectlist based on your feedback; it has the domino effect and it will ultimately result in aligning with WebKit's position.

gregwhitworth avatar Jan 10 '24 17:01 gregwhitworth

I had not heard of that before. The WebKit team strongly believes that the defaults should be consistent across controls and thus disagrees with that Open UI resolution.

Just to be sure I understand this comment - you're saying you don't think appearance:base (or whatever the API shape ends up being) should be the default. Is that right? I.e. you're still supportive of a way to get to interoperable styles, just not by default? (We're discussing this tomorrow at OpenUI - it'd be great if you could attend to offer your opinions regardless.)

mfreed7 avatar Jan 10 '24 17:01 mfreed7

That's correct. Unfortunately Open UI meets at a time that would be disruptive for my sleep. Aditya will be there though.

annevk avatar Jan 10 '24 18:01 annevk

I'll be there, but will miss the first 20 minutes.

pxlcoder avatar Jan 10 '24 23:01 pxlcoder

We can't post our minutes directly here but we just discussed this (we'll carry it forward to next week) in the Open UI telecon. Here are the minutes: https://www.w3.org/2024/01/11-openui-minutes.html

gregwhitworth avatar Jan 11 '24 20:01 gregwhitworth