You use CSS and create web pages for websites and applications but if you are not clear with few terms such as Cascading, CSS Specificity, and Classes and IDs then I recommend you this post to read now or bookmark for the later read. This post is written by Bappi Das one of ADMEC Mutlimedia best students in his assessment. He tried to put his best of CSS that he learnt in his CSS course in this institute with us.
What is CSS?
A simple one-line answer to this question is Cascading Style Sheet.
Now, what is “Cascading”?
The dictionary meaning of Cascade is –
(noun): A small waterfall, typically one of several that fall in stages down a steep rocky slope.
(verb): pass (something) on to a succession of others.
Well, we all know that CSS is something that is used to style the HTML. So, why these styling elements were named as Cascading Style Sheet? Did the inventors of CSS loved waterfalls or did they made CSS like that passes on something to a succession of others?
To understand this, we need to dive into the deeper world of CSS and see how the browsers think.
Let’s start our journey with a simple HTML document:
We all can understand this HTML, but the browser looks into this same HTML something like this –
This is called HTML family tree with the following members –
- Ancestor
- Descendent
- Parent
- Child
- Sibling
where –
- <html> tag is the ancestor of all other tags.
- <body> tag is the ancestor of <h1>, <p>, <ul> and all the <li> tags.
- <body> tag is the descendent of <html> tag.
- <p> tag is the descendent of both <body> and <html> tag.
- <li> tag is the descendent of <ul>, <body> and <html> tag.
- <title> tag is the descendent of both <head> and <html> tag.
- <html> tag is the parent of both <head> and <body> tag.
- <head> tag is the parent of <title> tag.
- <body> tag is the parent of <h1>, <p> and <ul> tag.
- <head> and <body> tags are the child of <html> tag.
- <title> tag is the child of <head> tag.
- <h1>, <p> and <ul> tags are the child of <body> tag.
- <strong> tag is the child of <p> tag.
- All the <li> tags are the child of <ul> tag.
- <head> and <body> tags are the siblings.
- <h1>, <p> and <ul> are the siblings.
- All the three <li> tags are siblings.
Now, let us come back to the term “cascading” which means pass on something to a succession to others. Here, we will try to understand this with another simple HTML example.
The browser will display this HTML page something like this –
Here, we see that the <strong> tag is accumulating the styles from it’s ancestors <body> and <p> tags. Thus, we have a clear view about that “Styles” are passed on to a succession to the child or descendants. Now, we can understand that the inventors of CSS didn’t go for the term “Cascading” because they loved waterfalls. So, we may say that Cascading is a set of rules for determining which style gets applied to an HTML element. It also specifies how a browser should handle multiple styles that apply to a same tag and what to do when CSS properties conflict.
So, we come to an important conclusion that –
The inherited styles accumulate.
But, what happens when the inherited styles conflict? Who wins?
Let’s check this with the following example –
The browser will display this HTML like this –
Here, we see that the <strong> tag has inherited the styles from its ancestors <body> and <p> tag. But, there was a conflict on the “color” property. But, finally we see that the color property of the nearest ancestor <p> tag is being applied. In other words, we can say that, <p> tag is the nearest ancestor of the <strong> tag, so it has applied the “color” property from its nearest ancestor <p> tag to resolve the conflict.
Thus, we come to an another important conclusion that –
The nearest ancestor wins when there is a conflict.
Till now, things are going smooth and we are getting a clear idea how the cascading works. But, sometimes we get trapped into more awkward and unexpected situation with CSS. In the next section, we shall dive deeper into all the weird things and come out with the solution to deal with them.
Let’s start the things with this simple looking HTML document –
As per the CSS, we have come across till now, we expect the second paragraph with class “special” should be displayed with font-family: “Times New Roman” and the text color red. But it is not what we expected. Just have a look
how the browser has displayed it for us –
This all has happened due to the Specificity.
Now, what is Specificity?
- A browser decides which specific style to be applied to an HTML element based on the preference or specificity of the style, when there is a conflict.
Here is a simple table with a few examples for calculating the specificity of the styles –
Tag Selector. eg. p{ color: red;} and h1{ font-size: 32px;} etc. | 1 Point |
Pseudo Element. eg. ::first-line{ color:blue;} | 1 Point |
Class Selector. eg. .mystyle{ font-family:Arial;} | 10 Points |
Pseudo Class. eg. :hover{ background-color:red;} | 10 Points |
ID Selector. eg. #sidebar{font-family:Arial;color:blue;} | 100 Points |
Inline Style. eg. <p style=”color:green”>Some text…</p> | 1000 Points |
Now, let’s try to understand how the browser assigns specificity to different styles –
SELECTORS | ID | CLASS | TAG | TOTAL SPECIFICITY |
p | 0 | 0 | 1 | 1 |
.mystyle | 0 | 1 | 0 | 10 |
p .mystyle | 0 | 1 | 1 | 11 |
#sidebar | 1 | 0 | 0 | 100 |
#sidebar img | 1 | 0 | 1 | 101 |
p strong | 0 | 0 | 2 | 2 |
#wrapper #sidebar .mystyle a:hover | 2 | 2 | 1 | 221 |
Now, let’s see the HTML document above and we notice that the specificity of #sidebar p is 101, whereas the specificity of .special is 10.
So, the color and font-family property defined inside the style #sidebar p overrules the same inside the class .special.
Note: The math involved with specificity calculation is a bit more complex then described above. But, this formula works for almost all the cases except a few weirdest cases. To know, how the browsers actually calculate specificity, please visit this link : http://www.w3.org/TR/css3-selectors/#specificity
Now, we move into the solution. If we get trapped in some weird situation as shown in the above example, then what should we do? There are two specific solution for this –
- Change the IDs into Classes to avoid complexity.
- Overrule the specificity with !important.
In our example, if we change a bit of the CSS styles by converting IDs into classes then it gives us the desired result
as follows –
Now have a look how the browser has displayed it for us –
This same result can also be achieved with the use of !important in the CSS properties as shown bellow –
At last, we end this discussion with a few things about CSS selectors using IDs in CSS. As per many CSS experts throughout the globe, it is better to avoid using IDs so far as possible to avoid complexity. ID selectors are very powerful and therefore we require more powers to override them. This often leads to specificity conflicts in which the style-sheet gets loaded with un-necessarily long and complicated selectors.
Instead, we should try to replace IDs with classes which works perfectly and removes all the limitations as well as complexities that we may face by using IDs. Basically, IDs don’t provide anything special that we can’t achieve with a simple class selector or a tag selector. So, it’s better to avoid using IDs – to avoid complexities.