Background color overridden even after reversing the order of CSS layers

586 views Asked by At

I want to use the new CSS cascade layers feature supported by latest versions of Chrome, Firefox, Safari, and Edge (see the support table).

I'm importing a stylesheet from highlight.js. It has a class named hljs that applies a background color to <code> elements. I want to override that color with CSS @layer rules:

@import url("styles/base16/google-light.min.css") layer(highlightjs);

@layer highlightjs, main;

@layer main {
  .hljs {
    background: red;
  }
}

This works and overrides the background color but when I reverse the order of layers, still my background color applies. Why is that?

@layer main, highlightjs;
3

There are 3 answers

0
Alohci On BEST ANSWER

The issue is that your @import provides the first naming of the "highlightjs" layer. It comes before the list of layers, so it makes it the lowest precedence layer. The list of two layers then has no effect.

@import url("data:text/css, code { background:blue; color:yellow }") layer(highlightjs);

@layer main, highlightjs;

@layer main {
  .hljs {
    background: red;
  }
}
<code class="hljs">
  Hello World
</code>

For this reason, an @layer list is allowed to precede an @import. In the snippet below, the order of layers is main, then highlightjs, and the colouring is adjusted appropriately.

@layer main, highlightjs;

@import url("data:text/css, code { background:blue; color:yellow }") layer(highlightjs);

@layer main {
  .hljs {
    background: red;
  }
}
<code class="hljs">
  Hello World
</code>

0
DevThiman On

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.

In CSS, there is such a thing as a layer. It must be said that it is familiar to everyone who has worked with any graphic editor, but, perhaps, it is still incomprehensible to others.

When creating a block in CSS, we always clearly set its parameters, as well as position it in a certain place on the screen. Thus, any block has two coordinates X and Y, which determine the position of the block on the screen plane. But in CSS there is also a third, spatial coordinate Z, which determines the number of the layer on which the block is located.

@layer reset, defaults, framework, components, utilities;

That will establish the layer order:

  1. un-layered styles (most powerful)
  2. utilities
  3. components
  4. framework
  5. defaults
  6. reset (least powerful)

but remember: what matters is the order each name first appears. So this will have the same result:

@layer reset, defaults, framework;
@layer components, defaults, framework, reset, utilities;

layers are stacked based on the order in which the layers first appear in your code

check this css-tricks.com/css-cascade-layers and https://www.successbeta.com/2022/10/learn-about-layers-in-css-step-by-step.html for further clarifications.

0
Panagiotis Sakellariou On

I look at anything that overrides specificity as a really, really bad idea. And the fact they they are pushing badly thought out features like @layer simply to accommodate people that can't get their heads around specificity is mind boggling. Do yourself a favor and don't use @layer, if you do you will soon find yourself in CSS hell where you have no idea what happens when and why. Stick to 2 simple rules :

  1. use scoping for overriding
  2. use !important ONLY to override inline style that you have no control over.