Demystifying the Rules of Cascading and Inheritance

There are several important CSS RULES of cascading and inheritance that you must know; otherwise, you may may get confuse as to why your CSS styles are not working as you intend them to work.  However, as in real life, there are usually exceptions to rules. This is the case with CSS rules as well.

Cascade and Inheritance are two different but related concepts:

According to W3C, cascading is defined as:

The cascade takes an unordered list of declared values for a given property on a given element, sorts them by their declaration’s precedence …, and outputs a single cascaded value.

In other words, a host of cascading styles can be associated with a given page. The browser will read ALL the styles and determine if there are any conflicts. If conflicts exist, the rules of cascading will determine which elements take precedence over others.

 

There are four main concepts that control the order in which CSS declarations are applied. They are listed below from highest weight to the least weight.

  1. Origin and Importance
  2. Specificity
  3. Source order

Origin and Important are the most important. However:

  • If two selectors have the SAME importance, then the specificity rule decides which one will be applied.
  • If two rules have the SAME specificity, then the source order decides which one will be applied.

General Guideline

You usually start with a comprehensive rule that cover most of what you need and then trump it with another rule.

Example

Let's say that you want ALL heading 1 text color to be blue with a blue border INITIALLY, you could write a RULE like this:

h1{color:blue; border:1px solid blue; padding:5px; display:inline;}


Then, you want ONLY the first heading text red but still have a blue border, you could write an EXCEPTION to this rule with another rule to trump just the blue text property and then apply it to the <h1> tag using a class attribute (see code below):

.my_custom_heading{color:red;}

What we have done is to start with a GENERIC RULE that covers MOST of what we NEED initially. Then, we created a MORE SPECIFIC RULE to trump what want DON'T NEED.

Conflict Resolution

When there are two DIFFERENT values (e.g., blue and red) for the SAME property (e.g., color) within DIFFERENT selectors, a CONFLICT will emerge. To resolve this or any other CSS conflict, you have to understand ALL of the rules of cascading to be effective.

The highest weighted attribute that the cascade checks is the ORIGIN and IMPORTANT of a given rule.

The origin of a declaration is based on WHERE it comes from and importance is whether or not it is declared important with the !important annotation.

The !important keyword is used to override order, specificity, and inline rules.

Authors should exercise caution when using !important rules since they will override any of the user's ! important rules.

EXAMPLE:

A low vision or color-blind user may require large font sizes or special colors and will normally declare their own style rules to be !important. Since !important rule will override normal rules, authors are advised to use normal rules almost exclusively to ensure that users with special style needs are able to read their page.

!importance has more weight than anything else regardless of its position within the style sheet.

Because BOTH author and user may specify important rules, the author's rule will trump the user rule in cases of importance.  Hence, it is recommended that you only use the !important annotation when working with 3rd-party styles.

The cascading rule considers BOTH the origin and importance when determining which declaration takes precedence. The combination of the two is given a weight and the one with the highest weight wins out. Below is the list in order from the highest to the least weight:

  1. CSS Transitions
  2. User-Agent (browser) & !important
  3. User & !important
  4. Author & !important 1
  5. CSS Animations, @keyframes 2
  6. Author, normal weight
  7. User, normal weight
  8. User agent, normal weight

When a user agent checks for conflicting CSS declarations and one wins at the origin & importance level, the CSS cascade resolves to this first rule. No other rule is needed. However, if conflicting declarations have the SAME level of origin and importance, the cascade moves on to the second rule of cascading: selector specificity.

1 Author styles (internal, external, and inline) are the only styles that the author has control over.

2 Even though animations are created by an author, they are temporary and the user agent weights them higher than normal author rules.

The second weighted attribute in the CSS cascade is selector specificity.

RULE OF SPECIFICITY – Since there are many ways to applied styles, what happens when there are multiple styles (e.g., internal, external, or inline) with different rules associated with them for the same element. In the absence of no user style sheet, the rule of cascade takes affect:

