Introduction to CSS: Selectors and Relationships Explained

Multithreaded JavaScript, O'Reilly 2021, has been published!


This article will provide an introduction to CSS, which also requires an explanation of HTML (even if you know HTML you may want to read through it as it explains the relationship model). This article won't explain every single CSS attribute, but will explain everything you need to know to fully comprehend the language.


Here are a few definitions and synonyms that I'll use:

  • Document – Our file we are editing which contains our HTML, CSS, or both
  • Element – A tag in our document
  • Parent – An element that contains another element
  • Child – An element contained within another element
  • Descendant – Any element inside of an element, even if it is nested within further elements
  • Ascendant – Any element that contains our element, even if it isn't the immediate parent


What is HTML?

First of all, what is HTML? It stands for HyperText Markup Language, which doesn't really say much. Ignoring the first two letters, what follows is Markup Language. A Markup Language is simply a storage language, which doesn't perform any calculations or decisions. In it's simplest form you've got XML (eXtendable Markup Language) which is essentially HTML except that there are no pre-defined “tags” and you can create your own “tag”.

Here is an example of HTML:

<ul id="mylist">
  <li class="foo">Text</li>
  <li class="foo bar"><strong>More Text</strong></li>
  <li style="color: black;"><a href="">Google</a></li>
<!-- This is a comment and does nothing -->
<br />

As you can see, it is a very simple language. The first thing that should be explained are tags. A tag is one of those items inside of the angle brackets, such as UL or BR. Tags are stored in a hierarchical manner, with tags existing inside of other tags. In this example, the UL contains three LI's, and the second LI contains a STRONG, and the like. All tags have closing tags as well (The /UL for example) which tells us where our tag ends.

You're probably wondering what is going on with the BR tag, since it has a slash inside of it. We call this a self closing tag; it doesn't actually contain any content (the BR is basically the same as pressing enter and creating a newline) so it doesn't need a separate closing tag.

Notice how the A tag has some extra information in it, specifically the href=”” part. We refer to this as an attribute. An attribute gives us more information about the tag and what it does. The attributes which affect how CSS works are the CLASS, ID, and the STYLE attributes.

HTML Element Relationships

Now, lets talk a little bit about the relationships of these elements. The three LI's are the “children” of the UL element. This means that the UL element is the “parent” of the LI elements. The UL tag isn't the direct parent of the A element, but it is an ascendant of it (think grandparent). Something to keep in mind is that if you apply a style to an element, all of its descendants get this same style applied to it. You can call this effect “Cascading” or “Inheriting”.

The LI elements are all siblings of each other, however this really doesn't matter to much when using HTML. Also, the LI element which has the style attribute is like the “uncle” of the A element, however this relationship doesn't matter whatsoever. In fact, I made up the term uncle to confuse you.

CSS (Cascading Style Sheets)

Time for what you are reading this article for, CSS. CSS, like HTML, is a language used to explain how things should look, and doesn't do any thinking or have any control structures. Lets see an example of CSS:

Example CSS Document

body {
  background-color: #eee;
ul {
  color: orange;
#mylist {
  font-weight: bold;
.foo {
  color: blue;
li > a {
  color: yellow;
ul li {
  text-decoration: underline;
/* This is a meaningless comment! */

CSS Selectors

In CSS, we call the items before the culy brackets in the above document selectors. They define what the rules in the following curly brackets will apply for. For example, the first group is called “body” and will affect the body of the document. Here's a list of the syntax of our selectors and what they mean:

  • item {} – This applies to an <item> element.
  • .item {} – This applies to any element with the class="item" defined.
  • #item {} – This applies to any element with the id="item" defined.
  • item subitem {} – This applies to a <subitem> element which is a descendant of an <item> element.
  • item > subitem {} – This applies to a <subitem> element which is a direct cihld of an <item> element (IE8+).
  • item:pseudo {} – This applies to pseudo elements, e.g. if you use a:hover, it will apply to <a> elements that you mouse over.
  • element.item {} – This applies to <element> with class="item", but not to other elements with the same class.
  • element#item {} – This applies to <element> with id="item", but not to other elements with the same id (which there shouldn't be any).

Not a very complex system if you think about it. Everything is based on relationships. Once you apply a style to an element, this style will be inherited in all of its children.

ID's vs. CLASS's vs. STYLE's

You're probably wondering why there is a difference between ID and CLASS attributes, I mean you can do everything just using one or the other, right? Well, yes you can… However ID's have an important role. Technically, there should only be ONE element in your document with any given ID. ID's also have a lot higher CSS priority, which is described in the specificity section.

Also, whats the deal with the STYLE attribute? This is a CSS rule that applies only to the element that you attach it to. We call this inline CSS, as you are actually placing your CSS inside of your HTML document (which is a naughty thing to do, but it makes things easier in certain situations). You don't use any selectors with your inline CSS, you just set rules, so you can't do any of the intricate children styling.

Default Browser CSS

Some element attributes are overwritten and need to be redefined, like if a paragraph is red, its links will be the default blue unless you specifically change them. I wish I had a copy of the default CSS that is applied to a document, if anyone ever gets a copy please post it in the comments!

Basically, there is a default stylesheet that is applied to an HTML document, and each browser has a slightly different one. For example, all text is black, Times New Roman, 12px. All links are blue, all background attributes are set to transparent. This can of course be overwritten.

Specificity and Rule Overwriting

When refering to an element, there can sometimes be conflicts. For example, if you do the following:

a { color: yellow; }
a { color: orange; }

The color of your A elements are going to be orange. Think of it like this, as the browser goes through your CSS document and pulls out rules, it builds a table of them. The table is first built from the default browser CSS, and is then replaced/appended with your rules. In this case, the second rule replaced the first rule.

Now, say that you define the following rules:

#item a { color: lime; }
a { color: purple; }

And you apply them to this HTML document:

<div id="item">
  <a href="#">This will be lime!</a>
<a href="#">This will be purple!</a>

As you can see, the first rule which defines purple links is more specific than the second rule which defines all links, which explains why the colors work the way they do. Here is a link to the page about CSS Specificity on the website. It goes through and shows you how to calculate your specificity for different situations. The easiest way to think about it is the more specific you are, the more likely the rule is to apply to the element.

Tags: #css
Thomas Hunter II Avatar

Thomas has contributed to dozens of enterprise Node.js services and has worked for a company dedicated to securing Node.js. He has spoken at several conferences on Node.js and JavaScript, is an O'Reilly published author, and is an organizer of NodeSchool SF.