CSS - tutorial - 05 - variables

revision:


Content

CSS variables let us create our own custom values why care about CSS custom properties? the var() function naming variables/custom properties valid values for custom properties breaking up values using the :root pseudo-class inheritance of custom properties / using the cascade! custom property fallback values overriding and adding variables using variables in media queries change variables with JavaScript get and set CSS variables with Javascript some examples of CSS variables


CSS variables let us create our own custom values

top

CSS variables - also called custom properties - allow a value to be stored in one place, then to be referenced in multiple other places. They also make it possible to change CSS dynamically at runtime (which previously required a CSS preprocessor).

To use a CSS variable, it first need to be declared by writing it inside a CSS set, like is the case for any other CSS declaration. Custom properties or variables are entities defined by CSS authors that contain specific values to be reused throughout a document. They are set using custom property notation (e.g., --main-color: black;) and accessed using the var() function (e.g., color: var(--main-color);).

Example:

            .card {
                --spacing: 1.2rem;
                padding: var(--spacing);
                margin-bottom: var(--spacing);
            }
    

Explanation: in above example, --spacing is the custom property with 1.2rem as the value, and var(--spacing) is the variable in use. Declaring a custom property is done using a custom property name that begins with a double hyphen (--), and a property value that can be any valid CSS value. Like any other property, this is written inside a ruleset.

Perhaps the most valuable reason to use custom properties is not repeating yourself (DRY code).

examples

This paragraph should have a blue background and yellow text.

This paragraph should have a yellow background and blue text.

This paragraph should have a green background and yellow text.

