{"id":363766,"date":"2022-02-21T07:40:35","date_gmt":"2022-02-21T15:40:35","guid":{"rendered":"https:\/\/css-tricks.com\/?p=363766"},"modified":"2022-10-19T12:44:27","modified_gmt":"2022-10-19T19:44:27","slug":"css-cascade-layers","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/css-cascade-layers\/","title":{"rendered":"A Complete Guide to CSS Cascade Layers"},"content":{"rendered":"\n
This is your complete guide to CSS cascade layers, a CSS feature that allows us to define explicit contained layers of specificity, so that we have full control over which styles take priority in a project without relying on specificity hacks or CSS Cascade Layers are intended to solve tricky problems in CSS. Let\u2019s take a look at the main problem<\/strong> and how cascade layers aim to solve it.<\/p>\n\n\n Many of us have been in situations where we want to override styles from elsewhere in our code (or a third-party tool), due to conflicting selectors. And over the years, authors have developed a number of \u201cmethodologies\u201d and \u201cbest practices\u201d to avoid these situations \u2014 such as \u201conly using a single class\u201d for all selectors. These rules are usually more about avoiding the cascade, rather than putting it to use<\/a>.<\/p>\n\n\n\n Managing cascade conflicts and selector specificity has often been considered one of the harder \u2014 or at least more confusing \u2014 aspects of CSS. That may be partly because few other languages rely on a cascade as their central feature, but it\u2019s also true that the original cascade relies heavily on heuristics<\/em> (an educated-guess or assumption built into the code) rather than providing direct and explicit control to web authors.<\/p>\n\n\n\n Selector specificity<\/dfn>, for example \u2014 our primary interaction with the cascade \u2014 is based on the assumption that more narrowly targeted styles (like IDs that are only used once) are likely more important than more generic and reusable styles (like classes and attributes). That is to say: how specific<\/em> the selector is. That\u2019s a good guess, but it\u2019s not a totally reliable rule, and that causes some issues:<\/p>\n\n\n\n Cascade layers<\/dfn> give CSS authors more direct control over the cascade so we can build more intentionally cascading systems without relying as much on heuristic assumptions that are tied to selection.<\/p>\n\n\n\n Using the These layers are ordered and grouped so that they don\u2019t escalate in the same way that specificity and importance can. Cascade layers aren\u2019t cumulative like selectors. Adding more layers<\/em> doesn\u2019t make something more important<\/em>. They\u2019re also not binary like importance \u2014 suddenly jumping to the top of a stack \u2014 or numbered like The cascade is a series of steps (an algorithm) for resolving conflicts between styles.<\/p>\n\n\n\n With the addition of cascade layers, those steps are:<\/p>\n\n\n\n\n\n\n\n Selector specificity<\/em> is only one small part of the cascade, but it\u2019s also the step we interact with most, and is often used to refer more generally to overall cascade priority<\/em>. People might say that the However, CSS Cascade Layers also make it more essential that we fully understand the role of As web authors, we often think of Importance isn\u2019t there to simply increase power \u2014 but to balance the power between various competing concerns.<\/p>\n\n\n It all starts with origins<\/dfn>, where a style comes from in the web ecosystem. There are three basic origins in CSS:<\/p>\n\n\n\n Browsers provide readable defaults for all the elements, and then users set their preferences, and then we (authors) provide the intended design for our web pages. So, by default, browsers have the lowest priority, user preferences override the browser defaults, and we\u2019re able to override everyone.<\/p>\n\n\n\n But the creators of CSS were very clear that we should not actually have the final word:<\/p>\n\n\n\n If conflicts arise the user should have the last word<\/strong>, but one should also allow the author to attach style hints.<\/p>\u2014 H\u00e5kon Lie (emphasis added)<\/cite><\/blockquote>\n\n\n\n So importance<\/em> provides a way for the browser and users to re-claim their priority when it matters most. When the For us, adding While most of the popular browsers have made it difficult to upload actual user stylesheets, they all offer user preferences: a graphic interface for establishing specific user styles. In that interface, there is always a checkbox available for users to choose if a site is allowed to override their preferences or not. This is the same as setting !important<\/code>. This guide is intended to help you fully understand what cascade layers are for, how and why you might choose to use them, the current levels of support, and the syntax of how you use them.<\/p>\n\n\n\n\n\n\n
Table of Contents<\/h2>
\n
Quick example<\/h3>\n\n\n
\/* establish a layer order up-front, from lowest to highest priority *\/\n@layer reset, defaults, patterns, components, utilities, overrides;\n\n\/* import stylesheets into a layer (dot syntax represents nesting) *\/\n@import url('framework.css') layer(components.framework);\n\n\/* add styles to layers *\/\n@layer utilities {\n \/* high layer priority, despite low specificity *\/\n [data-color='brand'] { \n color: var(--brand, rebeccapurple);\n }\n}\n\n@layer defaults {\n \/* higher specificity, but lower layer priority *\/\n a:any-link { color: maroon; }\n}\n\n\/* un-layered styles have the highest priority *\/\na {\n color: mediumvioletred;\n}<\/code><\/pre>\n\n\n
Introduction: what are cascade layers?<\/h3>\n\n\n
Problem: Specificity conflicts escalate<\/h4>\n\n\n
!important<\/code> hand-grenade<\/a>.<\/li><\/ul>\n\n\n\n
.overly#powerful .framework.widget {\n color: maroon;\n}\n\n.my-single_class { \/* add some IDs to this ??? *\/\n color: rebeccapurple; \/* add !important ??? *\/\n}<\/code><\/pre>\n\n\n
Solution: cascade layers provide control<\/h4>\n\n\n
@layer<\/code> at-rule and layered
@import<\/code>s, we can establish our own layers of the cascade<\/em> \u2014 building from low-priority styles like resets and defaults, through themes, frameworks, and design systems, up to highest-priority styles, like components, utilities, and overrides. Specificity is still applied to conflicts within each layer<\/em>, but conflicts between layers are always resolved by using the higher-priority layer styles.<\/p>\n\n\n\n
@layer framework {\n .overly#powerful .framework.widget {\n color: maroon;\n }\n}\n\n@layer site {\n .my-single_class {\n color: rebeccapurple;\n }\n}<\/code><\/pre>\n\n\n\n
z-index<\/code>, where we have to guess a big number (
z-index:<\/code>
9999999<\/code>?). In fact, by default, layered styles are less important<\/em> than un-layered styles.<\/p>\n\n\n\n
@layer defaults {\n a:any-link { color: maroon; }\n}\n\n\/* un-layered styles have the highest priority *\/\na {\n color: mediumvioletred;\n}<\/code><\/pre>\n\n\n
Where do layers fit in the cascade?<\/h3>\n\n\n
html { --button: teal; }\nbutton { background: rebeccapurple !important; }\n.warning { background: maroon; }<\/code><\/pre>\n<\/div>\n\n\n\n
<button class=\"warning\" style=\"background: var(--button);\">\n what color background?\n<\/button><\/code><\/pre>\n<\/div>\n<\/div>\n\n\n\n
!important<\/code> flag or the
style<\/code> attribute \u201cadds specificity\u201d \u2014 a quick way of expressing that the style becomes higher priority in the cascade. Since cascade layers have been added directly above specificity, it\u2019s reasonable to think about them in a similar way: one step more powerful than ID selectors.<\/p>\n\n\n\n
!important<\/code> in the cascade \u2014 not just as a tool for \u201cincreasing specificity\u201d but as a system for balancing concerns.<\/p>\n\n\n
!important<\/code> origins, context, and layers are reversed!<\/h3>\n\n\n
!important<\/code> as a way of increasing specificity, to override inline styles or highly specific selectors. That works OK in most cases (if you\u2019re OK with the escalation) but it leaves out the primary purpose of importance<\/em> as a feature in the overall cascade.<\/p>\n\n\n\n
Important origins<\/h4>\n\n\n
!important<\/code> flag is added to a style, three new layers are created \u2014 and the order is reversed!<\/p>\n\n\n\n
!important<\/code> browser styles (most powerful)<\/li>
!important<\/code> user preferences<\/li>
!important<\/code> author styles<\/li>
!important<\/code> doesn\u2019t change much \u2014 our important styles are pretty close to our normal styles \u2014 but for the browser and user it\u2019s a very powerful tool for regaining control. Browser default style sheets include a number of important styles that it would be impossible for us to override, such as:<\/p>\n\n\n\n
iframe:fullscreen {\n \/* iframes in full-screen mode don't show a border. *\/\n border: none !important;\n padding: unset !important;\n}<\/code><\/pre>\n\n\n\n
!important<\/code> in a user stylesheet:<\/p>\n\n\n\n