Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign up[css-cascade] Custom cascade origins #4470
Comments
This comment has been minimized.
This comment has been minimized.
|
It strikes me that in some ways specificity already works in isolated layers:
Clearly that was the original intent: components (IDs) override patterns (classes/attributes) override defaults (elements). But it maybe falls apart in modern use for a few reasons:
That could lead us down a path of providing more specificity layers rather than origin layers? I'm not sure… |
This comment has been minimized.
This comment has been minimized.
Its goal is exactly the opposite: because it's a pseudo-class, it allows only removing part of the selector from the specificity calculation, enabling authors to distinguish importance-signifying criteria from merely filtering criteria. Of course it can be used for the whole selector, but it doesn't have to be, nor was that the primary use case I had in mind when I proposed it. |
This comment has been minimized.
This comment has been minimized.
|
The CSS Working Group just discussed The full IRC log of that discussion<fantasai> Topic: Custom Origins<jensimmons> https://noti.st/jensimmons/QOEOYT/three-topics#srFUYHC <astearns> github: https://github.com//issues/4470 <TabAtkins> jensimmons: Possibility of custom cascade origins, controlled by authors. <TabAtkins> jensimmons: Part of a larger convo, which could be called "modernize the cascade" <TabAtkins> jensimmons: Why modernize? Some folks argue that specificity was designed for a simpler time, when one or a small number of people wrote the CSS for a site. Today CSS is maintained over years by large teams, and the cascade gets really hard. <TabAtkins> jensimmons: If a dev gets a ticket, they can't really rearchitect the whole page's cascade to fix that one thing. <TabAtkins> jensimmons: Lots of ways people attack this. <TabAtkins> jensimmons: (1) just do it right the first time <TabAtkins> jensimmons: (2) OOCSS, SMACSS, BEM, etc <TabAtkins> jensimmons: (3) Only ever use one class, to give identical specificity and remove the cascade. <TabAtkins> jensimmons: (4) overuse !important <TabAtkins> jensimmons: (5) CSS-in-JS, ignoring cascade again <TabAtkins> jensimmons: Problem there is no way to control order CSS is loaded. No wonder the cascade is confusing! <TabAtkins> jensimmons: (6) just inline-style everything, screw selectors <TabAtkins> jensimmons: Why not use specificiy as designed? <TabAtkins> jensimmons: IDs increase specificity, but can only use it once per page <TabAtkins> jensimmons: Not great for components. <TabAtkins> jensimmons: Element selectors work well for simple defaults, but too dependent on doc structure, and hard to use otherwise. <TabAtkins> jensimmons: So leaves a lot of these teams only using classes, attributes, and !important <TabAtkins> jensimmons: [shows example] <TabAtkins> jensimmons: [Tailwind CSS] <TabAtkins> jensimmons: [everything's inline, with no cascade] <TabAtkins> jensimmons: A lot of possible ideas here too, web components, scoping, etc. <TabAtkins> jensimmons: A project I did last year is how to protect CSS from this hate. <TabAtkins> jensimmons: So we put together a hard-core course on teaching the cascade. <TabAtkins> jensimmons: Miri Suzanne did a deep dive into the history/etc. <TabAtkins> jensimmons: She began thinking about how we could change CSS to modernize the cascade and work better. <TabAtkins> jensimmons: One of her ideas is to extend selectors, in #4690. <astearns> https://github.com//issues/4690 <TabAtkins> jensimmons: Another idea is to allow authors to make custom cascade origins. <TabAtkins> jensimmons: I didn't really know what a cascade origin was until Miri taught me. <TabAtkins> jensimmons: [describes the cascade origins] <fantasai> See https://www.w3.org/TR/css-cascade-4/#cascade-origin <TabAtkins> jensimmons: Proposal is for custom origins. Say, create 3 named origins (get !important variants automatically that work as expected), and put styles in the chosen origin to get auto-overriding. <TabAtkins> jensimmons: So use case. <TabAtkins> jensimmons: Reset styles in one origin, design system in another, then one-off overrides into a third. <TabAtkins> jensimmons: Or split apart the design system: reset -> defaults -> patterns > layouts -> components, all distinct origins. <emilio> q+ <TabAtkins> jensimmons: Or CMS Core -> CMS Extensions -> Base theme -> site styles <TabAtkins> jensimmons: Or a team trying to rewrite their CSS. Can't fix it all at once, but could put all their old code in one origin, and put their new code in a higher origin, to piecemeal fix it as they go. <TabAtkins> jensimmons: Or Bootstrap -> 3rd party -> ad networks -> actual site styles <TabAtkins> jensimmons: Adventages? <TabAtkins> jensimmons: Coudl help with specificity wars between frameworks and author styles. <TabAtkins> jensimmons: Could put !important back into its proper role, rather than being abused just to get a second origin. <TabAtkins> jensimmons: Or just using origins as a type of !important; might be just as annoying? <TabAtkins> jensimmons: Pulled some use-cases from Twitter (already mentioned) <TabAtkins> jensimmons: So what do you think? Want to pursue? <hober> q? <florian> q+ <fremy> q+ <astearns> ack emilio <fremy> q- <TabAtkins> emilio: I'm a bit confused abuot !important. <TabAtkins> emilio: If you want ad networks on an origin, and your styles on a higher origin, the ad networks could still override everything with !important style. Maybe that's not what you want? <bkardell_> q+ <TabAtkins> emilio: Second, it may be invalid, but IDs *can* be repeated on the page... <TabAtkins> emilio: There are ways for authors to use cascading origins that have better behavior - web components. <fantasai> fantasai: They're really hard to use <fantasai> TabAtkins: And also won't handle these use cases <TabAtkins> TabAtkins: WC doesn't solve any 0f Jen's use-cases, tho. <TabAtkins> emilio: When we discussed custom element default styles behavior, Apple was strongly against. Unsure if the'd still have complaints. <fantasai> i/emilio/iank_: We should add declarative shadow roots <TabAtkins> hober: I'l talk to Ryosuke/Antii, see if they have feelings on this. <emilio> Though ++ to declarative shadow roots <astearns> ack florian <TabAtkins> florian: I think it's a brilliant idea. <TabAtkins> florian: We've had the luxury of multiple origins here in CSS, letting us design thru problems. Authors haven't had that. <TabAtkins> florian: I think it would be great. Almost want to stop talking about whether or not to do it and jus tstart talking syntax. <TabAtkins> florian: Even as a singl eauthoe this seems useful. <TabAtkins> q+ <astearns> ack fantasai <TabAtkins> fantasai: I always want to say I love it. <astearns> ack dbaron <TabAtkins> dbaron: I'm also a big fan. <TabAtkins> dbaron: There are multiple choices we coudl make about !important. <TabAtkins> dbaron: Don't have to say they go in the opposite order. They could go in the same order, or be configurable, etc. <fantasai> +1 <TabAtkins> dbaron: Maybe have the !important right after the normal origin. <fantasai> essentially an origin can encapsulate its !important level <TabAtkins> dbaron: So lots of options we could choose between, or let authors configure. <AmeliaBR> +1 to dbaron says. Definitely don't want !important to automatically do reverse order. <TabAtkins> fantasai: Along those lines, might have an origin with sub-origins. <heycam> q+ <TabAtkins> fantasai: Which might have its !important held within the larger origin <astearns> ack bkardell_ <TabAtkins> bkardell_: First, thanks for bringing it up. <astearns> q+ <TabAtkins> bkardell_: I've had these same conversations and I think this is really healthy. <fantasai> Examples (from slide 25): <fantasai> Reset < Design System < Overrides <fantasai> Reset < Defaults < Patterns < Layouts < Components <fantasai> CMS Core < CMS Extend < Base Theme < Site Styles <fantasai> Old Styles < New Styles <astearns> q- <fantasai> Bootstrap < 3rd-party libs < Ad network < Site Styles <TabAtkins> bkardell_: To discuss what people are actually doing, rather than just relying on education <TabAtkins> bkardell_: I think CSS-in-JS does have an order... <TabAtkins> jensimmons: They can, but don't always <TabAtkins> bkardell_: wrt WC, they don't solve all problems, but they do solve some. They're already .2% of the web archive, despite only getting the last impl this week. <TabAtkins> bkardell_: Do we really rely on origin for UA level? I thought we kept them low speicficity. <TabAtkins> TabAtkins: We don't use IDs, no, but we do freey use attribute selectors, which can easily clash if it wasn't for the origin difference. <jensimmons> slides (again): https://noti.st/jensimmons/QOEOYT/three-topics#srFUYHC <fantasai> yes, we really rely on origin for UA level <TabAtkins> bkardell_: I do believe we'r emissing something here. I don't know if this addresses or exacerbates the problem. At some level it addresses their complaints, but by doubling down on what they're complaining about. <TabAtkins> jensimmons: Agree. <astearns> ack TabAtkins <fantasai> Scribnick: fantasai <fantasai> TabAtkins: I totally like this idea <fantasai> TabAtkins: had similar thoughts, but never did the use case exploration <fantasai> TabAtkins: Definitely agree we should pursue this, and the use cases made me absolutely sure we should pursue this <TabAtkins> ScribeNick: TabAtkins <astearns> ack heycam <TabAtkins> heycam: I think it's very important fo rus to try to address these problems. <TabAtkins> heycam: A little of a shame that it's taken several years after people started complaining, biut glad we're addressing it now. <TabAtkins> heycam: What I like about this is that it's so simple, and slots into the existing model. <astearns> q+ <TabAtkins> heycam: Not super sure about whether it really will capture all of these use-cases, or might need more discussion with real proponents of CSS-in-JS to see how well it works. <emilio> q+ <TabAtkins> heycam: I'd want to be more sure this is the right way to go for solving that. <TabAtkins> heycam: But see th eother use-cases anyway. <TabAtkins> astearns: I agree this is very nice it slots into our model, but a little concerned it's not the general author model. <TabAtkins> astearns: You had to learn about the concept anyway. <TabAtkins> astearns: So as Tess said, "origin" is an overloaded term, maybe we can come up with something else? <TabAtkins> [various suggestions] <astearns> ack astearns <astearns> ack fantasai <dbaron> "style sources"? <TabAtkins> fantasai: Some discussion about this addressing all the cases; I don't think it does, biut it addresses quite a few, and addresses the organizational layer of many projects. <TabAtkins> fantasai: So I think it fits well with how people put together their sites. <TabAtkins> fantasai: There's other places in the cascade where specificity gets unwieldy. I don't think WC is great here; it adds a *ton* of encapsulation. <TabAtkins> fantasai: Another proposal was scoped styles in CSS, which might also help. <jensimmons> q? <bkardell_> if we had this, would we need leaverou 's zero specificity pseudo still too? <TabAtkins> fantasai: They let you say "within this sidebar, these styles win over other things". <fantasai> s/things/things, regardless of specificity/ <TabAtkins> TabAtkins: I think declarative shadow dom addresses a lot of the problems with WC; I'd like to explore that more seriously first before we add something that is 98% identical to WC's model, but with 2% weird differences that make impl complicated. <astearns> ack emilio <fantasai> bkardell, you wouldn't need it for an entirely swath of styles, but would likely still be useful locally, for specific selectors or parts of selectors <AmeliaBR> q+ <TabAtkins> emilio: I agree this is neat. Is there a concrete proposal? Is that at the stylesheet level, or allow 3rd party styles to choose their origin, etc? <TabAtkins> emilio: Depending on details it might solve some use-cases but not vice-versa. <TabAtkins> emilio: Also need to figure out how this interacts with shadow dom. <leaverou> bkardell_: I believe so. This is great, but sometimes you need more fine-grained control. E.g. when theming *within* the same origin <TabAtkins> emilio: Shadow DOM introduces a stack of origins; introducing this naively makes it a matrix, which is harder. <jensimmons> q? <astearns> ack AmeliaBR <TabAtkins> AmeliaBR: echo Emilio's concern that we need details to see exactly how this sort of thing works. <TabAtkins> AmeliaBR: Coming up with specific proposals and cross-reffing them with specific use-cases would be helpful. <TabAtkins> AmeliaBR: So we should work from the use-cases to what features we actually need. <astearns> ack fantasai <TabAtkins> fantasai: For "how do you control", an easy way to think of it would be the person importing the sytlesheet bea ble to say what level it imports at. <TabAtkins> fantasai: And within each level, maybe you can have sub-ordering. <florian> q+ <TabAtkins> fantasai: And with a nesting block that lets you specify the layer within a single file. <TabAtkins> fantasai: Using numbers to establish the ordering might work if there's only one controller; multiple controllers gives you the z-index wars. <faceless2> q+ <TabAtkins> emilio: My concern with nubmers or letting stylesheets choose their own levels becomes a z-index fight. <astearns> ack florian <TabAtkins> florian: One thing I'm a little concerned is how we figure out the syntax to have a migration path toward this from legacy CSS.s <TabAtkins> florian: In particular, a syntax ignorable by old browsers is bad because the cascade will be all mushed up; but making it hide rules from old browsers means they'll just miss a lot of code. <TabAtkins> florian: Writing everything twice is bad, but not having an upgrade path is bad. <astearns> ack faceless2 <astearns> ack faceless <TabAtkins> faceless2: What if you had two toolkits, importing the same stylesheet at different levels? <astearns> zakim, close queue <Zakim> ok, astearns, the speaker queue is closed <fantasai> TabAtkins: Same as importing a style sheet twice, it's just present in both places <fantasai> TabAtkins: cascades together; effectively later one wins <TabAtkins> jensimmons: So got a lot of good issues and concerns. <bkardell_> +1 to talk about "this set of problems" for sure <TabAtkins> jensimmons: I do think it's worth looking deeply at the solutions we might need for the complete set of problems, not just what this particular solution could address, so we can tell if this is a good idea in the totality of a complete solution. <TabAtkins> jensimmons: I've even convinced myself that if we ship this today by itself, it could get abused pretty badly. <TabAtkins> jensimmons: (similar to people abusing Flexbox to do grids) <TabAtkins> jensimmons: Putting this on Twitter, I got a lot of trepidation from folks. Powerful tool, could be bad. <TabAtkins> jensimmons: But I got that people who really knew CSS the most thought this was a terrific idea. <TabAtkins> jensimmons: I think it does require some teaching, but it's not that complicated. <TabAtkins> jensimmons: So I'm hearing a tentative "yeah, this is good", but I think there is a bigger metaproject to modernize the cascade. <TabAtkins> jensimmons: Also, Miri has been very active in Sass to push CSS to be a featureful language; did crazy things with Sass variables back in the day. <TabAtkins> jensimmons: So I'd like to invite her as an IE. <TabAtkins> [intentionally not minuting] <TabAtkins> fantasai: Where to put it? <TabAtkins> TabAtkins: Suggest putting it in WICG until it gels, then merge it into Cascade 5. <fantasai> i/fantasai/astearns: So sounds like interest in the room, try to move proposal forward/ <TabAtkins> jensimmons: And I want to get some highly-skilled authors involved in the convo too, so hopefully WICG works there. |
This comment has been minimized.
This comment has been minimized.
|
came here via one of Jen's Tweet. https://twitter.com/jensimmons/status/1219351448028356609
well, actually CSS doesn't bother. You can have multiple elements with the same ID and they'd be styled according to the current rules. Maybe I got lost in translation reading this proposal (and what happend around Jen's tweet) and I'm going to state the obvious; but here are my 2ct. FWIW both Cascade and Specificity are and always have been perfectly fine the way they are: the closer to the element (origin/location/cascase) considering the selector specificity. Done. However, the culprits IMHO happen to be "modern" design patterns and philosophies like BEM or Atomic Design & such that are causing the issues ppl. apparently have with "specificity": you either have a rather flat hierachiy where everything has virtually the same specificity (i.e. BEM) (and origin/order matters) or the HTML is poluted with a gazillion cryptic utility classes and what-not that might end up raising the specificity over the roof. And then there are some Framework / Library creators that don't get it either and butcher our beautiful Cascade adding There's only one addition to the Level in the Origin line of things I'd imagine to be helpful in some situations and to some people. It'd be considerably 1. logical and 2. following the current rules of the Cascade but applied a different "weight" to stylesheets served from 3rd party domains (CDN et al) and one's own (sub-)domain. With such a distinction equal selectors and equally specific selectors in an author style (even if Here's how things could work bold = "new" origin level (out of my head from lower to higher priority)
Since this additional level of origin would change the current browser behaviour, authors should "opt-in" to enable the new origin level by adding a René |
This comment has been minimized.
This comment has been minimized.
|
I am very excited by this proposal, and have definitely wished for this exact thing. Even if authors can't define n origins, just two would go a long way: One for "base" styles, and another for "module" styles. I think in most modern development, there are fundamental differences between these two types of styling. Ideally, I would typically want base styles to apply to the whole page, even piercing into Shadow DOM; but they would be of a lower priority origin, so module styles would always override them. I'd even be interested in a way to do something like |
This comment has been minimized.
This comment has been minimized.
I think this might be useful to some, but it only addresses one specific problem that's a subset of this problem as a whole. Not everyone pulls in (say) Bootstrap from a CDN and then sticks some overrides on it. How would this help me override my own base styles? For me, I need more control over my styles and how they are applied. |
This comment has been minimized.
This comment has been minimized.
|
Having N author-defined origins is realistically no more difficult than having two (in other words, the spec text and probably implementation for both would be nearly identical, just with one being locked into 2), so that's nice at least. |
This comment has been minimized.
This comment has been minimized.
by CDN I simply mean "not the same hostname". I often set up one or more subdomains on the very same server pointing to the same files to overcome the connection limits (esp. for HTTP/1.1). So There you have you own "CDN" to stick some overrides on it :) |
This relates to the Cascade Specification, along with a number of "specificity" concerns and proposals (such as #2272 & #3890 & the
:where()selector).Much of my work with design systems has revolved around helping companies define layers of abstraction: building tokens, then defaults, then patterns, components etc. That's a common approach, whether we call it OOCSS or Atomic Design or ITCSS or something else. In order to do that, we often have to be very careful with matching specificity to layer – so components override patterns, and so on – and third-party tools can easily break a delicate balance.
It strikes me that cascading origins &
!importantare designed to solve that same problem on a larger scale (UA, user, author), and then reverse-order for!importantstyles. It's a pretty clever solution, but!importantis a blunt instrument for handling layers inside the author origin.I doubt most developers think about cascading origins, or the role importance plays in it - and at this point they don't really need to for practical reasons. I don't have a full solution here, but a rough sense that providing control of custom cascade origins (within/around the author origin) might help:
!importantare designed, and how they work under the hoodA few notes on finding a syntax/approach that would work:
!importantapproach (or!defaultproposal which I like) is useful in other situations, but too narrowly applied for this particular use-case:where()approach is both narrowly-applied and removes all specificity, which could still be a useful tool within origins@importor an at-rule of some kind (e.g.@origin?). That feels like the more proper scope for this problem.I realize this gets difficult to define quickly:
@originblocks internally, and I want to load it in a specific layer within my overall code. Are there layering contexts, similar toz-index? Nesting origins would get complicated quickly.I hope that all makes some sense. I'd be curious for additional thoughts on this, and happy to clarify anywhere I can.