css-inheritance

Have you ever gone too deep into creating CSS classes and nested selectors and assigned a large number of properties to each and every level of your rule?

Chances are yes you have done it. Or maybe you are still doing it.

Using too specific style for everything. This hugely depends on the nature of the task you're doing. But no matter what kind of task it is, There is always some redundancy that we can remove and optimize the way we use selectors using inheritance when needed.

CSS inheritance is a default functionality for some properties in the CSS cascading system. The child will always inherit computed values from the properties of their parent. Not all the properties are inherited. There is a list of properties that will get inherited values automatically. Others will get Initial value.

How CSS inheritance works:

When no property is specified for the rule of the element. Properties can be grouped into two categories when not defined. Inherited and Non-inherited.

CSS inheritance rules:

  • The child will inherit the properties of the parent only if the property type is Inherited Properties.
  • Use Inherit keyword to enable inheritance in any Non-Inherited properties.

Commonly used Inherited Properties:

  • font
  • color
  • direction
  • letter-spacing
  • word-spacing
  • white-space
  • text-align
  • text-indent
  • text-shadow
  • text-transform
  • list
  • border-collapse
  • border-spacing
  • visibility
  • cursor

Full list on W3

The above list of properties inherits the computed values from its parent. The below demo shows color, font, and text properties.

.parent{
font: normal small-caps 16px/30px "monospace";
color:#000;
letter-spacing:-1px;
text-align:center;
text-indent:0;
text-shadow:1px 1px 0px #f36;
cursor:e-resize;
}

Click on each text element to see an example of inherited properties in the box model.

The elements have the following properties:

  • Parent: margin, padding, border,color,letter-spacing, word-spacing, text-align, text-shadow, cursor
  • Child1, Child 2, Child 3: gets letter-spacing, word-spacing, text-align, text-shadow, cursor properties from the parent.

In the above demo, we have inherited property from the parent. Useful for alignment and text content styling. Structural properties are not inherited by default. Parent 1 has many layout properties but child 1 or child 2 don't get those properties. Only Inherited properties like font, text, color are passed to the child whereas other properties are limited to the element itself by default.

Commonly used non-Inherited Properties:

  • float
  • position
  • left
  • right
  • top
  • bottom
  • z-index
  • display
  • width
  • max-width
  • min-width
  • height
  • max-height
  • min-height
  • margin
  • padding
  • border
  • background
  • overflow
  • text-overflow
  • vertical-align

Full list on W3C

In the below inheritance example, we are using background, border, margin, padding, position properties on the parent.

.parent{
position:relative;
left:10px;
right:10px;
top:10px;
bottom:10px;
margin:5px;
background:#e06daa;
border:3px solid #000;
}

You can click on each element to see the box model in action.

The elements have the following non-inherited properties to inspect:

  • Parent: border, background
  • Child1, Child2, Child3 : no border, no background

Clearly, child elements of these properties don't inherit values by default. We have to explicitly specify if we want to inherit any property that is non-inherited by default. We are using position properties like top, bottom, left, right, margin, borders, background but they won't be applicable to their child by default. This is the default behavior of non-inherent properties.

If you haven't noticed borders and background color in the current example, Click and see what happens with borders and backgrounds, because we're going to make it inherit up next.

How to force Inheritance on non-inherited properties:

CSS is carefully made by experts so all the property that inherits parent values by default is useful. But If you want to do the same for non-inherited properties, you can do it with an inherent value of the property. Using Inherit on the properties like margins, paddings, or any of position properties can create chaos.

.parent{
...
}
.child{
background: inherit;
border: inherit;
}

Example of inherited value on background and border:

Click outside the box to get default property values in the box model. If you click inside the parent 1 or any of the element inside elements, visually nothing will happen. That's because all the element side parent 1 inherits some non-inherited properties.

Properties to inspect are margin, padding, background:

  • Parent: margin, background, border
  • Child 1, Child 2, Child 3: background, border

In the above example, we are using the same demo from non-inherited properties with few changes.

We can use * modifier to give every child of parent inherited properties of the border and background color. We have to specify property names individually to get inherited properties working. We can use "all" property to make every property inherit parent properties. { all:inherit;}

.child{
background: inherit;
border: inherit;
margin: inherit;
...
}

Font family and colors are already inherited so we don't need to specify inheritance for those properties. We can easily override any of the properties. I have a separate article explaining how CSS overriding works.

Why inheritance is useful

