The power of CSS variables
Have you ever wanted to change the content of a :before
or an :after
pseudo-element? You might have tried using javascript to gain access to them but you soon realized that they are not real DOM elements, thus you can’t manipulate them. The thing is you’re not out of luck! Enter: CSS variables.
When you hear of CSS variables you might think of pre-processors like LESS and SCSS which uses variables but after compiling you just get static values. No, I’m talking about real variables that you can change in real time. Cool, huh?
Let’s imagine we have a form with fields we want to validate. We want to show a tooltip with a message depending on the field, e.g. we want to show a message saying that the email format is incorrect but a different one for the lenght of the password. Also we don’t want to clutter the DOM with lots of spans or paragraphs with the different messages. The cleanest option is using the pseudo-elements :before
and :after
but the problem is changing the message at will. Or is it?
Let’s talk first about CSS variables. You might have read articles and tutorials showing you that you can declare variables in the root element like this:
And then you can access the variable anywhere in the css file:
This is very cool and useful when you want to change a lot of element’s background at the same time but if you want to change specific values to specific elements, this won’t cut it.
Fortunately we can limit the scope of the variables to classes or ids:
This way --primaryColor
is only accessible in the container-class
element. But why would we want to do this? To have dynamic content applied to our pseudo-elements. Let me explain. First we have the wrapper class for the input field:
Crappy message, I know, but bear with me. Now we have the actual input with its pseudo-element:
Now we have the cool stuff where we assign the values to --errorMessage
via Javascript:
The function addErrorMessage
would be called for each input element and you will pass the element element
and the appropriate message message
:
The object messages
contains the messages for the respective field. Lets imagine that the name of the properties are the actual names of the inputs. This will help us avoid a lot of if
statements or a switch
. We then query for the input
elements in the page and store them in inputs
. After that we loop through the inputs and call addErrorMessage
for each one of them, sending as parameters the element input
and the appropriate message. For the message part we access the value using the name of the property which happens to be (conveniently) the input name.
The beauty of this is that every :after
pseudo-element will have a different content
with the respective error message. This is possible because the --errorMessage
variable scope is limited to its respective wrapper-class
.
Browser support for CSS variables is somewhat limited but it will get better with time.
Hope you found this article helpful. Until the next time…