NOTE: The style rule closest to the TARGET tag will take precedence if there is any conflict.

  • An INLINE style will take precedence over an INTERNAL (embedded) style because it is closet to the target element.
  • An INTERNAL style with take precedence over an EXTERNAL style sheet IF IT IS LISTED BELOW THE LINK TO AN EXTERNAL STYLE SHEET. OTHERWISE, THE EXTERNAL STYLE SHEET WILL TAKE PRECEDENCE BECAUSE IT IS CLOSEST TO THE TARGET TAG IN CODE (NOT LOCATION).  Another way of saying this is that the <link> or <style> tag that is LAST in the <head> tag will take precedence.

While moving down the cascade styles, rules will either COMPLIMENT or CONFLICT when the element has the same property name but different rules defined within multiple places.

EXAMPLE:

If a rule in an external style sheet defines an <h1> tag as blue and italic:

h1{color:blue; font-style:italic;}

Then, there is an internal style sheet with the same <h1> tag rule but defined as green and italic AND is below the external style sheet.

h1{color:green; font-style:italic;}

The h1 element text color will be green (because it conflict with the external style sheet but also trump it) AND italic (because the font-style rule compliment each other because they are the same for both selectors).

The browser will SEQUENTIALLY check each styles and set any match properties as it moves down. If a match property is indeed found AGAIN further down the list, it will continue looking for additional match until it reaches the end of the list. The last match will be displayed in the browser.

EXCEPTION: If a rule is defined with the !important key word, it will take precedence over any other rule. (e.g., h1 {color:blue !important;}).  Notice the space between the rule and the key word !important.  This style basically said that it will define the h1 tag as blue regardless of the cascading order that will be discussed later.

h1{color: blue !important;}
h1{color: red;}

RULE OF SPECIFICITY – A more specific selector will always take precedence over a less specific or general selector

  • An INLINE selector takes precedence over an ID selector
  • An ID selector takes precedence over a CLASS selector which in turn takes precedence over an ELEMENT or TAG selector.

Specificity is useful when setting common elements and then overriding them for more specific elements. For example, if most of the tables are set to 100%, an individual table can be set to a different percentage elsewhere. table {width:100%;} table#special {width:80%;}

As each page loads, the browser checks the SELECTORS to see if a rule match. If a conflict exists, the SELECTOR with the most SPECIFICITY takes precedence. Listed from least to the most weight below.

Like origin & importance which each have their own weight, different CSS selectors are assigned different. When calculating specificity, the number of selectors and their weight are considered.

Style sheets can also override conflicting style sheets based on their level of specificity. More specific style will always win out over a less specific style. To calculate the specificity, count the number of:

  1. ID selectors
  2. CLASS selectors & pseudo-selectors (e.g., link, hover, active, and visited)
  3. Element (also called Type) selectors & pseudo-elements (e.g., ::before)

Then, write the three numbers in exact order with no spaces or commas to obtain a three-digit number. Note, you may need to convert the numbers to a larger base to end up with three digits. For example:

#id1 {…} /* a=1 b=0 c=0 --> specificity = 100 */
li.blue {…} /* a=0 b=1 c=1 --> specificity = 011 */
li {…} /* a=0 b=0 c=1 --> specificity = 001 */

The rule of specificity gives different weight to different selector types regardless of where they appear on the CSS ladder.

The order is as follow:

  • !important key word trump all selectors (Not needed on inline since it trump all other selectors)?????
  • Inline selectors (trump all selectors) 
  • ID selectors
  • Class (Normal and pseudo) selectors
  • Element/Tag selectors

    MEMORY TIP: To help you remember the order, think of the acronym ICE: Inline and ID, Class, and Element

TIP: If a rule that you are trying to apply  to an element does not seem to work. It may be because you did not make your selector SPECIFIC enough to OVERRULE a style that is being APPLIED somewhere else.

CAUTION: Text properties of a class or ID selector will NOT trump a tag selector if it target the parent container (e.g., a <div> tag) instead of the tag.

EXAMPLE:

p {color:red;font-weight:bold;}
.custom_selector {color:green;}

If the .custom_selector is applied to a <div> tag, it will not change the tag selector rule so the text color will still be red instead of green.

<div class="custom_selector">
<h1>This is a heading</h1>
<p>This is a paragraphs.</p>
<p>This is another paragraphs</p>
</div>

This is a paragraph.

This is another paragraph.

