Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I add a classname to a CSS variable?

Is it possible to add a classname to a CSS variable or is there some other way to set it up so that I don't have to manipulate each individual variable directly via javascript? I'd like to keep all my styles in CSS and simply turn on relevant classes with JS. For example, If something like this was possible in CSS:

:root.white{ --bgcol:#FFF; --col:#000; }
:root.black{ --bgcol:#000; --col:#FFF; }

Then I could then just toggle the .black or .white class from javascript to trigger all vars to change. What's the best approach for this type of setup?

like image 720
cronoklee Avatar asked Mar 31 '19 09:03

cronoklee


People also ask

How do you add a class to a CSS tag?

To select elements with a specific class, write a period (.) character, followed by the name of the class. You can also specify that only specific HTML elements should be affected by a class. To do this, start with the element name, then write the period (.)

Can you add a class through CSS?

With CSS Hero you can easily add classes to elements without needing to touch any of your theme files or adding weird code to your contents. Plus you can control all your classes right from the CSS Hero interface.

Can you define a class in CSS?

What is a CSS class? A CSS class is an attribute used to define a group of HTML elements in order to apply unique styling and formatting to those elements with CSS.

Can you change CSS variables?

CSS variables can be made conditional with @media and other conditional rules. As with other properties, you can change the value of a CSS variable within a @media block or other conditional rules. For example, the following code changes the value of the variable, gutter on larger devices.


2 Answers

That's frankly the best (as in most idiomatic) approach — the use of class names, if not altogether separate stylesheets (as has been tradition for many, many years), to theme entire layouts via custom properties. It's the most "fundamentally CSS" approach with JavaScript merely being the glue that makes the theme switching work. You really can't do much better than that.

For those unaware what :root means and wondering where exactly the class names are being applied, it's the html element (the parent of body). So there is nothing special going on here — you're simply switching class names on the html element. It just happens that global custom properties are conventionally defined for the document root element since it's at the top level of the inheritance chain.

If you have any theme-agnostic custom properties, as well as style properties (i.e. not custom properties) that apply to the root element, keep them in their own unqualified :root rule, separate from your themed custom properties, so they won't be affected by theme switching. Here's an example:

const root = document.documentElement;

// Default theme - should assign declaratively in markup, not JS
// For a classless default theme, move its custom properties to unqualified :root
// Again, keep it separate from the other :root rule that contains non-theme props
// Remember, the cascade is your friend, not the enemy
root.classList.add('white');

document.querySelector('button').addEventListener('click', function() {
  root.classList.toggle('white');
  root.classList.toggle('black');
});
:root {
  --spacing: 1rem;
  color: var(--col);
  background-color: var(--bgcol);
}

:root.white {
  --bgcol: #FFF;
  --col: #000;
}

:root.black {
  --bgcol: #000;
  --col: #FFF;
}

p {
  margin: var(--spacing);
  border: thin dashed;
  padding: var(--spacing);
}
<button>Switch themes</button>
<p>Hello world!
like image 83
BoltClock Avatar answered Oct 18 '22 20:10

BoltClock


Using :root selector is identical to using html, except its specifity is higher, thus there is no issues in using this approach.

For example:

:root {
  --bg: red;
}
:root.blue {
  --bg: blue;
}
// ...
div {
  background: var(--bg);
}

Later, you should just change html's class and variables will change.

You can see an example in this fiddle.

like image 3
Styx Avatar answered Oct 18 '22 19:10

Styx