How to Change Look & Feel of Pseudo Elements using JavaScript and CSS Custom Properties
Changing the UI of pseudo elements through JavaScript can become difficult sometimes. Let's see how we can make it easy with help from CSS Custom Properties.
The Problem
In general, if we want to change anything in pseudo elements through JavaScript, we do it in the following way:
- Create CSS classes on element, which will change pseudo elements' UI
- Get the element using
querySelector
- Modify the classes using
classList
Above approach works fine. But, if we need more customizations in pseudo elements, we will end-up creating many classes to handle all scenarios.
CSS Custom Properties to the rescue
Custom properties (sometimes referred to as CSS variables or cascading 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 are accessed using thevar()
function (e.g.,color: var(--main-color);
). - Source
Let's take an example to see it in action.
Initial Markup
- Create HTML for checkmark
<span class="checkmark"></span>
- CSS for
.checkmark
.checkmark {
display: inline-block;
width: 20px;
height: 20px;
border-radius: 10px;
background: #61d345;
position: relative;
transform: rotate(45deg);
}
.checkmark::after {
content: '';
box-sizing: border-box;
position: absolute;
border-right: 2px solid;
border-bottom: 2px solid;
border-color: #fff;
bottom: 6px;
left: 6px;
height: 10px;
width: 6px;
}
After above, the result will look like below:
Great, checkmark looks neat... ๐
Usage of CSS Custom Properties
Now, let's assume that in your website you want to allow users to change colors of this checkmark as they need on runtime. Let's see how we can change colors of element and its pseudo element with CSS Custom Properties.
Change colors in CSS like this:
.checkmark {
/* rest remains same */
background: var(--check-primary);
}
.checkmark::after {
/* rest remains same */
border-color: var(--check-secondary);
}
๐ Note: Custom property names are case sensitive โ
--my-color
will be treated as a separate custom property to--My-color
.
Now, from your JavaScript, you would do like below to update the colors:
// 1. Get the element
const element = document.querySelector(".checkmark");
function changeColor() {
// 2. Modify its custom css properties
element.style.setProperty("--check-primary", "#607d8b");
element.style.setProperty("--check-secondary", "#303030");
}
Cool! Now whenever you call changeColor
, it will update the colors. And it will look like below:
But wait, there is still one more problem. After updating the CSS, when you initially render it, it looks like below:
The reason it happened is we used CSS variables to assign colors, but those variables don't have any initial values.
We can solve this in 2 ways:
1st - Initialize variables with class or :root
.
:root {
--check-primary: #61d345;
--check-secondary: #fff;
}
// or
.checkmark {
--check-primary: #61d345;
--check-secondary: #fff;
}
2nd - Give fallback value in var()
function:
.checkmark {
background: var(--check-primary, #61d345);
}
.checkmark::after {
border-color: var(--check-secondary, #fff);
}
That's it! The final CSS looks like below:
.checkmark {
display: inline-block;
width: 20px;
height: 20px;
border-radius: 10px;
background: var(--check-primary, #61d345);
position: relative;
transform: rotate(45deg);
}
.checkmark::after {
content: '';
box-sizing: border-box;
position: absolute;
border-right: 2px solid;
border-bottom: 2px solid;
border-color: var(--check-secondary, #fff);
bottom: 6px;
left: 6px;
height: 10px;
width: 6px;
}
I have also created a Codepen:
Thank you for reading this article. Let me know your feedback and thoughts in comments section. I am also available on twitter via @shhdharmen.
Happy Coding.
๐ฒ ๐ ๐