- From: Lea Verou <lea@verou.me>
- Date: Sun, 27 Mar 2016 00:30:12 -0400
- To: Amelia Bellamy-Royds <amelia.bellamy.royds@gmail.com>
- Cc: www-style list <www-style@w3.org>
- Message-Id: <159977FD-C38E-44E1-8575-EE8CF32819F4@verou.me>
+1 to all of Amelia's points here. Lea Verou ✿ http://lea.verou.me ✿ @leaverou > On 26Mar, 2016, at 21:14, Amelia Bellamy-Royds <amelia.bellamy.royds@gmail.com> wrote: > > A hearty "hear, hear" to all of Lea's arguments. Authors need a consistent and extensible way to pass styles to user agents for use within native widgets. And the biggest obstacle to doing so right now is that CSS selectors for styling widget components in one browser are invalid CSS in any other. > > But would it be possible to simplify even further? > > Native widgets aren't the only case where the non-robust parsing rules are a problem. It comes up every time a new standard pseudo-class or pseudo-element is introduced. If you want to use a JS polyfill to add a class or aria-attribute instead of an unsupported pseudo-class, you'll either need to duplicate your CSS code, or use JS to find and replace the unrecognized selectors in the CSS plain text. > > So rather than defining a new selector for sub-components, would it be possible to define generic ::pseudo-element and :pseudo-class selectors? In other words, make it so that one or two colons followed by a valid CSS token is treated as a valid selector in any CSS parser. If the user agent doesn't recognize the pseudo-* name, it just skips over it the same way it does a class or tag name that doesn't match anything. That particular selector doesn't match, but other selectors in the same rule can still be evaluated. > > So you could do: > > input[type="range"]::-webkit-slider-thumb, > input[type="range"]::-moz-range-thumb, > input[type="range"]::-ms-thumb { /* styles for all */ } > > But you could also do: > > form:hover, > form:focus, > form:focus-within, /* if not supported yet, breaks the whole rule currently */ > form.contains-focus /* the fallback-class added by JS if :focus-within not supported */ > { /* styles */} > > I realize that suggesting a change to the fundamental CSS parsing rules could have wide-reaching implications. However, I'd be interested in whether anyone can come up with practical examples where changing an invalid selector to a valid-but-doesn't-match-anything selector would break existing code. Possibly there are horrible hacks for targetting CSS to specific browsers that rely on this behavior, but that's all I can think of. > > ~Amelia Bellamy-Royds > > On 21 March 2016 at 20:33, Lea Verou <lea@verou.me <mailto:lea@verou.me>> wrote: > The current situation > ————————————————— > > There is a large number of native, UA-dependent controls that authors want to style. To name a few: select, option, meter (and its various states), progress, input[type="whatever"], video & audio media controls, validation messages, placeholder text, details marker, scrollbars, resize widget. > > Currently, every UA exposes a bunch of proprietary pseudo-elements [1] for this. These pseudos come and go, or change at any time, and since they’re prefixed and inconsistent, authors have to duplicate their styles multiple times to work around invalid selector parsing rules. Despite these issues, authors STILL prefer to use these proprietary pseudo-elements, but there is a lot of pain and duplication involved. There are numerous tutorials and Q&As on the Web revolving around which pseudo-elements to use for any given component (see [2] for a tiny sample). > > There is also a number of scripts duplicating native behavior, just for styling purposes (fake scrollbars, fake select dropdowns etc etc. We’ve all seen them). This is even worse as it leads to decreased usability and accessibility. > > At this point, I don’t think anybody can reasonably continue arguing that authors should "just stop" styling native controls. They clearly need to, and UAs are trying to accommodate their use cases as they best can, while there is no standard to make this less painful for authors. I think this is a problem we need to address asap. The landscape of styling native components is currently as inconsistent as general CSS was in the early 2000s, and authors are using this CSS anyway and leaving tons of future web compat issues behind them. > > Problems with standardizing a solution > —————————————————— > > The internal implementations of these components are vastly different on different UAs and platforms. E.g. a calendar widget on Mobile Safari is completely different than a calendar widget on Chrome Desktop. Therefore, using the shadow DOM piercing combinator and targeting specific elements (e.g. video >>> input[type=range]) is flimsy, not to mention that browsers need to be free to change their internal representations. > > Most importantly, *not every part that authors want to style is part of the shadow DOM*. For example scrollbars or resizer widgets are not. > > Efforts to standardize which parts are exposed or which properties are allowed by explicitly defining them [3] is bound to become a lowest common denominator solution and not actually address authors’ use cases. Standardizing pseudos on a case-by-case basis (e.g. :placeholder-shown, ::placeholder, > > A modest proposed solution > —————————————————— > > Let’s leave the identifiers, what they correspond to, and which properties are allowed UA-dependent, but define a parameterized pseudo-element for addressing them en masse. Most of the pain in styling native components today is not so much due to the varying pseudo-element identifiers, but due to the duplication and prefixes. E.g. to style a slider thumb, one has to write: > > input[type="range"]::-webkit-slider-thumb { /* styles */ } > input[type="range"]::-moz-range-thumb { /* styles, again */ } > input[type="range"]::-ms-thumb { /* styles, again */ } > > With this proposal, authors would be able to write: > > input[type="range"]::parts(slider-thumb, range-thumb, thumb) { /* styles */ } > > On platforms where the range input does not have a thumb, the selector just doesn’t match anything. > > One could argue that we can do this with the Shadow DOM + classes and write something like: > > input[type="range"] >>> ::matches(.slider-thumb, .range-thumb, .thumb) { /* styles */ } > > However, note that: > - Native controls are not always part of the Shadow DOM (e.g. scrollbars, resizers, selects and date pickers on mobile) > - Even when native controls could have been part of the Shadow DOM, they are often not implemented that way. > - Some of the existing pseudos correspond to states, not just elements, e.g. ::-webkit-meter-optimum-value, ::-webkit-meter-suboptimum-value, ::-webkit-meter-even-less-good-value > - Given that this essentially syntactic sugar over the various existing pseudo-elements [1], it should be relatively quick/easy to implement and doesn’t require implementing the entire Shadow DOM spec (also, not all parts can be expressed as Shadow DOM). > - In addition, if the Shadow DOM provides a mechanism for hooking into this, author components can also expose select parts similarly. > - Hopefully, given that this leaves so much implementation-dependent, it should provide enough motivation for UAs to stop creating more proprietary pseudo-elements. > > We could still define a list of minimum properties that apply to these parts, e.g. fonts, colors, backgrounds, shadows etc. Also, there could be a centralized list for recommended identifiers when multiple conflicting ones exist for the same part (e.g. slider-thumb, range-thumb, thumb), so that UAs eventually converge, organically. But I believe the first version of this should leave a lot up to the UA to stop this pseudo-element madness in its tracks. > > PS: Turns out there is a very similar earlier proposal by hober [4], very good arguments there as well! > > [1]: Lists of the various pseudo-elements currently in use: > http://trac.webkit.org/wiki/Styling%20Form%20Controls <http://trac.webkit.org/wiki/Styling%20Form%20Controls> > https://gist.github.com/webtobesocial/aefd6e25064c08e0cc9a <https://gist.github.com/webtobesocial/aefd6e25064c08e0cc9a> > https://www.tjvantoll.com/2013/04/15/list-of-pseudo-elements-to-style-form-controls/ <https://www.tjvantoll.com/2013/04/15/list-of-pseudo-elements-to-style-form-controls/> > > [2]: A tiny sample of tutorials: > https://css-tricks.com/html5-meter-element/ <https://css-tricks.com/html5-meter-element/> > http://www.hongkiat.com/blog/html5-progress-bar/ <http://www.hongkiat.com/blog/html5-progress-bar/> > https://css-tricks.com/html5-progress-element/ <https://css-tricks.com/html5-progress-element/> > https://css-tricks.com/styling-cross-browser-compatible-range-inputs-css/ <https://css-tricks.com/styling-cross-browser-compatible-range-inputs-css/> > http://codepen.io/collection/DgYaMj/8/ <http://codepen.io/collection/DgYaMj/8/> > https://css-tricks.com/webkit-html5-search-inputs/ <https://css-tricks.com/webkit-html5-search-inputs/> > https://css-tricks.com/numeric-inputs-a-comparison-of-browser-defaults/ <https://css-tricks.com/numeric-inputs-a-comparison-of-browser-defaults/> > https://css-tricks.com/snippets/css/turn-off-number-input-spinners/ <https://css-tricks.com/snippets/css/turn-off-number-input-spinners/> > https://css-tricks.com/snippets/css/custom-file-input-styling-webkitblink/ <https://css-tricks.com/snippets/css/custom-file-input-styling-webkitblink/> > http://qnimate.com/guide-to-styling-html5-input-elements/ <http://qnimate.com/guide-to-styling-html5-input-elements/> > https://css-tricks.com/custom-scrollbars-in-webkit/ <https://css-tricks.com/custom-scrollbars-in-webkit/> > https://codegeekz.com/customize-your-scrollbars-with-css3-and-jquery/ <https://codegeekz.com/customize-your-scrollbars-with-css3-and-jquery/> > http://poselab.com/en/custom-scrollbars-in-webkit/ <http://poselab.com/en/custom-scrollbars-in-webkit/> > http://webdesign.tutsplus.com/articles/quick-tip-styling-scrollbars-to-match-your-ui-design--webdesign-9430 <http://webdesign.tutsplus.com/articles/quick-tip-styling-scrollbars-to-match-your-ui-design--webdesign-9430> > https://davidwalsh.name/style-textarea-resizer <https://davidwalsh.name/style-textarea-resizer> > https://css-tricks.com/almanac/properties/s/scrollbar/ <https://css-tricks.com/almanac/properties/s/scrollbar/> > http://advprog.blogspot.com/2013/07/styling-html-media-inner-workings.html <http://advprog.blogspot.com/2013/07/styling-html-media-inner-workings.html> > https://css-tricks.com/custom-controls-in-html5-video-full-screen/ <https://css-tricks.com/custom-controls-in-html5-video-full-screen/> > http://tylergaw.com/articles/fun-with-html-form-validation-styles <http://tylergaw.com/articles/fun-with-html-form-validation-styles> > http://webdesign.tutsplus.com/tutorials/bring-your-forms-up-to-date-with-css3-and-html5-validation--webdesign-4738 <http://webdesign.tutsplus.com/tutorials/bring-your-forms-up-to-date-with-css3-and-html5-validation--webdesign-4738> > http://thereforei.am/2011/07/01/css-selectors-for-html5-input-validation/ <http://thereforei.am/2011/07/01/css-selectors-for-html5-input-validation/> > http://www.useragentman.com/blog/2012/05/17/cross-browser-styling-of-html5-forms-even-in-older-browsers/ <http://www.useragentman.com/blog/2012/05/17/cross-browser-styling-of-html5-forms-even-in-older-browsers/> > > Also numerous stackoverflow Q&A omitted for brevity. > > [3]: https://drafts.csswg.org/css-forms/ <https://drafts.csswg.org/css-forms/> > [4]: https://lists.w3.org/Archives/Public/www-style/2014Feb/0621.html <https://lists.w3.org/Archives/Public/www-style/2014Feb/0621.html> > > Lea Verou ✿ http://lea.verou.me <http://lea.verou.me/> ✿ @leaverou > > > > > > > >
Received on Sunday, 27 March 2016 04:30:38 UTC