Native JavaScript Equivalents of jQuery Methods: CSS and Animation

Contributing Editor

Do You Really Need jQuery? Sometimes — especially if you want to support IE6/7/8 using jQuery 1.x. However, modern browser APIs now provide much of the functionality we take for granted in jQuery. In this article, we’re going to look at methods related to CSS.

Class Manipulation

One of the most common jQuery tasks is applying a class to a specific element:

$("#myelement").addClass("myclass");

We can achieve the same thing in native JavaScript:

document.getElementById("myelement").className = "myclass";

This isn’t quite the whole story:

  1. jQuery can apply the class to any number of nodes.
  2. jQuery appends the new class to existing class definitions, but the native example will overwrite them.

In native JavaScript, the className property is simply a string. We therefore need a function to replicate how jQuery works, e.g.

function addClass(node, class) {
	if (!node.length) node = [node];
	for (var n = 0, m = node.length; n < m; n++) {
		if ((" " + node[n].className + " ").indexOf(" "+class+" ") >= 0) {
			node.className += " " + class;
		}
	}
}
// apply myclass to all nodes
addClass(document.getElementById("myelement"), "myclass");

While this code is smaller and faster than jQuery, we’re replicating what’s already available in the library — there’s little point.

Fortunately, modern browsers now offer a new classList property which implements a DOMTokenList — an array-like collection of all classes applied to a node. The following properties are available:

  • length — the number of class names applied
  • item(index) — the class name at a specific index
  • contains(class) — returns true if a node has that class applied
  • add(class) — applies a new class to the node
  • remove(class) — removes a class from the node
  • toggle(class) — removes or adds a class if it’s applied or not applied respectively

We can use this in preference to the clunkier className property:

document.getElementById("myelement").classList.add("myclass");

classList is supported by most browsers except IE9. Fortunately, a couple of shims are available which could be conditionally loaded in that browser.

Style Manipulation

jQuery provides a number of methods to apply specific styles, e.g.

$("#myelement").css({
	color: "#c00",
	backgroundColor: "#eee",
	width: "200px",
	height: "100px",
	borderColor: "#f00"
});

The native equivalent:

var m = document.getElementById("myelement"), c = m.style;
c.color = "#c00";
c.backgroundColor = "#eee";
c.width = "200px";
c.height = "100px";
c.borderColor = "#f00";

Over 10,000 iterations using cached selectors, the jQuery code executed in 6,670ms. Native JavaScript took 330ms — it was 20x faster.

Of course, you shouldn’t use either unless a value needs to be calculated in some way. It’s more efficient to define a class of styles in CSS then apply its name to the element.

Animation

jQuery offers various animated effects out of the box including sliding and fading. Native JavaScript can be faster but none of that matters: CSS3 animation trounces both.

I was initially skeptical about CSS3 animation. It can never offer fine-grained control (such as stopping an animation after N frames) and trespasses on JavaScript’s behavioral responsibilities. However, the benefits more than outweigh the drawbacks:

  1. CSS3 animation is handled by the browser; it will always be faster than JavaScript execution.
  2. CSS3 animation is easier to use and requires significantly less code.
  3. CSS3 offers effects such as 3D transformations which would be impractical — if not impossible — in JavaScript alone.

IE9 and below won’t show the effects but they can degrade gracefully and IE10 should be the dominant version within a few months.

The CSS3 genie will never go back in the lamp. If you’re still using jQuery or JavaScript for DOM animation in modern browsers, you’re probably wasting your time.

That said, JavaScript can be used to react to CSS3 animations when they start, stop or proceed to the next iteration using animationstart, animationend and animationiteration accordingly. For more information, refer to How to Capture CSS3 Animation Events in JavaScript.

