In CSS, Differencebetween Cascading and Inheritance

In CSS, what is the difference between cascading and inheritance?

Inheritance is about how properties trickle down from an element to its children. Certain properties, like font-family inherit. If you set a font-family on the body, that font family will be inherited by all the elements within the body. The same is true for color, but it is not true for background or height which will always default to transparent and auto. In most cases this just makes sense. Why would the background inherit? That would be a pain. What if fonts didn't inherit? What would that even look like?

The cascade is about what take precedence when there is a conflict. The rules of the cascade include:

  1. Later properties override earlier properties
  2. More specific selectors override less specific selectors
  3. Specified properties override inherited properties

And so on. The cascade solves any conflict situations. It is the order in which properties are applied.


(update) Specificity is the calculation used to determine selector priority in the cascade. When two selectors apply to the same element, the one with higher specificity takes precedence.

  1. Inline styles have a very high specificity (1000)
  2. ID's have a specificity of 100
  3. classes/attributes and pseudo-classes add 10
  4. elements and pseudo-elements add 1

Add up all the parts in a selector chain to determine the total specificity. In case of a tie, the last selector takes precedence.

Of course, that comes with various edge-cases and caveats. One class will always override plain elements, no matter how many. More targeted selectors are given priority over inherited properties from parent selectors. And you can throw out all your calculations if someone used !important — that trumps everything.

CSS cascading with examples

When only considering "author" stylesheets (not user or user agent), then what you are probably confused about is not so much the "cascade", but the "specificity" rules for CSS.

Here are some good explanations of how specificity works and how to figure out why certain rules are applied to your elements:

http://coding.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/

http://css-tricks.com/specifics-on-css-specificity/

EDIT: The cascade:
All applicable rules for an element are gathered, then ordered according to their origin (higher number means higher precedence):

  1. user agent declarations
  2. user normal declarations
  3. author normal declarations
  4. author important declarations
  5. user important declarations

Specificity is used as a tie-breaker if the origin is the same. Finally, if specificity is the same, then declaration order is the final tie-breaker. Hopefully this is understandable without a tedious example...

Confusion between inheritance and specificity in CSS

Every CSS rule only applies to the subject of its selector.

For p { ... } the subject is all p elements

For #mainContent p { ... } the subject is all p elements which are inside the element with id mainContent.

if a p element is inside the element with id mainContent, the #mainContent p { ... } rule wins because it is a more specific rule.

The strong element is not the subject of either rule, so neither applies directly.

In the example, the strong element is the subject of the .green { ... } rule. So that is the rule that applies to that element.

So where does inheritance come in?

Inheritance of a property to an element can happen in one of two ways.

First, there can be an explicit rule whose subject is the element and the property setting is inherit. So strong { color:inherit; } will, if it is the highest priority rule with the color property in the cascade for a strong element, force the color of that element to be taken from that of its parent.

Alternatively, if there is no rule anywhere in the cascade for which a given strong element has a particular property defined, that element will take a default value. Some properties are defined as "inherited" and others are not. The color property is defined as inherited.

So, in this alternative case, only when that there is no rule whose subject is a given element and has a color property, does the color of that given element get inherited from the color of the containing element.

In your example. there are multiple rules for which the p element is the subject and the color element is defined, so no inheritance is effective on that.

What is the cascading module used for? Why it's called cascade ?

"Cascading" in this context means that because more than one stylesheet declaration could apply to a particular piece of HTML, there has to be a known way of determining which specific stylesheet rule applies to which piece of HTML.

The rule used is chosen by cascading down from the more general declarations to the specific rule required. The most specific declaration is chosen.

Read the official W3C specification on cascading here: https://www.w3.org/TR/css-cascade-4/

What's the difference between CSS inherit and initial?

The initial value given in the summary of the definition of each CSS property has different meaning for inherited and non-inherited properties.

For inherited properties, the initial value is used, for the root element only, when no value is specified for the element.

For non-inherited properties the initial value is used, for any element, when no value is specified for the element.

An initial keyword is being added in CSS3 to allow authors to explicitly specify this initial value.

