CSS, Classes & Dimensions

jQuery · Lesson 11 of 24 5 min read Updated

Making things look different is one of the most common reasons to touch the DOM: highlight a selected row, switch to a dark theme, show an error border on a form field. jQuery offers class methods, a .css() method for inline styles, and a set of methods for measuring sizes and positions.

In this lesson you will learn all three groups, the important change in jQuery 4 about units, and the plain JavaScript equivalents: classList, style, getComputedStyle() and getBoundingClientRect().

Classes first

The cleanest way to change how something looks is to define the look in CSS and switch a class from JavaScript. Your styles stay in the stylesheet, and your script only decides which state applies.

jQueryPlain JavaScript
$el.addClass("active")el.classList.add("active")
$el.addClass("a b")el.classList.add("a", "b")
$el.removeClass("active")el.classList.remove("active")
$el.toggleClass("open")el.classList.toggle("open")
$el.toggleClass("error", isWrong)el.classList.toggle("error", isWrong)
$el.hasClass("open")el.classList.contains("open")

The jQuery versions work on every element in the set; the plain versions work on one element, so use forEach for many.

HTMLTry it yourself
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Theme switch</title>
  <style>
    body { font-family: system-ui, sans-serif; transition: background 0.3s, color 0.3s; }
    body.dark { background: #16202a; color: #e8eef4; }
    .seat { inline-size: 2.4rem; margin: 0.2rem; padding: 0.3rem 0; background: transparent; color: inherit; border: 1px solid currentColor; border-radius: 4px; cursor: pointer; }
    .seat.booked { background: #0769ad; color: #fff; }
  </style>
</head>
<body>
  <button id="theme">Toggle dark theme</button>
  <h2>Choose seats: Jaipur Express, coach B2</h2>
  <div id="seats">
    <button class="seat">1</button><button class="seat">2</button><button class="seat">3</button>
    <button class="seat">4</button><button class="seat">5</button><button class="seat">6</button>
  </div>
  <p id="summary">No seats chosen.</p>

  <script src="https://cdn.jsdelivr.net/npm/jquery@4.0.0/dist/jquery.min.js"></script>
  <script>
    // Plain JavaScript for the theme
    document.querySelector("#theme").addEventListener("click", () => {
      document.body.classList.toggle("dark");
    });

    // jQuery for the seats
    $(".seat").on("click", function () {
      $(this).toggleClass("booked");
      const count = $(".seat.booked").length;
      $("#summary").text(count ? count + " seat(s) chosen, ₹" + count * 655 : "No seats chosen.");
    });
  </script>
</body>
</html>

Inline styles with css()

.css() reads or writes inline styles directly. Use it for values you calculate while the page runs, such as a progress bar width.

JavaScript
$("#bar").css("width");                          // read the computed width, e.g. "120px"
$("#bar").css("width", "75%");                   // write one property
$("#bar").css({ width: "75%", "background-color": "#2e7d32" }); // write several
$(":root").css("--brand", "#0769ad");            // CSS custom properties work too

// Plain JavaScript
const bar = document.querySelector("#bar");
getComputedStyle(bar).width;                     // read the computed value
bar.style.width = "75%";                         // write (camelCase names: backgroundColor)
document.documentElement.style.setProperty("--brand", "#0769ad");

As a getter, .css() returns the computed value of the first element (what the browser actually uses after all stylesheets), always as a string such as "16px". Use parseFloat() to get the number.

Units matter in jQuery 4. Older versions added px to almost any plain number you passed. jQuery 4 adds it only for a short list of size properties such as width, height, margin, padding, top and border-width. For anything else, such as font-size, gap or letter-spacing, a plain number is ignored. Run this to see it:

HTMLTry it yourself
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Units in jQuery 4</title>
</head>
<body>
  <p id="a">Text A</p>
  <p id="b">Text B</p>
  <button id="grow">Make both bigger</button>
  <pre id="out"></pre>

  <script src="https://cdn.jsdelivr.net/npm/jquery@4.0.0/dist/jquery.min.js"></script>
  <script>
    $("#grow").on("click", function () {
      const current = parseFloat($("#a").css("font-size"));   // "16px" -> 16

      $("#a").css("font-size", current + 4);          // number: ignored for font-size in jQuery 4
      $("#b").css("font-size", current + 4 + "px");   // string with a unit: works

      $("#out").text(
        "A: " + $("#a").css("font-size") + "\n" +
        "B: " + $("#b").css("font-size")
      );
    });
  </script>
</body>
</html>

Text A never grows; text B grows each time. The safe habit for both jQuery and plain JavaScript is simple: always pass a string with its unit.

Measuring sizes and positions

jQuery has methods that measure an element's box. The CSS box has content, then padding, then border, then margin:

jQueryMeasuresPlain JavaScript
.width()content only (a number)parseFloat(getComputedStyle(el).width) (with box-sizing: content-box)
.innerWidth()content + paddingel.clientWidth
.outerWidth()content + padding + borderel.offsetWidth or el.getBoundingClientRect().width
.outerWidth(true)... + marginadd the margins from getComputedStyle
.offset()position relative to the document: { top, left }rect.top + window.scrollY, rect.left + window.scrollX
.position()position relative to the positioned parentel.offsetTop, el.offsetLeft
$(window).scrollTop()how far the page is scrolledwindow.scrollY

.height() and its friends work the same way vertically. One difference: getBoundingClientRect() includes CSS transforms such as scale(), while offsetWidth and jQuery's methods measure the layout size.

HTMLTry it yourself
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Measuring a box</title>
  <style>
    #card { width: 200px; padding: 10px; border: 5px solid #0769ad; margin: 20px; }
  </style>
</head>
<body>
  <div id="card">Library card: Kabir</div>
  <pre id="out"></pre>

  <script src="https://cdn.jsdelivr.net/npm/jquery@4.0.0/dist/jquery.min.js"></script>
  <script>
    const $card = $("#card");
    const card = document.querySelector("#card");

    $("#out").text(
      "jQuery  width():           " + $card.width() + "\n" +
      "jQuery  innerWidth():      " + $card.innerWidth() + "\n" +
      "jQuery  outerWidth():      " + $card.outerWidth() + "\n" +
      "jQuery  outerWidth(true):  " + $card.outerWidth(true) + "\n" +
      "Plain   clientWidth:       " + card.clientWidth + "\n" +
      "Plain   offsetWidth:       " + card.offsetWidth + "\n" +
      "Plain   rect.width:        " + card.getBoundingClientRect().width
    );
  </script>
</body>
</html>

You should see 200, 220, 230 and 270 from jQuery, and 220, 230 and 230 from the plain properties.

Common mistakes

  • Setting many styles with .css() instead of a class. Styles scattered through JavaScript are hard to find and override. Put the look in CSS and toggle a class.
  • Passing plain numbers to .css() in jQuery 4. Only some size properties get px added. Write "18px", "1.2rem" and so on.
  • Overwriting all classes. .attr("class", "active") or el.className = "active" removes every other class. Use addClass or classList.add.
  • Measuring hidden elements. A display: none element has no layout box, so its sizes are 0.
  • Expecting .css("width") to return a number. It returns a string with a unit; .width() returns a number.

Key points

  • Switch looks with classes: addClass, removeClass, toggleClass(name, state) and hasClass, or classList in plain JavaScript.
  • .css() reads computed values and writes inline styles; plain JavaScript uses getComputedStyle() and el.style.
  • jQuery 4 adds px only to certain size properties, so always pass units as strings.
  • .width(), .innerWidth(), .outerWidth() and .outerWidth(true) measure content, padding, border and margin.
  • .offset() is relative to the document; getBoundingClientRect() is relative to the viewport, so add scrollY to compare.

Exercise

Build a "marks" bar: a grey track <div> with a coloured bar inside, and an input for marks out of 100. When the input changes, use jQuery to set the bar's width to that percentage with .css() (remember the unit), and use .toggleClass("fail", marks < 33) to turn the bar red for failing marks. Show the bar's measured width in pixels with .outerWidth().

Show solution
HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Marks bar</title>
  <style>
    #track { width: 300px; height: 16px; background: #eee; border-radius: 8px; }
    #bar { height: 100%; width: 0; background: #2e7d32; border-radius: 8px; }
    #bar.fail { background: #c62828; }
  </style>
</head>
<body>
  <label>Marks <input id="marks" type="number" min="0" max="100" value="45"></label>
  <div id="track"><div id="bar"></div></div>
  <p id="px"></p>
  <script src="https://cdn.jsdelivr.net/npm/jquery@4.0.0/dist/jquery.min.js"></script>
  <script>
    function update() {
      const marks = Math.min(100, Math.max(0, Number($("#marks").val())));
      $("#bar").css("width", marks + "%").toggleClass("fail", marks < 33);
      $("#px").text("Bar width: " + $("#bar").outerWidth() + "px");
    }
    $("#marks").on("input", update);
    update();
  </script>
</body>
</html>

The width is a percentage string, so jQuery 4 applies it correctly, and toggleClass with a condition adds or removes fail in one call.

Quick Quiz

1. What is the plain JavaScript equivalent of $el.toggleClass("open", isOpen)?

2. In jQuery 4, what happens with $("p").css("font-size", 20)?

3. Which jQuery method includes margin in its result?

4. What does $("#box").css("width") return?

Learn jQuery with a mentor

Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call