Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS variables root pseudo class scope and changing values through javascript

I have a question regarding how it's possible to access CSS variables that are not inline/exist on the same page. I.e. the CSS variables are defined in a custom CSS file.

I have a page that has an image with 3 inputs. One for controlling a background color, blur, and padding. As the sliders/colors is picked, the image and background color are adjusted accordingly. I have already written the javascript and it works but I am unsure on the exact reason why. I am trying to read through the documentation on mozilla developer documentation but my question was not answered: https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables

My question is as follows:

  • My CSS variables are defined at the root level using the :root pseudo class in my custom CSS file
  • I am accessing and modifying the variables using the document.documentElement.style.setProperty function in javascript

I understand that the documentElement by default returns the HTML element and you can find all children elements using this. And CSS variables are modified using the .style.setProperty function. So how is it that I can simply change the CSS variables I defined by selecting the global HTML element?

Is it because the :root pseudo class makes these variables available to be modified at the HTML element level? I am trying to wrap my head around how these CSS variables can be accessed and modified at a more concrete level. If the answer is as simple as css variables defined at the root pseudo class levels are able to be modified by accessing the HTML element, that would confirm my suspicions.Otherwise if you can dig into a little more detail, that would be helpful.

Link to Plunker: http://plnkr.co/edit/FdlCW7Ym5m8odaK05u4g?p=preview

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Scoped CSS Variables and JS</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <h2>Update CSS Variables with <span class='hl'>JS</span></h2>

  <div class="controls">
    <label for="spacing">Spacing:</label>
    <input id="spacing" type="range" name="spacing" min="10" max="200" value="10" data-sizing="px">

    <label for="blur">Blur:</label>
    <input id="blur" type="range" name="blur" min="0" max="25" value="10" data-sizing="px">

    <label for="base">Base Color</label>
    <input id="base" type="color" name="base" value="#ffc600">
  </div>

  <img src="https://source.unsplash.com/7bwQXzbF6KE/800x500">

  <script>

    const inputs = document.querySelectorAll('.controls input');

    function handleUpdate() {

      const val = this.dataset.sizing || '';
      document.documentElement.style.setProperty(`--${this.name}`,this.value + val);
    }

    inputs.forEach(currentItem => {
      currentItem.addEventListener('change', handleUpdate);
      currentItem.addEventListener('mousemove', handleUpdate)
    });
  </script>

CSS:

    /* Styles go here */


    :root {
      --base: #ffc600;
      --spacing: 10px;
      --blur: 10px;
    }
    /*
      misc styles, nothing to do with CSS variables
    */

    img {
      padding: var(--spacing);
      background: var(--base);
      filter: blur(var(--blur));

    }

    .hl {
      color: var(--base);
    }

    body {
      text-align: center;
      background: #193549;
      color: white;
      font-family: 'helvetica neue', sans-serif;
      font-weight: 100;
      font-size: 50px;
    }

    .controls {
      margin-bottom: 50px;
    }

    input {
      width:100px;
}
like image 535
Help123 Avatar asked Sep 15 '25 11:09

Help123


1 Answers

Your hypothesis is correct: CSS custom properties specified with the :root-selector, are assigned to the html-element. And because of the inheritance, they are available for all the children of <html>.

From https://developer.mozilla.org/en-US/docs/Web/CSS/:root

The :root CSS pseudo-class matches the root element of a tree representing the document. In HTML, :root represents the <html> element and is identical to the selector html, except that its specificity is higher.

From https://developer.mozilla.org/en-US/docs/Web/API/Document/documentElement

Document.documentElement returns the Element that is the root element of the document (for example, the <html> element for HTML documents).

like image 54
haugsand Avatar answered Sep 18 '25 05:09

haugsand