5 Ways that CSS and JavaScript Interact That You May Not Know About

By  on  

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!

Recent Features

  • By
    I’m an Impostor

    This is the hardest thing I've ever had to write, much less admit to myself.  I've written resignation letters from jobs I've loved, I've ended relationships, I've failed at a host of tasks, and let myself down in my life.  All of those feelings were very...

  • By
    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...

Incredible Demos

  • By
    Xbox Live Gamer API

    My sharpshooter status aside, I've always been surprised upset that Microsoft has never provided an API for the vast amount of information about users, the games they play, and statistics within the games. Namely, I'd like to publicly shame every n00b I've baptized with my...

  • By
    jQuery Link Nudge Plugin

    A while back I debuted a tasteful mouseover/mouseout technique called link nudging. It started with a MooTools version and shortly thereafter a jQuery version. Just recently Drew Douglass premiered a jQuery plugin that aimed at producing the same type of effect.

Discussion

  1. Thank you David for more wonderful USEFUL JavaScript api’s

  2. Daniel

    What about window.matchMedia ?

  3. 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.

  4. MaxArt

    Dealing 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.

  5. Shyam

    Sweet APIs

  6. Ondřej Bárta

    What about browser support for pseudo-elements in JS? I check out some resources but they do not match.

  7. George

    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.

    • Herbertusz

      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?

    • tinkertrain

      Would you like a lemonade as well sir?

  8. Nice post. You can find a polyfill for classList on the HTML5 Please site http://html5please.com/#classList

  9. 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.

  10. 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…

  11. David

    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.

  12. Nice little tricks set out here.

  13. 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.

  14. Great article! I liked how you mentioned lazy-loading resources to decrease load time, very helpful in my opinion.

  15. Shawn

    Will those add, remove and toggle class methods work on SVG nodes? That would be awesome

  16. i never get my css style sheet working on all browsers and is so annoying but this will deffo help me thanks guys

  17. David, Could you please explain what this line of code means?

    myDiv.classList.toggle('myCssClass'); // Toggles a class
    

    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.

    • Peter

      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 call element.classList.toggle('classToBeRemoved', false);

  18. 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.

  19. Thanks David, today I learn lot of things about CSS and JavaScript, which I didn’t know before.

  20. Wow..i just have one doubt..Can we use it in mobile sites ?

  21. fateen

    i’m currently dong a project on accessible website for visually impaired users..how can I change the external css value using javascript?

  22. Apart from ClassList API I didn’t know of any of the other four ways. Thanks for the awesome article.

  23. Great post. I had no idea that pointer-events could prevent events from firing.

  24. Tony

    Does pointer-events: none; also prevent the event from being activated in other ways, such as an enter key or JavaScript call?

  25. Great post! I come here often to learn new things with JavaScript. Thank you for revealing some amazing things with front-end processing.

  26. Vsync

    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.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!