question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow additional selectors on :root

See original GitHub issue

This library currently requires the vars you define to be attached to a :root rule and exactly a :root rule. Previous issues have discussed allowing vars on other selectors and I understand why that’s a challenge. I’m not sure I see why the rule has to be exactly :root though.

On our project, we’re making use of a shadow DOM to render our app in browsers that support it and to do that our rule is :root, :host. When using a shadow DOM, we don’t need to use your ponyfill so it’s fine if this doesn’t work for :host. But the problem is that the library won’t even process these variables because of the extra :host selector.

This line of code seems to be the cause: https://github.com/jhildenbiddle/css-vars-ponyfill/blob/e22453fba24bdf0d593b0dbca17b05a947c7ed32/src/parse-vars.js#L40

Can that check be changed so that it only requires that one of the selectors be :root and can ignore additional selectors?

I think changing that to the following would do it unless there’s some reason I’m not aware of that would make the library not work with the extra selector there.

if (rule.selectors.indexOf(":root") === -1)

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
jhildenbiddlecommented, Aug 9, 2019

@simonwinklerzh

This could be done, but there would be a significant performance hit for doing so as the ponyfill would have to generate scoped CSS for each :root selector variation.

Consider the following:

:root {
  --main-color: red;
}

:root.theme-a {
  --main-color: green;
}

:root.theme-b {
  --main-color: blue;
}

p {
  color: var(--main-color);
}

The ponyfill would have to generate the following CSS:

p {
  color: red;
}

:root.theme-a p {
  color: green;
}

:root.theme-b p {
  color: blue;
}

Each CSS rule is duplicated for each :root variation. The obvious performance hit comes from asking the ponyfill to generate more CSS but–perhaps surprisingly–this isn’t that big of an issue. The main concern is that the time it takes for the browser to parse large blocks of CSS and render the results is the most significant performance bottleneck, and the above approach would produce significantly more CSS for for the browser to parse.

The recommended way to swap themes is by using options.variables to swap values on demand.

// Setup themes in JS
const themes = {
  a: {
    color: "green"
  },
  b: {
    color: "blue"
  }
};

// Initial run (default theme)
cssVars();

// Switch to theme "A"
cssVars({
  variables: themes.a
});

// Switch to theme "B"
cssVars({
  variables: themes.b
});

There are some advantages to keeping your theme variables in JS as well, such as the ability to quickly access these values from JS or perform calculations on them (such as auto-generating shades/hues).

Hope this helps!

1reaction
simonwinklerzhcommented, Aug 9, 2019

Hi @jhildenbiddle

I post here, because the title of this issue matches my question perfectly.

We want to make use of css custom properties, in order to implement different color-themes on some websites that share the same code base.

Our approach using css variables would be this:

:root {
	--main-color: red;
}

:root.theme-a {
	--main-color: green;
}

:root.theme-b {
	--main-color: blue;
}
  1. This currently doesn’t work with the ponyfill, right?
  2. Would you consider implementing this?

Kind regards, Simon

Read more comments on GitHub >

github_iconTop Results From Across the Web

root - CSS: Cascading Style Sheets - MDN Web Docs - Mozilla
In HTML, :root represents the <html> element and is identical to the selector html , except that its specificity is higher.
Read more >
How to Use the CSS :root Pseudo-Class Selector - DigitalOcean
The CSS :root pseudo-class selector is used to select the highest-level parent of a given specification. In the HTML specification, the :root ......
Read more >
Get root selector, and use it in as part of another selector
I want the bottom selector in the code below to re-use the root selector, so the selector behaves like the working one above...
Read more >
root - CSS-Tricks
The :root selector allows you to target the highest-level “parent” element in the DOM, or document tree. It is defined in the CSS...
Read more >
CSS ROOT pseudo-class selector - YouTube
CSS ROOT pseudo-class selector HTML Playlist: https://www.youtube.com/playlist?list... … Show more. Show more ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found