DEV Community

Kilian Valkhof
Kilian Valkhof

Posted on • Originally published at kilianvalkhof.com

9 1

:root isn't global

Most developers prefer to keep all their CSS custom properties in one place, and a pattern that has emerged in recent years is to put those on :root, a pseudo-element that targets the topmost element in your document (so that's always <html> on web pages). But just because they're in one place and in the topmost element, it doesn't mean they're global.

I first encountered this issue with ::backdrop: Backdrop doesn't inherit from anywhere but after a recent rendering engine update to Polypane I noticed that all my custom selection colors (also powered by CSS custom properties) suddenly stopped working.

Turns out, ::selection is also not supposed to inherit styles, and Chromium 111+ is running an experiment to see what effect changing that has. Polypane runs with experimental features turned on, and so my selection styles became broken.

This is going to catch a lot of people off-guard because I, like many others, expect CSS Custom properties defined on :root to just be available everywhere. I guess I would also expect ::selection and ::backdrop to inherit from their "parent" element to allow more dynamic styling, but the spec writes apparently don't want this.

So if :root isn't global, what is?

Well, the jury's still out.

Discussions are happening in this GitHub issue: Custom properties on :root with a few options being discussed:

  • Use @property with an initial value (not cross-browser supported yet, only uses the initial value).
  • Make :root special.
  • Create a new :document pseudo-element that does propagate custom properties.
  • Create an new at-rule called @global, @root or @document that you could define custom properties in.
  • Make ::selection etc inherit from their originating element (e.g. "their parent").

That last item would solve both the problems people run into (it not inheriting, and it potentially inheriting directly from :root so you can't overwrite custom properties in the cascade). I hope spec writers choose to do this regardless.

Specifically, I want/expect this to work:

p {
    --selection-bg: #0f0;
    &::selection {
        background: var(--selection-bg);
    }
}
Enter fullscreen mode Exit fullscreen mode

When it comes to "a place to store global variables" I have no strong opinion, though I think it's interesting to keep in mind that in JavaScript there is now window, global and globalThis because the naming across contexts didn't work.

In that light, :document or @document seem potentially problematic. For that reason, I like @global or :global (I haven't actually seen global as a pseudo-element suggested yet, but it seems to be closest to how people expect things to work now).

In the mean time, you can use the suggestion I made in my ::backdrop post and replace :root with :root ::backdrop ::selection. Sorry about that.

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (1)

Collapse
 
fruntend profile image
fruntend

Сongratulations 🥳! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up 👍

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay