O'Reilly

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!

Track.js Error Reporting

Recent Features

  • Detect DOM Node Insertions with JavaScript and CSS Animations

    I work with an awesome cast of developers at Mozilla, and one of them in Daniel Buchner. Daniel's shared with me an awesome strategy for detecting when nodes have been injected into a parent node without using the deprecated DOM Events API....

  • Create Namespaced Classes with MooTools

    MooTools has always gotten a bit of grief for not inherently using and standardizing namespaced-based JavaScript classes like the Dojo Toolkit does.  Many developers create their classes as globals which is generally frowned up.  I mostly disagree with that stance, but each to their own.  In any event,...

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.

  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.

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

Recently on David Walsh Blog

  • Sort git Branches by Date

    I'll be first person to admit I don't do as much git repository maintenance as I should.  I rarely delete branches which have been merged, so a git branch execution shows me a mile-long list of branches that likely aren't relevant.  The best way to find branches I've recently...

  • Best Tools and Resources for Web Professionals in 2015

    Looking for the right resources to help you satisfy the needs of your clients? On the lookout for the best tools to help you increase your revenue? Searching for the right software to help you improve your business? Well, then you’ve come to the right place....

  • JavaScript Polling

    Polling with JavaScript is one of those ugly but important functions within advanced front-end user experience and testing practices.  Sometimes there isn't the event you can hook into to signify that a given task is complete, so you need to get your hands dirty and simply poll for...

  • OSCON Portland:  Conference Giveaway and Discount!

    O'Reilly puts on the best web industry conferences in the world.  These conferences include Fluent Conference, Velocity Conference, and the upcoming OSCON in Portland, Oregon from July 20-24.  Open Source Convention (OSCON) is a conference that focuses specifically on open source developers and the tools and possibilities...

  • Prevent Chrome from Translating a Page

    A while back I shared my favorite Google Chrome extension:  Google Art Project.  I've enjoyed seeing beautiful art when I open a new tab -- it's brought genuine happiness to my day, however small that happiness may be.  About a week ago, however, the art presented had...