Treehouse

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!

ydkjs-1.png

Recent Features

  • CSS 3D Folding Animation

    Google Plus provides loads of inspiration for front-end developers, especially when it comes to the CSS and JavaScript wonders they create. Last year I duplicated their incredible PhotoStack effect with both MooTools and pure CSS; this time I'm going to duplicate...

  • Chris Coyier’s Favorite CodePen Demos

    David asked me if I'd be up for a guest post picking out some of my favorite Pens from CodePen. A daunting task! There are so many! I managed to pick a few though that have blown me away over the past few months. If you...

Incredible Demos

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.

    • MaxArt

      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.

  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.

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

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