The inherit keyword means use whatever value is assigned to my parent.

Source : https://developer.mozilla.org/en-US/docs/Web/CSS/initial_value

Is there a difference between CSS custom properties and CSS variables?

A CSS Custom Property is the same thing as a CSS Variable. But that seems to come of some clumsy naming.

They weren't wrong to title the page: Using CSS custom properties (variables)

However a CSS Variable is not a variable in the traditional sense, as there is no way to define it so that it is globally scoped like in a programming language, or CSS Preprocessor (LESS/Sass).

Even a root scoped custom property/variable is not global. Changing the value of a property in a child will not change the value above or for siblings of that scope. If someone is expecting to be global, it may cause confusion and I suspect that's what Mozilla's writers are trying to point out.

if you look at

w3.org's CSS Custom Properties for Cascading Variables

This module introduces a family of custom author-defined properties known collectively as custom properties

Custom properties are definitions that can be referenced using var(--my-custom-prop). Like a variable!

quote continued...

as one only has to change the value once, in the custom property, and the change will propagate to all uses of that variable automatically.

Awkward... The above statement is not true exactly. It seems Mozilla Developer Network documentation is trying clarify that idea so that it's less confusing. Repeating the original quote:

Keep in mind that these are custom properties, not actual CSS variables. The value is computed where it is needed, not stored for use in other rules. For instance, you cannot set a property for an element and expect to retrieve it in a sibling's descendant's rule. The property is only set for the matching selector and its descendants, like any normal CSS.

They're pointing out it's not a variable in the traditional sense of a programming language. But that it is computed just like styles, adhering to the general cascade/scoping rules of CSS.

Thus var(--my-custom-prop) could resolve to very different things based on where it is declared, and that declarations don't propagate out to a higher scope.

Here's a codepen to mess around with if you'd like to try it out.

So think of CSS Custom Property the same as CSS Variable but be sure to remember that values cascade, and there's no global scope.

What's the difference between `all: unset` and `all: revert'

From the MDN:

The unset CSS keyword resets a property to its inherited value if it inherits from its parent, and to its initial value if not. In other words, it behaves like the inherit keyword in the first case, and like the initial keyword in the second case.

So unset is either inherit or initial

The revert CSS keyword reverts the cascaded value of the property from its current value to the value the property would have had if no changes had been made by the current style origin to the current element. Thus, it resets the property to its inherited value if it inherits from its parent or to the default value established by the user agent's stylesheet (or by user styles, if any exist).

Suppose the browser apply a default style to your element. Using revert, you will put back those styles while unset will not.

Example:

p {  margin: 50px;}
<p style="margin:revert">  some text here</p><p style="margin:unset">  some text here</p>

Why don't CSS media queries follow the normal conventions of inheritance and cascade?

Firstly thanks @BoltClock (for both comments), and to the other comments and answers for all your help.

I think I made a mistake in my media queries and/or was miss-understanding how they worked and interacted together. I was going to edit my question with the following but decided it would make more sense as an answer (since it's the solution I used). I apologise if this has wasted anyone else's time.

Here's my fixed snippet of code:

@media only screen 
and (max-width : 480px) {
.page { min-width: 300px; max-width: 480px; width: 100%; }
.page .alpha { font-size: 2em; }

/* Set-up the column */
.page .column { margin: 0 auto 2%; width: auto; }
.page .gallery .column { min-height: 470px; height: auto; padding: 2%; }
}
/* Increase the main title for slightly larger screens! */
@media only screen
and (min-width : 421px)
and (max-width : 480px) {
.page .alpha { font-size: 3em; }
}

I realised from your comments that if I increased the max-width in my first block to cover the necessary range/limit I could then either nest or add the second block after it (I tried both and they both worked for me -- using chromium browser [18.0.1025.151]). This successfully gave me the desired result, in that the page .alpha element's font size increased at the required stepping/interval.

Thanks again for all SO'ers who helped!
(and to SE for the awesome communities they've helped build)

Knowledge > OpenSource > Freedom



Related Topics



Leave a reply



Submit