Imagine, If you have to type CSS for every single element you use in an element, You end up creating a CSS file that is larger than the page itself. So many CSS properties would become repetitive and redundant. But luckily CSS inherits parent properties so we can select our elements more efficiently.

Inheritance Example With FontFamily and Color:

Here is an example of how we can take advantage of inherited properties. In the below example, we assigned the font family to the body. So we don't need to assign it again. The entire HTML will get its inherited value. We created a parent container div and assigned background and a tomato color properties.

Notice how all the text inside the immediate and nested child is turned tomato color. Each div in the example is nested to its parent. So in #3 parent, we assigned a text-transform to the div. That made its children text uppercase. This element inherits inheritable properties from its parent.

Going down in the hierarchy, #7 is having new property added to its list that is font-weight, Now, its descendants will have all properties inherited from their parent. We also used a font-modifier class to manipulate the font family on #7 and all its descendants.

Font inheritance is a widely used technique to create themes. It's easier to change site-wide font family and colors. Very useful when overriding color schemes and font families.

Inheritance Example With Form Elements:

Most of the CSS framework uses BEM or block element modifier method to do the styling. Bootstrap is also using a modifier to manipulate its UI colors and other properties. The technique doesn't use any parent-child inheritance because some properties don't inherit the style by default.

It's easy to maintain big projects using this method, but this becomes redundant if we're building a small project.

Suppose we have a master button that has all the characteristics of the button defined in one class and overridden property using a modifier class, The code would look something like this.


.btn {
color: #000;
background: tomato;
padding: 10px;
border: 3px solid darkslategrey;
margin-bottom: 10px;
}
.btn-primary {
color: #fff;
background: purple;
padding: 10px;
}
.btn-upper {
text-transform: uppercase;
}
.btn-rounded {
border-radius: 20px;
}
.btn-pinnkborder {
border-color: pink;
}

The problem with this method is we have to supply multiple class names every time we need styling. If we use multiple modifiers on the same element, It world look something like this:

 <button class="btn btn-primary btn-upper btn-rounded btn-pinnkborder">I am a button</button>

Look at the modifiers we have used to make button specific, If you have to create 10 buttons, It's too much code. Not really an optimal way to do it for small projects.

We can use a combination of properties and inheritance to manipulate the element using CSS.

Simple inheritance can solve this problem by moving master styles to attribute selectors and a single class can do the trick. In the below example we used attribute selectors for parent and no class to use inherited properties from the parent as a modifier for the button.

html,body{padding:1px; text-align: center; font-family: Arial, Helvetica, sans-serif; color:blue; font-size: 16px; line-height: 2;}

[class*="btn"] button{color:#000; background: tomato; padding:10px; border:3px solid darkslategrey; margin-bottom: 10px;}

[class*="-primary"] button{color:#fff; background: purple; padding:10px; }

[class*="-upper"] button{text-transform: uppercase;}

[class*="-rounded"] button{border-radius: 20px;}

[class*="-pinnkborder"] button{border-color: pink;}

And button syntax will look like this

<button class="btn-primary-upper-rounded">I am a button</button>

See how using inherited properties from parents can reduce the amount of code? If you want to know how we can use a CSS Selector, Checkout my article on How to select anything with CSS

Inheritance Example With Media Queries:

Consider a case when you are using a dark mode color schema on your system and you want to take advantage of a media preferred-scheme.

if we have used inheritance correctly. We can change the style of the entire website just by adding a couple of lines to the media query.

In the below example, We have used a class to manipulate site-wide color schemes. Just because it’s easy to demonstrate than changing the color scheme of your system or mobile. Click anywhere to see the color scheme changes.

The demo uses inherited properties on non-inherited properties like background and opacity to make this transition.

CSS inheritance needs to be used only when there is a problem with code redundancy. Like everything else in the world inheritance does have some advantages when used correctly and disadvantages when overused or misused. There is a method called CSS Overriding which can easily change CSS property values.

Pros
  • Can help establish basic code with fewer lines
  • Quickly alter the style of all the elements and child of the patent
  • Easy to manage media queries because of property dependency on the parent
Cons
  • If overused, can cause problems in the layout.
  • Not good for module-based CSS

Final Thoughts:

CSS inheritance is not a huge addition to the cascading nature of CSS. Many of the times it’s ignorable. But it does have the potential to optimize the way you write CSS and the way you use selectors. If there is a better way to do anything it's not best practice to go a complex route just to style a single element. Instead, let inheritance do the job for you to make your code less redundant.

Leave a Reply

Your email address will not be published. Required fields are marked *