CSS can be daunting to the newbie or even to the expert. This tutorial is a guide to selectors that you may (or may not) already know about. This tutorial assumes you already have a foundation of CSS (or at least understand the basic syntax).

To avoid any potential confusion here is a basic example of what selectors look like...

selector { property: value; } /* single line statements */
selector { /* multi-line statements */
    property: value;
    property: value;
}

Below are the most common selectors we all encounter in a daily basis. We'll go over the basics of these selectors. Feel free to skip this section if you believe you have a firm understanding.

The Players

Entity Selectors

Perhaps the best way to actually begin learning CSS is to start with the existing HTML elements before incorporating created ones.

Entity selectors, as we like to call them, are selectors that style HTML elements. For consider:

body { width: 960px; }

The above code sets the width of the body element to 960px. Pretty straight forward right? Let's see more examples.

body {
        margin: 0 auto;
        width: 960px;
        font: normal 12px verdana, sans-serif;
        color: #888;
}
p { line-height: 1.2em; }
a {
        color: blue;
        text-decoration: underline;
}

The above code styles the body element, the p element, and the a element. This ends our venture into the HTML entity selectors.

ID Selectors

ID selectors are our first venture into artificial elements we can style. Let's view an example off the bat:

<style type="text/css">
#nav {
        clear: both;
        background: blue;
        padding: 3px 0;
}
</style>
<div id="nav">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">Services</a></li>
    <li><a href="#">Support</a></li>
  </ul>
</div>

