This content originally appeared on Kilian Valkhof and was authored by Kilian Valkhof
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.
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);
}
}
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 :is(:root, ::backdrop, ::selection)
. Sorry about that.
This content originally appeared on Kilian Valkhof and was authored by Kilian Valkhof
Kilian Valkhof | Sciencx (2023-05-01T15:27:06+00:00) :root isn’t global. Retrieved from https://www.scien.cx/2023/05/01/root-isnt-global/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.