NOTE: There is a four component techniques that can be used as well which include Inline style:

  1. Inline styles (this is the only one that is not a selector but an attribute)
  2. ID selectors
  3. CLASS selectors & pseudo-selectors (e.g., link, hover, active, and visited)
  4. Element (also called Type) selectors & pseudo-elements (e.g., ::before)

If you combined ID, Class, and Element together to create a compound selector, the rule of specificity can be a little tricky. To determine the specificity of a rule, each selector type is assigned a numeric value. Each selectors values are added up and place into four levels:

  • a = 1 if the style is inline
  • b = total number of ID selectors
  • c = total number of class, pseudo-class and attributes selectors
  • d = total number of element  selector or pseudo-elements selectors

  The specificity is calculated on the base 10 for simplicity:

Selector Specificity Specificity (base 10)
Style = " " 1,0,0,0 1000
#container #mainContent 0,2,0,0 200
#mainContent .profile 0,1,1,0 110
div#mainContent 0,1,0,1 101
#mainContent 0,1,0,0 100
p.warning .general 0,0,2,1 21
p.warning 0,0,1,1 11
div p 0,0,0,2 2
p 0,0,0,1 1

NOTES:

  • Inline styles will always be more specific than any other rule even though they are not recommended.
  • Highly specific selectors (e.g., IDs) are never overwritten by many less specific selectors (e.g., elements). A specificity of 0,0,2,0 is more specific than a 0,0,1,10 because the general rule of specificity takes precedent in this case because there are more classes in the first example.
  • If two rules have the same specificity, the last rule will prevail.

 See Web PlatForm Doc for more details.

TIP: Keeping selector specificity low ensures CSS rules stay flexible so that you can override styles when you need to.

  • Use class selectors for custom styles
  • Use element selection for default styles

Specificity has higher priority than the order rule and will be applied, even if the rule is at the top or bottom. (VERIFY)

EXAMPLE:

#content{color: #333}

#content p{color: #f00}

#content p em{color: #f00}

#content  p em{color: #foo}: This rule wins out because it is the most specific of the three.

EXCEPTION: When both an ID and Class selector is used, the Class selector will override an ID selector if it is the last one used. An ID selector will only take precedence over a Class selector if they are both used in the same element. (VERIFY)

The last attribute of the Cascade rule is the source order. When two selectors have the same specificity, the last declaration takes precedent.
If two declarations affect:

  • the same element
  • have the same importance and
  • the same specificity

the source order is used to determine which one “wins”. The declaration that appears last in the style sheets will “win” over those that come before it.

EXAMPLE 1:

If a single external style sheet has declarations at the end of the file, it will override those that occur earlier in the file if there’s a conflict.

The conflicting declarations could also happen in different style sheets. The order in which the style sheets are linked, included or imported controls what declaration will be applied.

EXAMPLE 2:

if two stylesheets are linked in a document head element, the one linked to further down will override the one further up.

As each page loads, the browser checks the RULES to see if a rule match. If a conflict exists, the ORDER of the RULES takes precedence. The LAST RULE takes precedence.

TIP: If you are using a CSS reset or a CSS framework, load it before custom styles.

Internal or embedded styles have the same weight as external or linked stylesheets. So, if they have the SAME rules, the order rule applies.

EXAMPLE 3:

<link rel="stylesheet"  href="stylesheet1.css">
<link rel="stylesheet" href="stylesheet2.css">

Stylesheet2 will take precedence since it is the last one listed.

EXAMPLE 3:

  • p {color:black;}
  • p.intro {color:brown;}
  • p {color:red;}

Rules #1 and #3 conflict because they are from the SAME style sheet and they have the SAME level of specificity. So, the rule of order must be made. Even though Rule #2 is more specific, Rule #3 trump it because it comes last.

Initial & inherited properties are not part of the CSS cascade; however, they do determine what happens if there are no CSS declarations targeting an element which determine the element default values.

Inherited values will cascade down from parent elements to child elements. For example, font-family & color properties are inherited. This is use so that less CSS rules can be used—this concept is called economy of code.

EXAMPLE:

body {font: 14px Helvetica;}

Setting the font property on the body element will allows all the other text to inherit the 14 px Helvetica font rule unless otherwise defined.

Every element inherits all inheritable properties from its parent.