Codes:

                    <style>
                        :root {--first-color: #16f;--second-color: #ff7;}
                        #firstParagraph {background-color: var(--first-color); color: var(--second-color);}
                        #secondParagraph {background-color: var(--second-color);color: var(--first-color);}
                        #container {--first-color: #290; }
                        #thirdParagraph {background-color: var(--first-color); color: var(--second-color);}
                    
                    </style>
                    <p class="spec" id="firstParagraph">This paragraph should have a blue background and yellow text.</p>
                    <p class="spec" id="secondParagraph">This paragraph should have a yellow background and blue text.</p>
                    <div id="container">
                        <p class="spec" id="thirdParagraph">This paragraph should have a green background and yellow text.</p>
                    </div>
                
                

why care about CSS custom properties?

top

1: they help DRY up your CSS. That is "Do not repeat yourself." Custom properties can make code easier to maintain, because you can update one value and have it reflected in multiple places. Careful though, overdoing abstraction can make have the opposite effect and make code less understandable.

2: they are particularly helpful for things like creating color themes on a website.

3: they unlock interesting possibilities in CSS. In no small part because they cascade.

4: the fact that they can be updated in JavaScript opens up even more interesting possibilities.

examples

Lorem Ipsum

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper diam at erat pulvinar, at pulvinar felis blandit.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper diam at erat pulvinar, at pulvinar felis blandit.

code:
                    <div class="containerA" style="margin-left:4vw;">
                        <h3>Lorem Ipsum</h3>
                        <p class="spec">Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
                        Etiam semper diam at erat pulvinar, at pulvinar felis blandit.</p>
                        <p class="spec">Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
                        Etiam semper diam at erat pulvinar, at pulvinar felis blandit.</p>
                        <p class="spec">
                            <button>Yes</button>
                            <button>No</button>
                        </p>
                    </div>
                    <style>
                        .containerA {--blue: #1e90ff;--white: #ffffff;}
                        h3 {border-bottom: 2px solid var(--blue);}
                        .containerA {color: var(--blue); background-color: var(--white); padding: 1.5vw;}
                        button {background-color: var(--white); color: var(--blue); border: 1px solid 
                            var(--blue); padding: 0.5vw;}
                    </style>
                
                

the var() function

top

The var() function is used to insert the value of a CSS variable. The syntax of the var() function is as follows: var(name, value), where the variable name must begin with two dashes (--) and it is case sensitive!

When you declare a CSS variable, you also give that variable a scope: a variable's scope determines where that variable will work, based on where you declare it. CSS variables can have either local or global scope. Global variables can be accessed/used through the entire document, while local variables can be used only inside the selector where it is declared. To create a variable with global scope, declare it inside the ":root" selector, which matches the document's root element. To create a variable with local scope, declare it inside the selector that is going to use it.

The place in the CSS hierarchy where you declare a CSS variable will determine its level of visibility throughout the lower levels of the hierarchy. A CSS variable used throughout the entire page is declared in the "::root pseudo-selector", or in the "html selector". This is because all the elements on the page are enclosed in one HTML element, so CSS variables declared in the HTML element or in its ::root selector will be visible for consumption from its children. Generally, a CSS variable is only visible to child elements of the parent element it is declared in.

examples

explanation: two global variables (--blue and --white) are declared. Then, the var() function is used to insert the value of the variables later in the style sheet.

Lorem Ipsum

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper diam at erat pulvinar, at pulvinar felis blandit.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper diam at erat pulvinar, at pulvinar felis blandit.

code:
                    <div class="container3">
                        <h3>Lorem Ipsum</h3>
                        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper diam 
                        at erat pulvinar, at pulvinar felis blandit.< /p>
                        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper diam 
                        at erat pulvinar, at pulvinar felis blandit.< /p>
                        <p>
                        <button>Yes</button>
                        <button>No< /button>
                        </p>
                    </div>
                    <style>
                        :root {--blue: #1e90ff; --white: #ffffff; --top-color: orange; --bottom-color: yellow;}
                        h3{margin-left:4vw; border-bottom: 2px solid var(--blue);}
                    .container3{margin-left:4vw; color: var(--blue); background-color:var(--white); padding: 1.5vw;}
                    button{background-color: var(--white); color: var(--blue); border:1px solid var(--blue);}
                    </style>
                

Advantages of using var() are:

1/ makes the code easier to read (more understandable),
2/ makes it much easier to change the color values

Inheritance: like with normal CSS, child elements inherit the CSS variable values of their parent elements (as long as the parent value is not overwritten in the child element).

Fallback values: every time you use var(), you must specify a CSS variable inside the parenthesis.

You also have the option to write a fallback value, a CSS value that is applied if your CSS variable doesn't work for some reason.
This could be due to a typo somewhere in your CSS, or the browser being unable to render the value you specify for your variable.
Fallback values are placed within the parenthesis of the var() call after the first argument, the CSS variable name. The two arguments are separated by a comma.

You can even add multiple fallback values for the same CSS property in case your first fallback doesn't work. In this case, fallback values are written in a list separated by commas, and are applied in that order.

examples

explanation: the snippet here below creates the --my-gradient variable and sets it to the value of both the --top-color and --bottom-color variables to create a gradient.

code:
                <div>
                    <div class="demo1"></div> 
                    <div class="d1"></div>
                    <div class="d2"></div>
                    <div class="d3"></div>
                </div>
                <style>
                    :root {--blue: #1e90ff; --white: #ffffff; --top-color: orange; --bottom-color: yellow; --my-gradient: 
                    linear-gradient(var(--top-color), var(--bottom-color));--my-gradient2: linear-gradient(var(--bottom-color), 
                    var(--top-color));}
                    .demo1, .d1, .d2, .d3{margin-left: 5vw; height: 5vw; width: 10vw; border: 1px solid black;}
                    .demo1{background-color: var(--top-color);}
                    .d1{background-color: var(--bottom-color);}
                    .d2{background-image: var(--my-gradient);}
                    .d3{background-image: var(--my-gradient2);}
                </style>
            

naming variables/custom properties

top

Custom properties must be within a selector and start with two dashes (--): e.g. element{--main-bg-color:brown;}.

The selector given to the ruleset defines the scope that the custom property can be used in. A common best practice is to define custom properties on the :root pseudo-class, so that it can be applied globally across the HTML document: e.g. :root{--main-bg-color:brown}

With respect to naming, it's best to stick with letters, numbers, and dashes while making sure the custom property is defined inside of a valid selector. Custom property names are moreover case sensitive: e.g. --my-color will be treated as a separate custom property to --My-color.

Examples:

Nope, not within a selector: --foo: 1;
No, 0 or 1 dash won't work: foo: 1; -foo: 1;
 Yep!: --foo: 1;
OK, but they're different properties: --FOO: 1; --Foo: 1;
Totally fine: --mainColor: red; --main-color: red;
Special characters are a no: --color@home: red; --black&blue: black;

You can set the value of a custom property with another custom property:

Examples:

--red: #a24e34;
--green: #01f3e6;
--yellow: #f0e765;
--error: var(--red);
--ok: var(--green);
--warning: var(--yellow)

P.S. the custom property value is used by specifying the custom property name inside the var() function, in place of a regular property value: e.g. element {background-color: var(--main-bg-color);}


valid values for custom properties

top

Custom properties are surprisingly tolerant when it comes to the values they accept. They can be hex values, color functions, units of all kinds, and even strings of text.

Examples:

--brand-color: #990000;
--transparent-black: rgba(0, 0, 0, 0.5);
--spacing: 0.66rem;
--max-reading-length: 70ch;
--brandAngle: 22deg;
--visibility: hidden;
--my-name: "Fred Aster";

breaking up values

top

You can use custom properties to break up multi-part values.

Splitting colors

Examples:

button {--h: 100; --s: 50%; --l: 50%; --a: 1; background: hsl(var(--h) var(--s) var(--l) / var(--a));  }
button:hover { /* Change the lightness on hover */--l: 75%;}
 button:focus { /* Change the saturation on focus */ --s: 75%;}
 button[disabled] {  /* Make look disabled */ --s: 0%; --a: 0.5; }

By breaking apart values like that, we can control parts of them in a way we never could before. Just look at how we did not need to declare all of the HSL arguments to style the hover, focus and disabled state of a button. We simply overrode specific HSL values when we needed to.

Shadows: box-shadow doesn't have a shorthand property for controlling the shadow's spread on its own. But we could break out the box-shadow spread value and control it as a custom property.

Examples:

    button {--spread: 5px; box-shadow: 0 0 20px var(--spread) black;}
    button:hover {--spread: 10px; }
    

Gradients: there is no such thing as a background-gradient-angle (or the like) shorthand for gradients. With custom properties, we can just change that part as if there was such a thing.

Examples:

    body {--angle: 180deg; background: linear-gradient(var(--angle),red, blue);}
    body.sideways {--angle: 90deg;}

Comma-separated values (like backgrounds): any property that supports multiple comma-separated values might be a good candidate for splitting values too, since there is no such thing as targeting just one value of a comma-separated list and changing it alone.

Examples:

 
    body {
        --bg1: url(./img/angles-top-left.svg);
        --bg2: url(./img/angles-top-right.svg);
        --bg3: url(./img/angles-bottom-right.svg);
        --bg4: url(./img/angles-bottom-left.svg);
        --bg5: url(./img/bonus-background.svg);
        background-image: var(--bg1), var(--bg2), var(--bg3), var(--bg4);
    }
    @media (min-width: 1500px) {
        body {background-image: var(--bg1), var(--bg2), var(--bg3), var(--bg4), var(--bg5);}
    }   
    

Grids: we can take the "grid-template-columns" property and abstract its values into custom properties to make a super flexible grid system.

Examples:

        .grid {display: grid; --edge: 10px; grid-template-columns: var(--edge) 1fr var(--edge);}
          @media (min-width: 1000px) {
            .grid {--edge: 15%;}
          }
    

Transforms: CSS will soon get individual transforms but we can get it sooner with custom properties. The idea is to apply all the transforms an element might get up front, then control them individually as needed.

Examples:

        button {transform: var(--scale, scale(1)) var(--translate, translate(0));}
        button:active {--translate: translate(0, 2px);}
        button:hover {--scale: scale(0.9);}
    

Concatenation of unit types: There are times when combining parts of values doesn't work quite how you might hope. For example, you can't make 24px by smashing 24 and px together. It can be done though, by multiplying the raw number by a number value with a unit.

Examples:

        body { --value: 24;--unit: px;
            /* Nope */ font-size: var(--value) + var(--unit);
            /* Yep */  font-size: calc(var(--value) * 1px);
            /* Yep */  --pixel_converter: 1px; font-size: calc(var(--value) * var(--pixel_converter));
        }
    

using the :root pseudo-class

top

By declaring a custom property on the :root pseudo-class and using it where needed throughout the document, a CSS author can reduce the need for repetition.

examples
1:
2: Text 5 - more text
code:
                    <style>
                        :root{--main-bg-color: blue;}
                        .een{color: white; background-color: var(--main-bg-color); margin: 1vw; width: 5vw; height: 5vw; display: inline-block;}
                        .twee{color: white; background-color: black; margin: 1vw; width: 15vw; height: 7vw; display: inline-block; }
                        .drie{color: white; background-color: var(--main-bg-color); margin: 1vw; width: 25vw;}
                        .vier{color: white; background-color: var(--main-bg-color); margin: 1vw; width: 10vw;}
                        .vijf{background-color: var(--main-bg-color);}
                    </style>
                    <div style="margin-left:4vw;">
                        <div class="een">1:</div>
                        <div class="twee">2: Text <span class="vijf">5 - more text</span></div>
                        <input class="drie"/>
                        <textarea class="vier">4: Lorem Ipsum</textarea>
                    </div>
                
                

inheritance of custom properties / using the cascade!

top

Custom properties do inherit. This means that if no value is set for a custom property on a given element, the value of its parent is used.

Example:

        <div class="one">
            <div class="two">
              <div class="three"></div>
              <div class="four"></div>
            </div>
        </div>
        <style>
            .two {--test: 10px;}
            .three {--test: 2em;}
        </style>
    

In this case, the results of var(--test) are: for the class="two" element: 10px; for the class="three" element: 2em; for the class="four" element: 10px (inherited from its parent); for the class="one" element: invalid value, which is the default value of any custom property


custom property fallback values

top

Using the var() function, you can define multiple fallback values when the given variable is not yet defined; this can be useful when working with Custom Elements and Shadow DOM.

The first argument to the function is the name of the custom property to be substituted. The second argument to the function, if provided, is a fallback value, which is used as the substitution value when the referenced custom property is invalid.

The function only accepts two parameters, assigning everything following the first comma as the second parameter. If that second parameter is invalid, such as if a comma-separated list is provided, the fallback will fail.

Example:

        .two {color: var(--my-var, red); /* Red if --my-var is not defined */}
        .three {background-color: var(--my-var, var(--my-background, pink)); /* pink if --my-var and -my-background are not defined */}
        .three { background-color: var(--my-var, --my-background, pink); /* Invalid: "--my-background, pink" */}
    

Including a custom property as a fallback, as seen in the second example above, is the correct way to provide more than one fallback. The technique has been seen to cause performance issues as it takes more time to parse through the variables.


overriding and adding variables

top

Overriding global variables with local variables: sometimes we want the variables to change only in a specific section of the page. Then, we can re-declare the variable inside the selector. The local variable will override the global variable for the selected elements.

Add a new local variable: if a variable is to be used on only one single place, a new local variable can be declared.


using variables in media queries

top

Variables in media queries: we first declare a new local variable named --fontsize for the respective class. We set its value to 25 pixels. Then we use it in other related classes. Then, we create a @media rule that says "When the browser's width is 450px or wider, change the --fontsize variable value of the class to 50px."


change variables with JavaScript

top

CSS variables have access to the DOM, which means that they can be changed with JavaScript.

examples

Lorem Ipsum

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper diam at erat pulvinar, at pulvinar felis blandit.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper diam at erat pulvinar, at pulvinar felis blandit.


code:
                    <div class="container1">
                        <h3>Lorem Ipsum</h3>
                        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper diam at erat pulvinar, at pulvinar felis blandit.</p>
                        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper diam at erat pulvinar, at pulvinar felis blandit.</p>
                        <p>
                            <button>Yes</button>
                            <button>No</button>
                        </p>
                    </div>
                    <br>
                    <button class="drie" type="button" onclick="myFunction_get()">Get CSS variable with JavaScript</button>
                    <button class="drie" type="button" onclick="myFunction_set()">Change CSS variable with JavaScript</button>
                    <style>
                        :root{--main-bg-color: blue;}
                        h3{margin-left:4vw; border-bottom: 2px solid var(--blue);}
                        .container1{margin-left:4vw; color: var(--blue); background-color:var(--white); padding: 1.5vw;}
                        button{background-color: var(--white); color: var(--blue); border:1px solid var(--blue);}
                    </style>
                    <script>
                        // Get the root element
                        var r = document.querySelector(':root');
                        //Create a function for getting a variable value
                        function myFunction_get() {
                        // Get the styles (properties and values) for the root
                        var rs = getComputedStyle(r);
                        // Alert the value of the --blue variable
                        alert("The value of --blue is: " + rs.getPropertyValue('--blue'));
                        }
                        // Create a function for setting a variable value
                        function myFunction_set() {
                        // Set the value of variable --blue to another value (in this case "lightblue")
                        r.style.setProperty('--blue', 'lightblue');
                        }
                    </script>
                
examples
code;
                    <div class="container2">
                        <div class="toggle-controls"><button class="toggle-controls_button" type="button">Click to choose blend & color</button></div>
                        <div class="controls">
                            <label for="multiply"> <input type="radio" id="multiply" name="blends" value="multiply"> Multiply</label>
                            <label for="overlay"> <input type="radio" id="overlay" name="blends" value="overlay"> Overlay</label> 
                            <label for="screen"> <input type="radio" id="screen" name="blends" value="screen"> Screen</label>
                            <label for="darken"> <input type="radio" id="darken" name="blends" value="darken"> Darken</label>
                            <label for="lighten"> <input type="radio" id="lighten" name="blends" value="lighten"> Lighten</label>
                            <label for="color-dodge"> <input type="radio" id="color-dodge" name="blends" value="color-dodge"> Color-Dodge</label>
                            <label for="color-burn"> <input type="radio" id="color-burn" name="blends" value="color-burn"> Color-Burn</label>
                            <label for="soft-light"> <input type="radio" id="soft-light" name="blends" value="soft-light"> Soft-Light</label>
                            <label for="hard-light"> <input type="radio" id="hard-light" name="blends" value="hard-light"> Hard-Light</label>
                            <label for="exclusion"> <input type="radio" id="exclusion" name="blends" value="exclusion"> Exclusion</label>
                            <label for="difference"> <input type="radio" id="difference" name="blends" value="difference"> Difference</label>
                            <label for="hue"> <input type="radio" id="hue" name="blends" value="hue"> Hue</label>
                            <label for="saturation"> <input type="radio" id="saturation" name="blends" value="saturation"> Saturation</label>
                            <label for="color"> <input type="radio" id="color" name="blends" value="color"> Color</label>
                            <label for="luminosity"> <input type="radio" id="luminosity" name="blends" value="luminosity"> Luminosity</label>
                            <label for="normal"> <input type="radio" id="normal" name="blends" value="normal"> Reset</label>
                            
                            <input type="color" class="color-picker" id="colorPicker" value="#ff0000">
                        </div>
                    </div>
                    <style>
                        .container2 {--blend-mode: multiply; --bg-color: #ff0000;--page-overflow: hidden;width: 100%; height: 100vh; 
                            overflow: var(--page-overflow); position: relative;  background-color: var(--bg-color); background-image: url(../pics/3.jpg);
                            background-repeat: no-repeat; background-position: top center; background-size: cover; background-blend-mode: 
                            var(--blend-mode);}
                        .toggle-controls {position: absolute; top: 0; left: 0; width: 15vw; padding: 1vw;background-color: rgba(0,0,0,.5); z-index: 2;}
                        .toggle-controls_button {--webkit-appearance: none; --moz-appearance: none; padding: 0.5vw; background-color: 
                            transparent; color: white; text-transform: uppercase; text-align: center; cursor: pointer; }
                        .controls {--left-pos: translate(-25vw);--controls-display: hidden;--transparency: 0;position: absolute; top: 12.5vw;
                            left: 0; transform: var(--left-pos); opacity: var(--transparency); max-width: 15vw; overflow: var(--page-overflow); 
                            padding: 1vw; background-color: white; transition: transform 1s, opacity 1s;}
                        .controls label {display: inline-block; width: 100%; margin-bottom: 0.5vw; font-weight: bold; color: #444;}
                        label:last-of-type { text-transform: uppercase; border-bottom: 3px dotted #444;
                        padding-bottom: 0.5vw;}
                    .color-picker { border: none; width: 10vw; height: 4vw; margin-top: 0.5vw; }
                    </style>
                    <script>
                    //function to open and close the sidebar with the controls (with the click to choos button)
                    const toggleControls = (elem, container, isOpen) => {
                        //if the sidebar is open these values applied to the appropriate CSS variables will close it
                        if(isOpen) {
                        elem.style.setProperty('--left-pos', 'translate(-25vw)');
                        elem.style.setProperty('--controls-display', 'hidden');
                        elem.style.setProperty('--transparency', '0');
                        container.style.setProperty('--page-overflow', 'hidden');
                        } 
                        //otherwise the sidebar is closed and this code opens it
                        else {
                        elem.style.setProperty('--controls-display', 'visible');
                        elem.style.setProperty('--transparency', '1');
                        elem.style.setProperty('--left-pos', 'translate(0)');
                        container.style.setProperty('--page-overflow', 'auto');
                        }
                    };
                    //function to select a blend mode
                    const pickBlendMode = (blendMode, elem) => {
                        let chosenMode;
                        //if the radio button is checked, grab its value and set it as value of the --blend-mode CSS variable
                        if (blendMode.checked) {
                        chosenMode = blendMode.value;
                        elem.style.setProperty('--blend-mode', chosenMode);
                        }
                    };
                    //function to select background color from color picker and use it to set the value of the --bg-color CSS variable 
                    const setBgColor = (picker, elem) => {
                        let chosenColor = picker.value;
                        elem.style.setProperty('--bg-color', chosenColor);
                    };
            
                    //vars
                    const colorPicker = document.querySelector("#colorPicker"),
                        toggleButton = document.querySelector('.toggle-controls_button'),
                        controlsSidebar = document.querySelector('.controls'),
                        docElement = document.querySelector('.container2'),
                        //turn blends from node list of radio buttons into array, so you can use array methods on this variable
                        blends = [].slice.call(document.getElementsByName("blends"));
            
                    //picking blend modes by looping over the radio buttons, attaching click events and calling the appropriate function defined above
                    blends.forEach((radioBtn) => {
                        radioBtn.addEventListener('click', () => pickBlendMode(radioBtn, docElement));
                    });
            
                    //picking a color: attach a listener for when users change color on the color picker
                    colorPicker.addEventListener('change', () => setBgColor(colorPicker, docElement));
            
                    //toggling controls panel on button click
                    toggleButton.addEventListener('click', () => {
                        
                        //retrieve the current value of the --left-pos variable
                        const cssStyles = getComputedStyle(controlsSidebar);
                        let cssVal = String(cssStyles.getPropertyValue('--left-pos')).trim();
                        
                        //hide or show the sidebar with the controls depending on the value of cssVal: -250px means the sidebar is closed 
                        //(the parameter isOpen in the toggleControls() function is false), therefore the button click 
                        //needs to open it, otherwise the button click will close it
                        if(cssVal === 'translate(-25vw)') {
                        toggleControls(controlsSidebar, docElement, false);
                        } else {
                            toggleControls(controlsSidebar, docElement, true);
                        }
                    });
                    </script>
                

get and set CSS variables with Javascript

top

To get the CSS variable's value in Javascript use "getComputedStyle()" to get the real-time CSS properties of the element.

CSS variables are applied on the root element of the document. This root element can be referred through "document.documentElement".
getComputedStyle() returns all CSS properties of the element. To get the value of a specific CSS property we need to use "getPropertyValue()" on it.

Example 6:

"var bg_color_val = getComputedStyle(document.documentElement).getPropertyValue('--bg-color');"

To set the CSS variable's value in Javascript: first access the styles of the root element with "document.documentElement.style". Then use "setProperty" to set the variable's value

Example 7:

"document.documentElement.style.setProperty('--bg-color', '#999999');"


some examples of CSS variables

top

Hover effects: change background colors

examples
Hover me
Hover me
Hover me
Hover me
Hover me
code:
                <div>
                    <div class="btn">Hover me</div>
                    <div class="btn red">Hover me</div>
                    <div class="btn teal">Hover me</div>
                    <div class="btn orange">Hover me</div>
                    <div class="btn green">Hover me</div>
                </div>
                <style>
                    .btn {border: 2px solid var(--color, black); background: white; font-size: 1vw; 
                        line-height: 2vw; border-radius: .2vw; margin-bottom: .5vw;text-align: center;}
                    .btn:hover {cursor: pointer; background: var(--color, black);color: white;}
                    .btn.red {--color: red;}
                    .btn.yellow {--color: yellow;}
                    .btn.green {--color: green;}
                    .btn.orange {--color: orange;}
                    .btn.teal {--color: teal;}
                </style>
            

Hover effects: move elements

examples
code:
                <ul>
                    <li>Hover on me!</li>
                    <li>Hover on me!</li>
                    <li>Hover on me!</li>
                </ul>
                <style>
                    ul {padding: 2vw; list-style: none; width: 20vw;}
                    li {font: normal 1.8vw sans-serif; padding: 2vw; transition: 0.4s; margin: 1vw; color: #444; 
                        cursor: pointer; background-color: yellow; }
                    ul {--tiny-shadow: 4px 4px 2px 0 rgba(0, 0, 0, 0.8);--animate-right: translateX(2vw);}
                    li {box-shadow: var(--tiny-shadow);}
                    li:hover {transform: var(--animate-right);}
            
                </style>
            

Managing CSS variables

examples

CSS variable managed through JS

some text
red green blue yellow purple pink
code:
                <div>
                    <div class="head_background">some text</div>
                    <div class="change_color">
                        <span class="change_color--red">red</span>
                        <span class="change_color--green">green</span>
                        <span class="change_color--blue">blue</span>
                        <span class="change_color--yellow">yellow</span>
                        <span class="change_color--purple">purple</span>
                        <span class="change_color--pink">pink</span>
                    </div>
                </div>
                <style>
                    .head_background {width:80vw; height:10vw;line-height: 2vw; text-transform: uppercase;
                        background-color: var(--basic-bg-grey); /*reusing CSS variable*/ border: 0.2vw 
                        solid #000000;}
                    .change_color--red { background: #FF0000; }
                    .change_color--green { background: #008000;}
                    .change_color--blue { background: #87CEEB;}
                    .change_color--yellow { background: #FFFF00;}
                    .change_color--purple { background: #9370DB; }
                    .change_color--pink { background: #FF69B4;}
                    .head_background, .change_color {text-align: center; margin: 2vw; }
                    .change_color span { margin: 0 1vw; display: inline-block; padding: 1vw 0; min-width: 7vw; 
                        border: 2px solid transparent; cursor: pointer;}
                </style>
                <script>
                    var div = document.querySelector('.head_background');
                    var color = document.querySelectorAll('.change_color span');
            
                    color.forEach((changeColor) => {
                        changeColor.addEventListener('click', () => {
                        const clickedStyle = getComputedStyle(changeColor);
                        const backgroundColor = clickedStyle.backgroundColor;
                        div.style.setProperty('--basic-bg-grey', backgroundColor);
                        })
                    });
                </script>
            

Creating theme styles with CSS variables

examples

CSS variables make creating site-wide theme styles easy.

Hello World

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean v

Can the world hear?

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean v
code:
                <div class="three">
                    <div class="theme">
                        <button value="dark">dark</button>
                        <button value="calm">calm</button>
                        <button value="light">light</button>
                    </div>
                    <article>
                        <h3>Hello World</h3>
                        Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ... Vivamus elementum 
                        semper nisi. Aenean v
                        
                        <h4>Can the world hear?</h4>
                        Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ... Vivamus elementum
                        semper nisi. Aenean v
                    </article>
                </div>
                <style>
                    :root{--bg: green; --bg-text: blue;}
                    .three{ width: 35vw; height: auto; background-color: var(--bg, white); 
                        color: var(--bg-text, black)}
                    .three article {padding: 0.5vw;}
                    .three article h3 {margin-top: 1vw;}
                </style>    
                <script>
                    const root = document.documentElement; 
                    const themeBtns = document.querySelectorAll('.theme > button')
                    themeBtns.forEach((btn) => {
                    btn.addEventListener('click', handleThemeUpdate)
                    })
                    function handleThemeUpdate(e) {
                        switch(e.target.value) {
                            case 'dark': 
                            root.style.setProperty('--bg', 'black')
                            root.style.setProperty('--bg-text', 'white')
                            break
                            case 'calm': 
                            root.style.setProperty('--bg', '#B3E5FC')
                            root.style.setProperty('--bg-text', '#37474F')
                            break
                            case 'light':
                            root.style.setProperty('--bg', 'white')
                            root.style.setProperty('--bg-text', 'black')
                            break
                        }
                    }
                </script>
            

Using JavaScript to update CSS variables

examples

updating CSS variables with JavaScript

👉🏻 Move the slider
👉🏻 Write any color in the red boxes
code:
                    <main class="booth">
                        <aside class="slider">
                            <label>Move this 👇 </label>
                            <input class="booth-slider" type="range" min="-50" max="50" value="-50" step="5"/>
                        </aside>
                        <section class="color-boxes">
                            <div class="color-box" id="1"><input value="red"/></div>
                            <div class="color-box" id="2"><input/></div>
                            <div class="color-box" id="3"><input/></div>
                            <div class="color-box" id="4"><input/></div>
                            <div class="color-box" id="5"><input/></div>
                            <div class="color-box" id="6"><input/></div>
                        </section>
                        <footer class="instructions">
                        👉🏻 Move the slider<br/>
                        👉🏻 Write any color in the red boxes 
                        </footer>
                    </main>
                    <style>
                        main {margin: 0; color: rgba(255,255,255,0.9); font-family: 'Shadows Into Light Two', 
                        cursive;}
                        main.booth {min-height: 20vh; display: flex; justify-content: center; align-items: 
                            center;} 
                        .slider{position: relative;background: rgba(0,0,0,0.4); margin: 1vw 2vw; 
                            border-radius: 0.5vw; }
                        .instructions{position: relative;background: rgba(0,0,0,0.4); margin: 1vw 0.2vw; 
                            border-radius: 0.5vw; }
                        .slider {right: 1vw; top:1vw;}
                        .slider > * {display: block;} 
                        .instructions {text-align: right; bottom: 0; background: initial;color: black;} 
                        .color-boxes {background: red; box-shadow: 1vw 1vw 3vw rgba(0,0,0,0.4); border-radius: 0.3vw;
                            transform: perspective(50vw) rotateY( calc(var(--slider) * 1deg)); transition: transform 0.3s;}
                        .color-box {padding: 1vw 3.5vw; margin-bottom: 0.5vw; border: 1px solid rgba(255,255,255,0.2); 
                            border-radius: 0.3vw; box-shadow: 1vw 1vw 3vw rgba(0,0,0,0.4);} 
                        .color-box:nth-child(1) {background: var(--bg-1);}
                        .color-box:nth-child(2) {background: var(--bg-2);}
                        .color-box:nth-child(3) {background: var(--bg-3);}
                        .color-box:nth-child(4) {background: var(--bg-4);}
                        .color-box:nth-child(5) {background: var(--bg-5);}
                        .color-box:nth-child(6) {background: var(--bg-6);} 
                    </style>
                    <script>
                        const inputs = document.querySelectorAll('.color-box > input')
                        const root1= document.documentElement
                        const range = document.querySelector('.booth-slider')
                        //as slider range's value changes, do something 
                        range.addEventListener('input', handleSlider)
                        //as the value in the input changes, do something.
                        inputs.forEach(input => {
                        input.addEventListener('input', handleInputChange)
                        })
            
                        function handleInputChange (e) {
                            let value = e.target.value
                            let inputId = e.target.parentNode.id 
                            let inputBg = `--bg-${inputId}` 
                            root1.style.setProperty(inputBg, value)
                        }
            
                        function handleSlider (e) {
                            let value = e.target.value 
                            root1.style.setProperty('--slider', value)
                        }
                    </script>