In my next article, we’ll finish the series by looking at events, Ajax and utility functions.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://magnetikonline.com.au/ Peter Mescalchin

    Craig – I’m liking these series of articles, anytime I can work on a project and not fall into the trap of using jQuery I’m happy. :D

    On the CSS3 animation/transition DOM event side of things, I put this little library together recently to make things easier – from memory it was your original CSS3 animation event blog post that was a good reference for this work: https://github.com/magnetikonline/cssanimevent

    • http://www.optimalworks.net/ Craig Buckler

      Thanks Peter.

      I wouldn’t necessarily call jQuery a trap, but some developers use it out of habit because they think it offers cross-browser compatibility in browsers where the issues no longer exist.

      Great work on your CSS3 library!

      • http://magnetikonline.com.au/ Peter Mescalchin

        Thanks Craig.

        Yeah “trap” is probably a weee bit harsh. :D

  • Christopher Pitt

    document.getElementById(“myelement”).classList.add(“myclass”)

  • http://www.greensock.com Jack

    You’re absolutely right about CSS animations trouncing jQuery for animation, but there are some huge limitations when it comes to CSS animations that make them ill-suited for professional-grade animation (jQuery is terrible for that too). Like did you know you can’t control individual components of transforms independently? For example, try animating the rotation and scale of an element with different timings (that overlap) and different eases. No-can-do. And you can’t seek or reverse or time-scale. And what if you want to animate along a Bezier path or do physics-based animations or use an ease like Elastic or Bounce? Nope. What about animating canvas library objects or generics? If you’re just doing some simple stuff with css, they’re great. But CSS animations quickly fall apart when you start doing serious stuff. Try doing this animation with CSS: http://www.greensock.com/why-gsap/

    Have you checked out GSAP yet? It’s literally up to 20x faster than jQuery plus it’s far more flexible than CSS animations and requires less code. A lot less. There’s an article comparing GSAP and CSS transitions/animations at http://www.greensock.com/transitions/. Sometimes CSS animations are faster than JS, but not always. A lot depends on how the JS is written and which properties you’re animating.

    Anyway, sorry if that came off as promotional or argumentative – I just think there’s a lot of hype surrounding CSS animations and they can be great but too few people talk frankly about all the shortcomings.

    You make some excellent points about how people rely on jQuery for too much these days (even though it is a great tool). Thanks for sharing your thoughts.

    • http://www.optimalworks.net/ Craig Buckler

      Thanks Jack. I agree that CSS3 animation is limited — you’d struggle using it in a game, for example. (That said, Alex Walker’s CSS3 Pong is insane!… http://www.sitepoint.com/css3-pong-insane-things-to-do-with-css/).

      GSAP looks great (shame you couldn’t name it ‘GASP’!). It’s ideal for advanced animations where you require fine-grained control over paths and individual frames.

      However, jQuery mostly implements fading, sliding and simple CSS property transitions. They’re used for basic animations such as pop-ups, lightboxes, and carousels which could (and probably should) be replaced by CSS3 alternatives.

  • http://www.vordik.com/ Toronto Web Design agency

    CSS animations that make them ill-suited for professional-grade animation like did you know you can’t control individual components of transforms independently. jQuery plus it’s far more flexible than CSS animations.

    • http://www.optimalworks.net/ Craig Buckler

      No one is saying CSS3 is the answer to all animations you could ever want or need. Not sure what you mean by “professional-grade”, but they cover the basics very well and certainly go beyond what’s offered by the jQuery core.

    • http://www.brothercake.com/ James Edwards

      You should look into @keyframes if you want more control over CSS animations.

  • http://heera.it Sheikh Heera

    Thanks Craig! I was not aware of classList. Anyways, according to this http://www.sitepoint.com/browser-trends-june-2013/ IE (all) users are still now 29.69% so it’s not the right time yet to drop a library and start using the new features of modern browsers. I think it’ll take 2/3 years to completely rely on new features without worrying about backward compatibility but I could be wrong.

    • http://www.optimalworks.net/ Craig Buckler

      In the most part, IE10 is as good as the competitors, growing rapidly and supports classList. IE9 and below are losing market share and are likely to be inconsequential within one year. Assuming you don’t have clients who need oldIE support, backward compatibility for core features such as DOM manipulation, events and Ajax will become a thing of the past.

      • http://www.brothercake.com/ James Edwards

        You can’t be serious?

        People are still using IE7, and you think IE9 will be inconsequential in less than a year?

  • Hemanth

    Thanks Craig for getting us all back to plain javascript and that we don’t need frameworks with the available latest technologies. Not to say jquery is not good. It definitely had its day.

  • http://www.fortuneinfotech.co.uk/ Web Development

    Thanks…