NOTE: The html element does not have any inheritable properties because it is the top most parent element without a parent.

Rule of Inheritance

The rule of inheritance is not part of the rules of cascading; however, it play an important role on how some elements are styled.

RULE OF INHERITANCE – When elements are nested they create parent/children relationships. As in real life, children may inherit certain properties of their parents. Yet, they also have certain properties independent of their parents. Hence, children elements will inherit properties of its parent elements.

NOTE:
This rule only applies to text-related properties but not box-related.

Exception: While children can inherit properties of their parents, they can DEFINED their own or in essence REDEFINED properties of their parent.

EXAMPLE:

If you apply an inline style to the body tag, then the children tags (e.g., headings, paragraph, lists) will be blue.

<body style="color:blue">

However, if you redefined the style for <h1> element as in the example below, it will be red.

h1{color:red;}

The <h1> tag will be red even though the parent defined it as blue because it defined its own rule or another way of saying it redefined its parent rule. Notice that any other children tags will be red as well if they don't redefine their parent rule.

NOTE: This is akin to the law of gravity. If you drop a watermelon from the top of a building it will fall to the ground. However, you can "trump" the law of gravity by using another law called the law of lift. A bird or plane can fly because of the law of lift. Now, the law of gravity is still in effect; however, it is trumped by the law of lift.  Another way of saying this is that the law of lift does not do away with the law gravity or deny that it exists — it just supersede or defy the law of gravity.

MEMORY TIP: Just as a young child can change certain style attributes of its body (e.g., hair color, eye color) that was INHERITED at birth, he or she can in essence trump its INHERITED styles from its parent by DEFINING his/her own even though the parents may be stronger.

TIP: By using a methodology called economy of code, adding a style at the top level will influence elements below it. For example, adding a font-family in a body tag selector will be inherited by headings, paragraphs, lists, and table tags without having to define styles for them. It is common practice to define a rule for the body tag since it is the top-level tag. As a result, all descendant tags will inherit its text properties regardless of how far down the hierarchy it is. This will minimize the amount of CSS you may need to style a page. To help you with this process, select File > Page Properties... and the select the Appearance(CSS) from the category and make any changes you want.

body,td,th {
font-family: Gotham, "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
color: #E5282B;
}

NOTE: Using this dialog box may also set <th> and <td> tag properties as well for the <body> tag???



NOTES:

  • Many CSS properties are not inherited because they don't make sense to be inherited. Only text attributes are inherited. Properties relating to position and display of box elements (e.g., padding, borders and margins) are not inherited. (VERIFY)
  • Be careful when using relative sizes (e.g., ems and percentage).  If a text tag is styled at 80% and then its descendant styled also at 80%, the text will actually be 64%. (VERIFY)
  • Inheritance is useful by NOT having to add the same style to every descendant element. For example, instead of using:
    p, div, h1, h2, h3, h4, h5, h6, ol, ul, dl, li {color:blue;} it could be written simply as body {color:blue;} 

    SHOW EXAMPLE (See my note in Styling with CSS pg 58.)

TIP: Because font-family is an inherited property, its value is passed to all its descendants. So it is best practice to include it in the <body> tag so that it can cascade down throughout the rest of the page.  You can easily set font design by changing the font size in one location (e.g., the body) and have it scale proportional in the rest of the page based on this baseline font.   This reduces the number of font-size rules that need to be created:

EXAMPLE 1: If you set the properties of the body tag to render the font-color to be blue with the Arial font listed.

body {font-family: "Arial,Helvetica, sans-serif"; font-size:1em; font-color:blue;}

ALL decendents tags (e.g., <p>, <h1>, <h2>, <h3>, etc.) will be displayed in Arial with a blue font.

EXAMPLE 2: Another approach is to set the font size in the <body> element as a relative unit of measurement (e.g., % or ems) as a base font.

Once the baseline font is set in the <body> element, other decendent element fonts can be set from this reference:

h1 {font-size: .8em;}
p {font-size: .8em;}
ul, ol {font-size: .75em;}

TIP: It is best practice when setting font-size using CSS to set:

  • the base font-size to 100% or 1em
  • the headings larger than 100% or a larger em value (e.g., h1:140%, h2:130%, h3:120%, etc.)
  • the paragraphs and other text objects to less than 100% or a smaller em value (e.g., p:85%)

