Quick Intro to CSS variables

Quick Intro to CSS variables

CSS custom properties can be set and used as variables. Let’s learn the basics of CSS variables, and how cool they can be.

They look like this:

:root {
	--accent-color: #123123;
}

And when you need to use that dark green anywhere on the site, you use the custom property inside a var() as a variable like this:

h2 {
	color: var(--accent-color);
}

It works exactly like a CSS value, but controlled in one spot, and that means you can change it any time to change all instances where it’s used. It’s super useful. Especially in the long run when you are developing repeated templates, following strict color schemes, or even making your own development workflow.

Just one thing we need to cover before we move on.
PLEASE NOTE: CSS custom properties do not work on IE11. If your client’s user base is less than 2% for IE11 on smaller sites or less than .5% for sites with huge traffic, then you’re ok (those are just the numbers I’ve seen large companies use when making that decision). Otherwise, you’re going to have to use regular values. If you still want to be able to make your own CSS frameworks, then consider learning SASS. You can change the variables and then compile it to work on IE11. (Regardless of IE11, SASS is also a great syntax to learn, so consider learning it. It works with CSS variables as well.)

OK, back to the modern web.

Now for the rest of the world who either used IE11 to install Chrome or Firefox, we can talk about CSS variables.

The video

Global properties

When defined in the :root, the properties apply literally to the root. Which means the whole html document, or simply put, the whole page. For most websites, including WordPress, the CSS file will probably be loaded in the and will be in the first few lines of the file, so there’s no problem getting it to apply to every part of the whole website.

Let’s have a look at a quick example.

:root {
	--body-color: blue;
	--accent-color: red;
	--line-height: 1.2;
	--margin-unit1: 6rem;
}
h2 {
	font-size: 2rem;
	margin-top: var(--margin-unit1);
	margin-bottom: calc(var(--margin-unit1) * .25);
}
p {
	font-size: .9rem;
	margin: 1em 0;
}
h2, 
p {
	line-height: var(--line-height);
}
.txt-color_accent {
	color: var(--accent-color);
}
.txt-color_body {
	color: var(--body-color);
}

Let’s break that down.

A certain color has been defined in the root dubbed “accent color,” and “body color.” The default line height (leading in typography terms) is defined alongside as my favorite unit, the 6rem, as a base unit 1.

We then proceed to use those custom properties as variables in h2, p, and some classes.

Please note that the variables can even be used inside a calc.

If at any time, we need to change any styling, such as the accent color, then all we need to do is change it in the root, and voila, done.

So that’s pretty simple, right? How does that work in real-life WordPress page builder terms? I know most of my readers use a page builder of some kind or another, so let’s see how it works there.

For Beaver, Divi, and Elementor, you can use a child theme to load up the CSS file, and you can just add the custom properties at the beginning of the file. For Oxygen, you can enqueue the CSS file with a plugin, or you can add a whole file in the builder.

Once you have the custom properties and the classes that use them as variables so you can easily toggle multiple styles all set up, it’s time to implement it.

Let’s say you have the HTML set up like this:

<section class="ai-section ai-padding_v1">
	<div class="ai-row ai-container ai-flex">
		<div class="ai-col ai-col_1-2 ai-col_img">
			<img src="/url/image_name.jpg" alt="yo image">
		</div>
		<div class="ai-col ai-col_1-2 ai-col_txt">
			<h2 class="txt-color_accent">
				This is the h2
			</h2>
			<p class="txt-color_body">
				This is the body text. Lorem ipsum something something dolor, yada yada yada. 
			</p>
		</div>
	</div>
</section>

Here’s the JSfiddle that will show how it looks. (note: I added some extra bits for the image to show as a gray block, and the layout stuff is not added so it just stacks.)

Then you can probably see that the h2 and p will all be colored as per their assigned classes.

You can see that once you write the CSS to be controlled with selectors (in this case, classes), you can easily add the classes to the modules throughout the builder of your choice, and have a centralized (and very detailed) settings panel.

Feel free to fork the fiddle and… fiddle around with it.

So that’s great.

However, you can take it a step further and do even cooler stuff with…

Local properties

Yeah, you read that right. CSS variables can have local properties. Simply put, you can define them inside other selectors besides :root. Have a look at this CSS:

