Inheritance and Cascading in CSS


This is a guide to help people learning CSS to understand how a browser works out what styles to apply to a particular element.

As we saw in the introduction to CSS, there are lots of ways you can apply styles to a particular element. When more than one of these methods applies, how do you know which styles will be applied?

Fortunately, these rules are quite simple, once you know them. This article tries to explain all. Of course, the best way really to learn this stuff is to try stuff out and see what happens.

Overview of rules

  1. Styles can be inherited from a parent
  2. Later styles over-rule earlier styles
  3. Styles can combine from different sources
  4. Style definitions can use any combination of element, id, classname and modifier
  5. You can specify an element with a certain element type AND id and classname(s)
  6. Styles can apply to elements nested in a particular way

1. Styles can be inherited from a parent

Some styles, like font family, text-alignment etc., are automatically inherited by child elements from their parent element (i.e. by an element contained inside another one). Other are not automatically inherited.

Example

<div style="font-family:serif; border:1px solid red; padding:10px;">
This text will be in a serif font.
<p>
This text is also in a serif font, because font is inherited by default.
But the border and padding properties are not inherited from the parent div.
</p>
</div>

However, you can make an element inherit styles from its parent.

Example

<div style="font-family:serif; border:1px solid red; padding:10px;">
This text will be in a serif font.
<p style="border:inherit;">
Now the paragraph also has a red border.
Border properties are not inherited by children, by default, but because I set border to "inherit", it is.
</p>
</div>

2. Later styles over-rule earlier styles

If you define a style property, and later define an alternative style property for the same thing, the later definition over-rules the earlier one.

Example

<style type="text/css">
body {
background-color:yellow;
font-weight:bold;
}
div {
background-color:#afa;
font-weight:normal;
}
</style>

<body>
<p>Some text here, inherits properties of the body.</p>
<div>
<p>However, the div's rules over-ride the body's rules, as the div's rules apply later (i.e. nearer to this text in the document).</p>
</div>
</body>

This also applies when you have a combination of external stylesheets, on-page styles, and inline styles. All other things being equal, the styles that are defined latest, i.e. written nearest to the actual HTML elements and read by the browser last, will over-rule earlier definitions.

3. Styles can come from different sources

The styles that are eventually applied to an element can have been defined in any combination of the following ways:

  • An external stylesheet
  • On-page style definitions
  • Inline styles
  • Inherited from a parent/container

Complex example

styles.css
.frodo {
border:2px dashed red;
}
complex.html
<link href="styles.css" type="text/css" rel="stylesheet" />

<style type="text/css">
.frodo {
background-color:#fcc;
}
</style>

<div class="frodo" style="font-style:italic;">
Here's some text.
</div>

In the example above, the div with the class name "frodo" gets its border style from an external stylesheet, its background-color from styles defined above on the page, and its font-style from an inline style.

From what we've already seen, if the later styles set any of the same properties as the previously-defined ones, they would overwrite the previous styles.

4. Style definitions can use any combination of element, id, classname and modifier

The basic ways of applying a style to an element are by virtue of its

  • HTML element type
  • HTML element type modifier
  • id property
  • or its classname(s)

I'll explain what each of these means, and how & when you should use them.

HTML element type

As we covered in the Introduction to CSS, you can define styles to apply to HTML elements of a certain type, all the way from the body to little list items.

In CSS, this is written as, e.g.:

table {
margin:10px;
background-color:#fff;
}

This will apply a space of 10px around every HTML table, and make them all have a white background - unless over-ruled by other styles.

HTML element type modifier

There are only a few of these, and the only ones that are really useful and that work on all browsers are the modifieres to the anchor (link) tag <a>.

Anchor tags have 4 modifiers:

a:link
Doesn't really do anything; just applies to an anchor that really is a link.
a:visited
Used for styling a visited link.
a:hover
Applies when you hover your mouse over the link.
a:active
Applies when you have the mouse button down on a link.

Note that it's good practice to apply any of these modifiers in the order above. I don't know why, but it'll ensure they work as expected on different browsers. (I use the mnemonic: "LoVe HA!" to remember it.)

Example

<style type="text/css">
a, a:link {
color:blue;
text-decoration:none;
}
a:visited {
color:#666;
}
a:hover, a:active {
color:red;
text-decoration:underline;
}
</style>

<a href="css-inheritance-cascade.cfm">I am a link to this page, so should look "visited".</a>
<a href="nofile">I am a link to a non-existent file, so should look "unvisited".</a>

ID

An HTML element may have one ID (unique identifier) property, e.g. <form id="searchform">. And there should be only one element on a page with a particular ID.

To assign styles to an element through its ID, the styles must be defined in CSS (either on the page, or in a separate CSS document), and indicated by the element's id prefixed with a hash/pound sign (#).

Example

<style type="text/css">
#thing {
color:red;
}
</style>

<div id="thing">
This text is red, because it is part of the element with the id "thing".
</div>

Classname(s)

Applying styles by classname can get more complicated than using an element's ID, because:

  • There can be more than one element with the same class, and;
  • An element may have more than one class.

Example

<style type="text/css">
.makegrey {
background-color:#ddd;
font-weight:normal;
}
.bigfont {
font-size:1.5em;
font-weight:bold;
}
</style>

<div class="makegrey bigfont">
This div is grey, because it has the class "makegrey".
Its text is also big and bold, because the div also has the class "bigfont".
</div>

<div class="bigfont makegrey">
This version also has both classes, however the font is not bold because the class names are reversed.
Because the second class (makegrey) sets the font-weight to normal, it over-rides the bold setting of the first class (bigfont).
</div>

5. You can specify an element with any combination of id, class and element

You can apply styles to an element using id, classnames, element, and modifier in any combination.

Example

<style type="text/css">
#someid { background-color:#666; }
.class1 { color:#fff; }
.class2 { font-weight:bold; }
div { border:1px solid blue; }
a { font-style:italic; }
a:link { text-decoration:underline; }
</style>

<div id="someid" class="class1 class2">
<a href="#">
This text inherits all the styles above - each a different way..
</a>
</div>

6. Styles can apply to elements nested in a particular way

You can define styles to apply to particular kinds of elements nested within (or a child of) other particular kinds of elements. For example:

  1. Any div that is inside another div
  2. A list item (<li>) that is a child of an unordered list (<ul>)
  3. An anchor (<a>) that is a child of a list item that is a child of an unordered list with the id "links"...

To specify nesting, you list the element definitions separated by a space. Here's how I'd define the specifications above:

  1. div div {styles here...}
  2. ul li {styles here...}
  3. ul#links li a {styles here...}

All I've done is list the parent (or grandparent) elements in order of placement in the HTML document (highest first), concluding with the target element I want to be affected.

Note: Elements defined in this way don't have to be directly inside the parent/ancestor elements. There can be other elements in between, so long as the elements are nested in the order specified.

Last modified: Thursday, 24 July 2014, 2:54 PM