We can create phony elements that we can style via HTML/CSS. We indicate any ID selectors (IDs) via the id attribute in HTML. We denote IDs via the use of a "hash" tag/pound sign (#) before the name of the selector.


Note: we must cover something very very important. Both ID and CLASS selectors cannot begin with a number or special character. In fact, use nothing other than capital/lowercase letters, numbers, hyphens (-), and underscores (_) in your selectors. Let's see some examples...

#1blah { clear: both; } /* BAD */
#blah1 { display: block; } /* GOOD */
#blah_1 { top: 13px; } /* GOOD */
#blah+1 { float: left; } /* THIS DOES NOT EQUAL</pre>
<div id="blah+1">*/
#blah-1 { font-weight: 700; } /* GOOD */

Now that we have go over selector naming conventions... Let us continue:

ID selectors have a very important feature that we must be conscious of in order for our code to validate. We can only use an ID in HTML once per HTML page. IDs can be thought of as identification so it has to be unique and there is only one of them per page.

<!-- this is bad -->
<div id="item"></div>
<div id="item"></div>

Class Selectors

Class selectors are, perhaps, the most commonly used selectors. Unlike IDs, class selectors (classes) can be used multiple times within the same document. Let's see an example:

p.big { font-size: 16px; }
.underline { text-decoration: underline; }

 

<p>This is some text</p>
<p class="big">This is some <span class="underline">BIG</span> text</p>
<p class="big">Big text</p>

The output from the above would be:

This is some text This is some BIG text Big text

Class selectors are denoted by the use of a "." before the name of the selector.

Pseudo-Class Selectors

Despite the daunting name, these guys are very easy to understand and to use. We encounter these selectors on a regular basis and are often implemented globally. Let's look at an example first and foremost. This is a linkThere you are, you have now seen a pseudo-class selector (pcs) in action! What exactly did you see/do you might ask? The simple act of rolling over the link, causing an action to happen, is a pcs. Here are the most common selectors we encounter on a day-to-day basis. There are more but these will be covered later on.

/* NOTE: The ordering of these selectors must be as follows */
a, a:link { /* unvisited link */
        color: #ccc;
        text-decoration: underline;
}
a:visited { color: #666; } /* a previous visited link */
a:hover { /* what happens when you roll over the link */
        text-decoration: none;
        background: #ccc;
        color: white;
}
a:active { color: green; } /* what happens when you click on the link */

Why are these called pseudo-classes you might be wondering? Let's look at some code!

a { text-decoration: underline; }
a.hover { text-decoration: none; }
a.active { color: green; }
<!-- no roll over styled by a {} -->
<a href="#"></a>
<!-- upon roll over styled by a.hover {} -->
<a href="#" class="hover"></a>
<!-- upon click styled by a.active {} -->
<a href="#" class="hover active"></a>

Imagine when we mouse over an anchor tag our browser automatically appends the class "hover" to our anchor tags. When we click on a link, our browser automatically appends the "active" class. When we move our mouse away the "hover" class is removed. This is basically what happens with pseudo-classes. We can think of these as classes that are inherently understood by the browser and the browser checks to see if various elements are hovered over, visited already, active, etc. As much simpler way of accomplishing styling of links is via:

/* style main links */
a, a:link, a:focus { }
/* styles to show when the link has been visited already */
a:visited {}
/* styles to show when mouse is over link */
a:hover {}
/* styles to show when the link is clicked */
a:active {}

Typically, general practice (at least for us) is as follows:

a, a:link, a:focus, a:visited {}
a:hover, a:active {}

Grouping Selectors

a, a:link, a:focus, a:visited { color: green; }
a:hover, a:active { color: blue; }

What is significant about this code other than the use of Pseudo Classes one might inquire? You'll come to notice that these selectors are all separate and share the same styles. CSS is very friendly and enables us to group selectors together in order for them to share styles. Let's dissect the code above: a, a:link, a:focus, a:visited all share the same styles. This means that all basic links (when focused upon of visited) will have the color of green. a:hover, a:active will share the same styles (when hovered over or clicked on) and the color of the text will be blue. Pretty easy right? Let's take a look at inheritance.

blockquote, div.indent {
    color: #666;
    padding-left: 15px;
    font-weight: normal;
}
div.indent { font-style italic; }

We can see that we have blockquote, div.indent grouped together and are sharing the same styles. What if we want to allow div.indent to have most of the same styles as blockquote? This is an inheritance issue. We give the two elements the same styles but we want div.indent to have italic font. We can accomplish this by writing a new styling definition for this selector. Seems simple enough, right? What if we want a style for div.indent to override something in a grouping?

blockquote, div.indent {
    color: #666;
    padding-left: 15px;
    font-weight: normal;
}
div.indent { color: #ccc; }
Remember: CSS stands for Cascading Style Sheets. Cascade means to go in a sequence. CSS will only override preexisting styles if the definition comes after any previous style definitions.
div.indent { color: #ccc; }
blockquote, div.indent {
    color: #666; /* this overrides the color in div.indent */
    padding-left: 15px;
    font-weight: normal;
}
blockquote, div.indent {
    color: #666;
    padding-left: 15px;
    font-weight: normal;
}
div.indent { color: #ccc; } /* this overrides the color defined in blockquote, div.indent */

The styles are the same but the position of the styles within a style sheet make a BIG difference how they are rendered.

Nesting

To continue a lesson inheritance, we will now discuss nesting selectors in CSS. Let's look at an example:

blockquote {
    margin: 0;
    padding: 0;
    -moz-box-shadow: 0 0 5px 2px #ababab;
    -webkit-box-shadow: 0 0 5px 2px #ababab;
    box-shadow: 0 0 5px 2px #ababab;
    border: 1px solid #ababab;
}
blockquote .inner {
    -moz-box-shadow: inset 0 0 5px 2px #ababab;
    -webkit-box-shadow: inset 0 0 5px 2px #ababab;
    box-shadow: inset 0 0 5px 2px #ababab;
    border: 1px solid #ababab;
    padding: 15px 5px;
    margin: 0 5px;
}

And the HTML:

<blockquote>
     <div class="inner">Lorem ipsum...</div>
</blockquote>

In the terms of inheritance we have a parent blockquote and a child .inner. Nesting selectors implies a parent > child > grandchild > great-grandchild > and so on relationship. The simplest of these relationships is a parent-child relationship. The number of nesting you can do in CSS is only limited to how much your server can handle. The important concept to grasp with nesting elements in CSS is that your browser will assume that:

parent child { }

Means:

<parent>
     <child></child>
</parent>

And all styling done with the parent child {} will apply ONLY to the <child>element. Let's see another example!

#nav {
    width: 100%;
    border: 1px solid white;
}
#nav li { background: #ccc; }
#nav li a { color: black; }
#nav li.current { background: #222; }
#nav li.current a { color: white; }

 

<ul id="nav">
	<li><a href="#">Item</a></li>
	<li><a href="#">Item</a></li>
	<li><a href="#">Item</a></li>
	<li><a href="#">Item</a></li>
</ul>

So what's going on here anyway? We're creating a simple navigation menu so let's dissect some code:

#nav {
    width: 100%;
    border: 1px solid white;
}

This is our ID element (we only will have one of these per page). With the code above we're setting the width of the #nav element and wrapping it in a white border. Next:

#nav li { background: #ccc; }

We are nesting the #nav and li element (#nav being the parent and li being the child. We are styling:

<ul id="nav">
     <li></li>
</ul>

We can think of this as the following: where the li element is a child of the element that has the id of #nav, put a gray background on the lielement where these conditions are true. Here is a pseudo code version of what we described above:

if "li" is a child of an element that has an id of "nav"
    then, add a background of "#ccc"

Sibling Selectors

Siblings are defined as two or more objects that come from the same parent. For example:

.parent1 .sibling1.sibling2 { }

ID attributes DO NOT allow for multiple values within the ID field!

<div id="item1 item2"></div>

Will not validate!

The benefit of class attribute values is that we can use multiple class values within this attribute field. For instance:

.parent .child_1 { color: blue; }
.parent .child_1.child_2 { color: red; }
.parent .child_2 { color: green; }
.parent .child_3 { color: lightblue; }
.parent .child_4 { color: gray; }
<div class="parent">
    <p class="child_1">Text</p>
    <p class="child_1 child_2">Text</p>
    <p class="child_2">Text</p>
</div>
<div class="parent">
    <p class="child_3">This is lightblue</p>
    <p class="child_4">This is gray</p>
    <p class="child_3 child_4">This is gray</p>
</div>

Let's take a look at this code, shall we? We have a parent selector .parent and we have two children elements .child_1 and .child_2.

  1. When child_1 is within the parent element, make the text color blue
  2. When child_1 and child_2 are siblings, make the text red
  3. When child_2 is within the parent element, make the text color green
  4. When child_3 is within the parent element, make the text color lightblue
  5. When child_4 is within the parent element, make the text color gray

Let's actually see the rendered result: http://jsfiddle.net/atomicpages/b7Yuk/

What's exactly happening in our last example:

This is gray

Why would this text be gray? Would it be gray as the text suggests?
Indeed, the text would be gray as the text suggests because we are cascading styles. Because the color value described in child_4 is being called after child_3, we see the styles described in child_4. What if we had the code <p class="child_4 child_3">This text will be gray</p>. Will this text be gray or will it be lightblue?

Pseudo Element Selectors

Pseudo Elements Selectors (PES) behave the same way as normal elements. The only exception being that PES aren't actual elements. Here is a list of PES:

  • :first-line
  • :first-letter
  • :before
  • :after
:first-line

Consider the following code:

p:first-line { font-weight: bold; }

 

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Cras accumsan sapien eu urna adipiscing mattis.</p>

At first glance this may seem strange but we can assume, based on the PES, that we are styling the first line of the <p>element. Let's see a different approach:

<p><span:first-line>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span:first-line>
Cras accumsan sapien eu urna adipiscing mattis.</p>

We are imagining that Lorem ipsum dolor sit amet, consectetur adipiscing elit. is the first line of this element. It's important to know that the first line is always relative to the width of a parent container. For example: I have a width of 100px

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras accumsan sapien eu urna adipiscing mattis.

I have a width of 400px

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras accumsan sapien eu urna adipiscing mattis.
:first-letter

Similar to the :first-line PES, the :frist-letter PES styles the first letter of the matching element.

p:first-letter { font-size: 2em; }
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras accumsan sapien eu urna adipiscing mattis.</p>

Our result would be:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras accumsan sapien eu urna adipiscing mattis.
:before

The :before PES differs from first-letter or first-line greatly. The :before PES actually treats the area before an element as an autonomous entity. Let's observe some code:

<p class="before"></p>
<p>content</p>

We can consider p.before as it's own element because that's essentially what :before does to begin with. Let's see a realistic example:

<p class="upload">This is some text</p>
p.upload { font-size: 16px; }
p.upload:before { background: transparent url('upload.png') 0 0 no-repeat; }
:after

Similar to :before, the :after PES does the exact opposite of what :before does. Instead of treating the area before the element as an element, we're treating after the element as an element. Here is a very common real-life example:

<nav>
     <ul>
          <li><a href="#">Sample</a></li>
          <li><a href="#">Sample</a></li>
          <li><a href="#">Sample</a></li>
     </ul>
</nav>
nav {
     display: block;
     margin: 0;
     padding: 0;
     background: #ccc;
     float: left;
     width: 50%;
}
nav:after {
     display: block;
     clear: both;
     content: '\0020';
}
nav ul {
     margin: 0;
     padding: 0;
}
nav ul li {
     float: left;
     margin-right: 8px;
}
nav ul li a {
     color: white;
     text-decoration: none;
     font-weight: normal;
}
nav ul li a:hover { color: black; }

Since we're setting the width of our nav element to 50%, this means elements that are not floated can actually start wrapping around the nav element where there is whitespace. We have a few options here, we can clear each non-floated element that this may happen to on a dozen or so pages or we can have one CSS rule that says after this nav element we want a display a block, clear left and right floats, and add some weird content thing.

So what exactly is content: '\0020';? The code \0020 is just a space (literally -> ' '). Some people will do content: '.'; or some will use a 1px by 1px transparent gif called blank.gif to help escape floated elements. If we're dealing with responsive designs, Android navtive browser (at the time of this writing) actually showed content: "."; so I like to use \0020 instead.

Here is an exmaple on jsfiddle showing ALL of the PESs that we just covered! http://jsfiddle.net/atomicpages/FumgJ/

Direct Descendant Selectors

Although, the name I use is not the actual name, it helps me think about what these selectors do. First, let's look at the syntax because we use a unique symbol to indicate parent-child relationships using direct descendant (dd) selectors.

div p { color: red; } /* regular */
div > p { color: red; } /* dd */

So what makes these selectors unique anyway? It's all about optimization, baby! Let's look at some more code:

<div class="parent">
     <p>Text</p>
     <div>
          <p>More Text</p>
     </div>
</div>
div p { color: red; }

The above CSS will produce a potentially undesired result here. This will make all of our p elements within div red. No matter how many elements we have below <div class="parent"> they will be red unless otherwise overridden. What if we don't want that? What if we only want children of div.parentto be red?

div.parent p { color: red; }

Will that work? Of course not! I mean... we can make it work if we wanted to with extra code, but why write more code when we don't need to?

div.parent > p { color: red; }

Ahhh yes! This will work! All p children elements of div.parent will now be red and we didn't need to write extra code to override styles. Again, here is another fiddle showing a live example: http://jsfiddle.net/atomicpages/YWuHD/

Adjacent/Sibling Selectors

We touched base on sibling selectors with two class selectors. When we refer to siblinghere we mean two selectors that are adjacent to each other (the W3C doesn't explain this distinction very well). To recap, here is a sibling relationship between class selectors:

.item.one { ... } /* <div class="item one"></div> */

These adjacent/sibling selectors in this case also use a symbol similar to our direct descendant selectors:

div + dl  { padding-left: 25px; }

 

<form>
     <div>This is some text...</div>
     <dl>
          <dt>Term</dt>
          <dd>Definition</dd>
     </dl>
</form>

It is said that div and dl are siblings because they some from the same parent form in our case. Using this selector can be very useful when styling elements that lack any attributes, class values, or ids. I believe with this selector in particular, it's best to see an example. Here is a fiddle: http://jsfiddle.net/atomicpages/hYVce/

Attribute Selectors

Some of you may be scratching your heads wondering what attributes even are. Let's take a look, shall we?

<ol attribute="value">&nbsp;</ol>

Amazingly enough, attributes can be whatever we want them to be. For example, here is a sample like button using the facebook JavaScript SDK:

<div class="fb-like" data-href="http://example.com/" data-send="false" data-layout="box_count" data-width="50" data-show-faces="false"></div>

data-href, data-send, data-layout, class, data-width, and data-show-faces are all attributes and the text enclosed in double quotes (since we follow the W3C specifications) are called values.

Now that we are (re)acquainted with HTML attributes, let's begin! In CSS we have different specifications that we can use. With attribute selectors we have two specifications we can follow: CSS2 and CSS3. We must be aware of which specification we are using for browser compatibility purposes.

CSS2 Specification

This is best described in a table:

Selector Definition Example - HTML
input[rel] Match the element with "type" attribute <input rel="text">
input[type="text"] Match an element whose "type" attribute value is exactly equal to "text" <input type="text">
input[class~="text"] Match an element whose "class" attribute value is a list of whitespace-separated values, one of which is exactly equal to "text" <input type="text" class="field text">
input[lang|="en"] Match an element whose "lang" attribute has a hyphen-separated list of values beginning (from the left) with "en" <input type="text" lang="en-US">
CSS3 Specification

Being that these are CSS 3 specifications, it means that older browsers may not support them i.e. IE 6-8 and others.
The interesting thing about level 3 attribute selectors is that they're called substring selectors 1

Selector Definition Example - HTML
a[href=^="https"] Match an element whose "href" attribute begins with "https" <a href="https://google.com">Google!</a>
a[href$="sample"] Match an element whose "href" attribute ends with "sample" <a href="http://www.atomicpages.net/blog/sample">Blog!</a>
a[href*="pages"] Match an element whose "href" attribute value contains the substring "pages" <a href="http://www.atomicpages.net/">Home!</a>

To see a real-world example of using these selectors, check out this fiddle: http://jsfiddle.net/atomicpages/jLjfe/

1 http://www.w3.org/TR/css3-selectors/#attribute-selectors

:nth-child Selectors

A new feature to the CSS3 specification, this selectors gives us the power to select and style any element with a parent. We follow a simple equation when using this selection: an+b. This reminds me of high school algebra class when I was trying to get pencils stuck in the ceiling instead of actually paying attention — oh, right...

The first part of our equation, an is asking which element to select. n is the element in question. For those who are familiar with arrays and array indexes, we can think of n as the key value in an array:

$array = array(
	0 => 'Zero',
	1 => 'One',
	2 => 'Two',
	3 => 'Three'
);

Here is some sample HTML

This is some text... <!-- n = 0 -->
This is some text... <!-- n = 1 -->
This is some text... <!-- n = 2 -->
This is some text... <!-- n = 3 -->

In the example above, we show the values of n in the comments. What about a in our equation? Just like the distributive property says in algebra, we need to distribute a to n.

Let's say we want to style only the third p element in the sample of html above. Let's write some code!

p:nth-child(3n) { color: red; }

The above might be your natural inclination for this to be a success. Given the number of elements we have, you would see a correct result. Here is how it's wrong. 3n translates to:

3 * 0 = 0 no style
3 * 1 = 3 red
3 * 2 = 6 red
3 * 3 = 9 red

The correct way to style ONLY the third element would be:

p:nth-child(3) { color: red; }

In this case we just provide the value for n and the rest of the equation is assumed as 1n + 0.

What if we wanted to style all of the EVEN or ODD elements?

p:nth-child(2n+1) { color: red; } /* style odds */
p:nth-child(2n+2) { color: blue; } /* style evens */

Here's the math spelled out:

Odd Even
(2 * 0) + 1 = 1 (2 * 0) + 2 = 2
(2 * 1) + 1 = 3 (2 * 1) + 2 = 4
(2 * 2) + 1 = 5 (2 * 3) + 2 = 6

Some of you may be having an "ah-hah" moment right now and that's quite all right! Here is a more simple way to accomplish the above:

p:nth-child(odd) { color: red; } /* same as 2n + 1 */
p:nth-child(even) { color: blue; } /* same as 2n + 2 */

Finally, as a last example, let's say we wanted to style the 9th, 19th, and 29th element:

p:nth-child(10n-1) { color: green; }
p:nth-child(10n+9) { color: green; }

So which is the correct answer? They're both correct actually. The last bit to our equation, b can be any positive, negative, or zero value – no decimals, ± characters, +-, or -+ allowed. Here is a fiddle to play with! http://jsfiddle.net/atomicpages/fKYmF/.

Be Sociable, Share!