5 Ways that CSS and JavaScript Interact That You May Not Know About
CSS and JavaScript: the lines seemingly get blurred by each browser release. They have always done a very different job but in the end they are both front-end technologies so they need do need to work closely. We have our .js files and our .css, but that doesn't mean that CSS and JS can't interact more closely than the basic JavaScript frameworks will allow. Here are five ways that JavaScript and CSS work together that you may not know about!
Get Pseudo-Element Properties with JavaScript
We know that we can get basic CSS style values for an element with the style
property, but what about pseudo-element properties? Yes, JavaScript can even access those too!
// Get the color value of .element:before var color = window.getComputedStyle( document.querySelector('.element'), ':before' ).getPropertyValue('color'); // Get the content value of .element:before var content = window.getComputedStyle( document.querySelector('.element'), ':before' ).getPropertyValue('content');
You can see how I access the content property value in my blog post about Device State Detection. Incredibly useful if you're looking to create dynamic, unique sites!
classList API
We've all used the addClass
, removeClass
, and toggleClass
methods in our favorite JavaScript libraries. For the sake of supporting older browsers, each library would grab the element's className
(in its string format) and appending/removing the class, then updates the className
string. There's a newer API for adding, removing, and toggling classes, and it's called classList:
myDiv.classList.add('myCssClass'); // Adds a class myDiv.classList.remove('myCssClass'); // Removes a class myDiv.classList.toggle('myCssClass'); // Toggles a class
classList
has been implemented for a long time in most browsers, but this API hit IE at version 10.
Add and Remove Rules Directly to Stylesheets
We're all well versed in modifying styles via the element.style.propertyName
method, and we've used JavaScript toolkits to do it, but did you know you can actually read and write rules within new and existing stylesheets? The API is actually quite simple too!
function addCSSRule(sheet, selector, rules, index) { if(sheet.insertRule) { sheet.insertRule(selector + "{" + rules + "}", index); } else { sheet.addRule(selector, rules, index); } } // Use it! addCSSRule(document.styleSheets[0], "header", "float: left");
The most common use case is creating a new stylesheet, but if you want to modify an existing stylesheet, go for it.
Load CSS Files with a Loader
Lazy-loading resources like images, JSON, and scripts is a great way to decrease load time. We can load those external resources with JavaScript loaders like curl.js, but did you know you can lazy load stylesheets and get that notification within the same callback?
curl( [ "namespace/MyWidget", "css!namespace/resources/MyWidget.css" ], function(MyWidget) { // Do something with MyWidget // The CSS reference isn't in the signature because we don't care about it; // we just care that it is now in the page } });
This blog lazy loads PrismJS, the syntax highlighter, based on the presence of pre
elements. Once all resources are loaded, including the stylesheet, I can fire off a callback. Useful!
CSS pointer-events
CSS' pointer-events
property is interesting in that it almost acts in a JavaScript-like way, effectively disabling an element when the value is none but otherwise allowing the element to function per usual when the value isn't none
. You may be saying "so what?!" but pointer-events even prevent JavaScript events from firing!
.disabled { pointer-events: none; }
Click on that element and any addEventListener
callback you've placed on the element will not fire. A perfect property, really -- you don't need to do a className
check before you decide whether or not to fire something based on class presence.
Those are just five ways that CSS and JavaScript interact that you don't always think of. Have more ideas? Please share them!
Thank you David for more wonderful USEFUL JavaScript api’s
What about
window.matchMedia
?I did know the specifics of pseudo-element properties with JavaScript. And I had no idea classList API existed. Any idea if library’s like JQuery make use of that API? I assume it is faster when available.
Nope, jQuery doesn’t use it, because it seems the change isn’t worth the effort in most cases:
http://bugs.jquery.com/ticket/5087
Things may change in the future, though.
MooTools supports
classList
since July 2012: https://github.com/mootools/mootools-core/commit/bd6ac113600fa508017c29237cf03c36171e9603Dealing with stylesheets has always been a mess… Thanks, of course, to Microsoft and its deaded IE.
Things improved in IE9, but IE8 is still an issue for most of us.
In the end, universal and standardized specs have seen the light too much too late and the damage was done. A *huge* damage. That’s why today we’re not dealing with CSS rules with the freedom we do with DOM nodes.
And there’s no current way to determine style properties for pseudo-elements or altered stated on IE<9.
Also a note: pointer-events may be cool, but don't relyon it estensively because IE<11 and Opera<15 don't support it, and they fire the mouse events. If you have to support those, use classes and whatever.
Sweet APIs
What about browser support for pseudo-elements in JS? I check out some resources but they do not match.
As always, no info about about browser support.
Do more research before posting, please.
As always, the browser support for said features frequently changes so do your own research before using.
How do you mean “browser support frequently changes”? For example, tha classList api supported by IE10+. Do you think it will change in the future?
Would you like a lemonade as well sir?
Nice post. You can find a polyfill for classList on the HTML5 Please site http://html5please.com/#classList
Every time I come across one of your articles, I feel like an amateur.
Quote.
And this site is like a golden mine to me.
Thanks, David.
CSS pointer events ftw
Agreed – one of my favorites for sure. People have also used it to increase performance in some interesting ways, so the future seems bright. No IE10 support is extremely disappointing though…
Love it, but learning new vanilla js still requires old school for compatibility. I guess I feel like sticking with a library is far more practical, but then again, not every article has to have code that’s immediately practical. Cool to know thought.
Nice little tricks set out here.
Wow! CSS – event? I never heard of this before. It’s so interesting for me that events can be implemented in CSS without need to write javascripts code. Thank you for this informative post.
Great article! I liked how you mentioned lazy-loading resources to decrease load time, very helpful in my opinion.
Will those add, remove and toggle class methods work on SVG nodes? That would be awesome
i never get my css style sheet working on all browsers and is so annoying but this will deffo help me thanks guys
David, Could you please explain what this line of code means?
I can understand Remove and Add methods but not this one.
I would appreciate if you answer my question.
It means that if the class is currently applied to the element, it will be removed. If it is not present, it will be added.
Citing MDN (https://developer.mozilla.org/en-US/docs/Web/API/element.classList#Syntax)
“The
toggle
method has an optional second argument that will force the class name to be added or removed based on the truthiness of the second argument. For example, to remove a class (if it exists or not) you can callelement.classList.toggle('classToBeRemoved', false);
“for input elements, setting
input.diabled=true|false
in JS triggers the:disabled
and/or:not(:disabled)
pseudo-selectors.Same works for
input.checked
with a checkbox/radio button. so you can make rules like:checked ~ *
and:not(:checked) ~ *
to control vast swaths of your interface.Oops. that’s pretty ugly. I assumed the code tag would be inline. my bad.
Thanks David, today I learn lot of things about CSS and JavaScript, which I didn’t know before.
Wow..i just have one doubt..Can we use it in mobile sites ?
i’m currently dong a project on accessible website for visually impaired users..how can I change the external css value using javascript?
Apart from ClassList API I didn’t know of any of the other four ways. Thanks for the awesome article.
Great post. I had no idea that pointer-events could prevent events from firing.
Does
pointer-events: none;
also prevent the event from being activated in other ways, such as an enter key or JavaScript call?Great post! I come here often to learn new things with JavaScript. Thank you for revealing some amazing things with front-end processing.
I would very much like this post to be revised for our current times, 2018. much has been added to the world of CSS-JS.