CSS tutorial for jQuery developers

This tutorial is targeted to jQuery developers who want to know a little bit more about how CSS works. CSS and jQuery are tightly coupled together, because the main syntax of jQuery is CSS-like. Also, jQuery can read the values of all CSS properties, thus providing an invaluable help in most cases. What's more, jQuery animations are CSS-based and the jQuery UI theming is based in turn on CSS cascading. Let's see some use cases of how CSS works.

Cascading and specificity

Cascading is the way by which multiple styles combine together and specificity is the mechanism that allows browsers to assign the final values to all page elements. Suppose that you have the following CSS rule:

#test {
 width: 100px;
 height: 100px;
 background: gray;
}

You have an element with ID test. Suppose now that you want to dynamically change its styles by adding the following class to it:

.evident {
 background: red;
 width: 150px;
 height: 150px;
}

Then you use jQuery like so:

$('#test').hover(function() {

  $(this).addClass('evident');

}, function() {

  $(this).removeClass('evident');

});

but nothing happens. Why? This is where CSS specificity comes into play. Since both rules have the same declarations and since an ID selector is more specific than a class selector, the first rule wins. If you want to make this code work, you have to increase the specificity of the second rule:

#content div.evident {
 background: red;
 width: 150px;
 height: 150px;
}

If you're in trouble with specificity, use the !important statement: it makes a declaration take precedence over the others.

#content div.evident {
 background: red !important;
 width: 150px !important;
 height: 150px !important;
}

But what happens when two rules have exactly the same specificity and the !important declarations have failed? In this case, the rule that comes later in the source wins. This principle applies also to linked style sheets: the style sheet that comes later in the source has an higher precedence over the others. Suppose that you want to overwrite the default theme of jQuery UI. In this case, your custom CSS file must come later in the source:

<head>
<!--<link> to the jQuery UI CSS file-->
<link rel="stylesheet" href="theme-custom.css" type="text/css" media="screen"/>
</head>

The same rule applies to imported style sheets: a style sheet imported through the @import rule has a lower precedence over the style sheet that hosts it. For further reading, check out this post.

Positioning

CSS positioning is used with animations to move an element around the screen. There are two kinds of positioning: relative and absolute. Relative positioning is calculated using the current position of an element as reference, while absolute positioning takes the whole viewport as its default reference.

Consider this example:

#slider img {
 position: relative;
 float: left;
 width: 200px;
}

Then when you use the animate() method, the offsets of each image will be calculated according to their positions. So if your first image is visible inside the slider, its initial position will have a left offset of 0, while the second image will have a left offset of 200 and so on. The sliding of each image will be calculated in relation with their initial offsets:


function moveImage(index) {

  $('img', '#slider').eq(index).
  animate({
    left: - $(this).position().left
  }, 1000);

}

By default, the movements obtained with top, right, bottom and left CSS properties are the following:

  1. top: from top to bottom
  2. right: from right to left
  3. bottom: from bottom to top
  4. left: from left to right

If you use a negative value, then the movement is inverted. In our example, the movement will take place from right to left.

Absolute positioning, instead, calculates the offsets and positions by taking the whole browser viewport as reference. This default behavior can be modified if you set position: relative on the parent element of the child elements you want to absolutely position. By doing so, now the positions and offset of the child elements will be calculated against their parent element, not against the viewport.

Since absolute positioning doesn't take into account the current position of an element, as with relative positioning, all elements will be by default put on the very top left corner of their parent, that is, they will be entirely removed from their original positions. You should always be aware of this fact when you decide to use absolute positioning.

Floats

Unlike positioning, that removes elements from the normal flow without affecting other elements, floating moves elements along the current line by pushing them to left or right. The main problem with floating is that they make vertical space collapse, so you have to contain them. For example:

#slider {
 width: 200px;
 overflow: hidden;
 height: 100%;
}

Using the overflow property set to hidden, combined with an height declaration for IE6, it's one of the most used techniques for containing floats. The only case when containing floats is not necessary is when your parent element has a stated height: in this case, vertical space doesn't collapse.

Another thing to bear in mind is horizontal space: when a float doesn't have more room for being displayed on the same line, it's automatically moved to the next line. That's why most sliders use the following approach:

#slider-wrapper {
 width: 2000px;
 height: 200px;
}

2000 pixels prevents floated images from being moved to the next line. This rule is used in combination with overflow: hidden on the main container to make sure that all images will be on the same line and that only one image will be visible at time.

Leave a Reply

Note: Only a member of this blog may post a comment.