:root {
	--body-color: #222;
	--body-color-inv: #eee;
	--accent-color: red;
	--accent-color-inv: yellow;
	--light-bg: #eee;
	--dark-bg: #000;
}
.section-color_reg {
	--section-bg: var(--light-bg);
	--section-accent-color: var(--accent-color);
	--section-body-color: var(--body-color);
	background-color: var(--section-bg);
}
.section-color_inversed {
	--section-bg: var(--dark-bg);
	--section-accent-color: var(--accent-color-inv);
	--section-body-color: var(--body-color-inv);
	background-color: var(--section-bg);
}
.txt-color_accent {
	color: var(--section-accent-color);
}
.txt-color_body {
	color: var(--section-body-color);
}

Soooooo… this is a bit more interesting , isn’t it?

We’ll only be focusing on colors at the moment, but everything else would work the same.

Let’s break it down.

In the root, we define all the colors we’ll need later down the road.
There are two separate classes, each with new custom properties defined, and they use a predefined custom property as a variable.
The text colors are defined with the variables that would have been defined in its parent element.
And the children inherit the custom property from its parent.

Here’s the html that you can try it with:

<section class="ai-section section-color_reg">
	<div class="ai-row ai-container ai-flex">
		<div class="ai-col ai-col_1-2 ai-col_img">
			<img src="/url/image_name.jpg" alt="yo image">
		</div>
		<div class="ai-col ai-col_1-2 ai-col_txt">
			<h2 class="txt-color_accent">
				This is the h2
			</h2>
			<p class="txt-color_body">
				This is the body text. Lorem ipsum something something dolor, yada yada yada. 
			</p>
		</div>
	</div>
</section>
<section class="ai-section section-color_inversed">
	<div class="ai-row ai-container ai-flex">
		<div class="ai-col ai-col_1-2 ai-col_img">
			<img src="/url/image_name.jpg" alt="yo image">
		</div>
		<div class="ai-col ai-col_1-2 ai-col_txt">
			<h2 class="txt-color_accent">
				This is the h2
			</h2>
			<p class="txt-color_body">
				This is the body text. Lorem ipsum something something dolor, yada yada yada. 
			</p>
		</div>
	</div>
</section>

Have a look at the preview (again, nothing for layouts except a quick img block)

Just run that with the css in a style tag and you’ll be able to see it run. Or just check out this fiddle and fork it.

Did you get it to work? Coolio.

What this means for us

Now what kinds of awesome potential does this open up for us? Well, this means that we can define whole sections and layouts using second-tier variables that are once removed from the root and all we need to do is change things in the root to drastically change whole layouts and color schemes.

Think of it like this:
Define everything you need in root > mid-level element defines its children’s styles > children are only defined with properties inherited from mid-level elements

You can easily define stuff like font families, flex properties, spacing/sizing units, etc, and they can all be controlled with one class!

Even better, you can write your CSS to inherit styles directly from the theme or plugin, and that means the settings from the plugin/theme will also control your custom code styles! That’s pretty awesome, right?

If you need to override the builder’s CSS that defines what you’re writing to be able to write local properties, you can use an id in front of the mid-level elements like this:

#builder .section-color_reg {
	--section-bg: var(--light-bg);
	--section-accent-color: var(--accent-color);
	--section-body-color: var(--body-color);
	background-color: var(--section-bg);
}

That’ll usually take care of things. Of course, change the #builder to whatever id the theme or page builder is using. If you need help finding the right one, have a look at the bottom of this post about setting responsive typography, or learn how to inspect the frontend with this (virtually) free course.

Want to learn more?

Want to learn how to read and write CSS in record time? The CSS crash course can do that for you.

Want to learn some CSS, but you’re not sure how to start? I have a course that covers everything from beginner to expert.

I have a lot of courses covering lots of topics at different price points so come have a look.

Leave a Reply

Your email address will not be published. Required fields are marked *

    New tutorials

    Why no ads?

    Hi, I'm PK, and I maintain and publish content on this site for two reasons.

    1. To give back to the community. I learned so much from people's tutorials and StackOverflow that I wanted to contribute and help others.

    2. To provide a more structured learning experience. People struggle to find the course that guides them from start to finish, based off of real life experience, and my courses provide that.

    The only "ads" I have here are for my own courses, and maybe an affiliate link, but that's it. They fund the website resources and provide more motivation for me to produce better content.

    Any bit of interest helps. Even sharing with your friends, suggesting my courses to your developer or designer, or subscribing to my YT channel, or joining our Discord. Thanks and I'll see you around!

    There's a newsletter!

    Sign up to the newsletter for the occasional updates on courses, products, tutorials, and sales.

    Happy Pride Month!

    Happy Pride Month!

    Pretty simple really.

    Happy pride month to everyone who celebrates it!

    I've been seeing a lot of nasty comments on social media recently, so I wanted to add some extra pixels that lean towards love, empathy, and inclusivity to help balance it out.

    Thanks,
    PK