Inheritance and Cascading in CSS
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
- Styles can be inherited from a parent
- Later styles over-rule earlier styles
- Styles can combine from different sources
- Style definitions can use any combination of element, id, classname and modifier
- You can specify an element with a certain element type AND id and classname(s)
- 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
However, you can make an element inherit styles from its parent.
Example
<p style="border:inherit;">
Border properties are not inherited by children, by default, but because I set border to "inherit", it is.
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
body {
background-color:yellow;
font-weight:bold;
}
div {
background-color:#afa;
font-weight:normal;
}
</style>
<body>
<div>
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.cssborder:2px dashed red;
}
<style type="text/css">
.frodo {
background-color:#fcc;
}
</style>
<div class="frodo" style="font-style:italic;">
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.:
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
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
#thing {
color:red;
}
</style>
<div id="thing">
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
.makegrey {
background-color:#ddd;
font-weight:normal;
}
.bigfont {
font-size:1.5em;
font-weight:bold;
}
</style>
<div class="makegrey bigfont">
Its text is also big and bold, because the div also has the class "bigfont".
<div class="bigfont makegrey">
Because the second class (makegrey) sets the font-weight to normal, it over-rides the bold setting of the first class (bigfont).
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
#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>
<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:
- Any div that is inside another div
- A list item (<li>) that is a child of an unordered list (<ul>)
- 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:
- div div {styles here...}
- ul li {styles here...}
- 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.
<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>