REVIEW INFO BELOW AND ADD OR DELECT CONTENT (MAY HAVE TO DELETE THIS SELECTION?????)

NOTE: Most browsers have a default size of 1 em (16px).
NOTE
: Notice that the <li> tag was NOT set in the previous example because it inherits the same font size as its parent (e.g., ul and ol).  Also, because the <li> tags are nesting inside of a list (ordered/unordered), the result of nesting would result in a less than expected size:

For example, if the <ul> tag is set to 0.75 ems and the <li> tag is set to 0.7 ems the result would be 0.525 ems ( 0.7 x 0.75 ).

  • item 1
  • item 2
  • item 3

(REVEIW AGAIN -- PG 80 OF STYLING WITH CSS) To prevent this problem from occurring, use a contextual selector to target an element in the list. (e.g., ul a {font-size: inherit) so that the <li> tags can "inherit" the size for the <ul> or <ol> tag.

  • item 1
  • item 2
  • item 3

EXAMPLE 3: If you set the font color in the <body> element, all text elements inside of the <body> element will inherit that color unless they define their own.

Inheritance has the lowest priority among styling methods.

EXAMPLE 4: If a child element has a rule that is specific to it, then the inherited value will be ignored, even if the inherited value has an important keyword. This goes back to the statement, “Children will inherit properties of their parents unless they defined their own.”

<style>
child_rule {color:blue;}
</style>
<div style="color:  red !important;">
<div class="child_rule">This text is blue even though its parent specified its color rule to be red with an important keyword. </div> </div>

EXCEPTIONS: There are some cases where the child selector does not inherit the parent selector's values for obvious reasons. For example:

  • The margin property is not inherited
  • A paragraph would not have the same top margin as the document body

Styles that are not inherited are usually related to elements appearance. For example, it does not make sense that the child element has the same margin as its parent.

For non-inherited properties (e.g., background-color, border, margins, width), each element has a set of initial values that are defined in the CSS specification for a given rule. For example, if no CSS declaration is given for background-color, it will default to transparent. Ask yourself if it make sense for a particular property to be inherited or go to JavaScript Kit.

Controlling Inheritance

Every CSS property has four special universal property values for controlling inheritance:

  • Inherit - sets the property value applied to a selected element to be the same as that of its parent element. Effectively, this "turns on inheritance".
  • Initial - sets the property value applied to a selected element to be the same as the value set for that element in the browser's default style sheet. If no value is set by the browser's default style sheet and the property is naturally inherited, then the property value is set to inherit instead.
  • Unset - resets the property to its natural value, which means that if the property is naturally inherited it acts like inherit, otherwise it acts like initial.
  • Revert – Set ….  This is a newer property with limited browser support.

EXAMPLE:

body {color:green;}
.inherit_demo a {color:inherit;}
.initial_demo a {color:initial;}
.unset_demo a {color:unset;}

<ul>
<li>Default <a href="#">link</a> color</li>
<li class="inherit_demo">Inherit the <a href="#">link</a> color</li>
<li class="initial_demo">Reset the <a href="#">link</a> color</li>
<li class="unset_demo">Unset the <a href="#">link</a> color</li>
</ul>

RESULTS:

The rules of cascading are the most difficult concepts to understand with dealing with CSS. However, knowing how they work together will help you write great code. For example, some users like to resort to using the !important annotation instead of use a higher specificity selector.

Understanding concepts that relate to CSS will allow a user to write fewer CSS rules.

Only CSS declarations, that is property/value pairs, participate in the cascade. This means that at-rules containing entities other than declarations, such as a @font-face rule containing descriptors, don't participate in the cascade. In these cases, only the at-rule as a whole participates in the cascade: here, the @font-face identified by its font-family descriptor. If several @font-face rules with the same descriptor are defined, only the most appropriate @font-face, as a whole, is considered.

While the declarations contained in most at-rules — such as those in @media, @document, or @supports — participate in the cascade, declarations contained in @keyframes don't. As with @font-face, only the at-rule as a whole is selected via the cascade algorithm.

Finally, note that @import and @charset obey specific algorithms and aren't affected by the cascade algorithm.