CSS Style Selectors, Inheritance, and Specificity
Cascading Style Sheets (CSS) is a markup language used to format languages like HTML (thanks Wiki). Anyone who is involved with web pages will have to know some level of CSS in order to manipulate the content on the screen. One of the difficult pieces of designing web pages is tailoring the CSS so it will work on the greatest number of browsers. Every browser will display content a little bit differently because they each have their own way of interpreting CSS. A few of the major browsers are Google Chrome, Microsoft Internet Explorer, Mozilla Firefox, and Apple Safari. There are also portable versions of these browsers on mobile devices like cell phones and tablets. The newest browsers support most of the advanced CSS while the older browsers only support a subset of the CSS language. It’s important to keep compatibility in mind if you’re developing a web page that needs to be accessible by everyone.
Two aspects of CSS that need to be understood when building a web page are inheritance and specificity. Inheritance is when a child element uses the same CSS styles from a parent or further up the family tree. Specificity determines which properties will be applied to an element based on the type of selectors used. For these examples, the CSS color property will be used with different selectors to show how inheritance and specificity affect the text color.
The image below is a snapshot from Google Chrome. One of the nice features of Chrome (and many other browsers now too) is the Developer Tools which can be accessed by pressing F12. You can also right click on almost any object in web page and click Inspect element to access the Developer Tools. On the left side, you’ll see the HTML organized into different levels while on the right side, you’ll see the styles for the selected element.
Let’s take a look at a very basic markup that says: Hello and good morning world. All the text is inside of a paragraph (p) tag and most of the words are inside span tags. By default, all the text inside of the paragraph tags inherits the properties of the paragraph. In this case, the paragraph has the property,color, with a value of green so the text wrapped in span tags will inherit the color green. Take a look at the last three span tags. They all have attributes like class, id, and style. These attributes can be used with CSS selectors to specify which properties to apply to the elements.
<p style="color: green;">
Hello <!-- Green -->
<span>and</span> <!-- Gold -->
<span class="class2 class">good</span> <!-- Pink -->
<span class="class" id="id" style="">morning</span> <!-- Red -->
<span class="class" id="id" style="color: blue;">world</span> <!-- Blue -->
</p>
If you’re scratching your head at this point wondering where the CSS for the first, second, and third span tags is located, take a look at the next image. I’ve listed over 10 different selectors from CSS version 1, 2, and 3 that you can use in your web pages. For a full list of selectors, check out this page from W3Schools.
<style>
* {
color: white;
}
p {
color: green;
}
p span {
color: palegreen;
}
p > span {
color: gold;
}
span:last-child {
color: gray;
}
span:nth-child(4) {
color: silver;
}
span {
color: orange;
}
.class {
color: black;
}
.class2 {
color: cyan;
}
span.class {
color: pink;
}
span[style] {
color: brown;
}
#id {
color: red;
}
</style>
Once you combine the HTML and the CSS into a web page, you should get something that looks like this:
Now, if you would like to know how web browsers determine which selector has the highest priority, take a look at a screenshot from Chrome. The styles at the top have the highest priority while styles at the bottom have the lowest priority. All of the color properties in the image below are applied to the word, world, but only one can actually be display on the screen. The element.style is the style=”color: blue;” HTML attribute which is placed inline on the span tag itself.
There are a few things to note about the order of priority. The span[style] and span.class selectors are of equivalent priority so whichever one is loaded last will take priority. The same thing also applies to the span:nth-child(4) and span:last-child selectors. From a CSS standpoint, the selector with the highest priority (outside of the inline style) is the id selector (#id) because you should only have 1 element on a web page with a certain id. Classes may apply to a bunch of elements while ids should be unique.
The span[style] is an interesting little selector. It can only be applied to elements that have an inline style attribute. For instance:
<span id="id1" style="font-size: 12px;">This WILL receive the style</span>
<span id="id2">This will NOT receive the style</span>
In the current versions of Chrome, Firefox, and Safari, you can have empty attributes: style=“”. In Internet Explorer 11, empty attributes are automatically removed so the span[style] does not apply.
The last piece of information I’m going to share is about the !important declaration. It is the trump card of CSS. Any property that contains the !important declaration will receive the highest priority. If multiple styles use the declaration, the browser will use the same hierarchy as described above, but with the !importants at the top. It looks like this:
span {
color: orange !important;
}
I’m going to warn you…if you find yourself using the !important declaration in your own code a lot, you’re probably not following best practices. I’ve run into issues with WordPress themes and plugins that have stylesheets with !important declarations and they lead to inconsistent formatting. Check out this article on CSS Tricks to see best practices for the declaration. Remember, there is no way to override an inline !important declaration without modifying the element itself:
<p style="color: orange !important">You cannot override my color!</p>