CSS Inheritance: An Introduction

Asha Laxmi
Share

It’s common to see inheritance in action in real life. Unless some other factor comes into play, it’s often the case that tall parents have tall children, and so on. We can see something similar in CSS.

CSS Inheritance - Inherit the Kingdom

If you set the color on a container element to green, then unless some rule overrides that color value, the color of all the elements inside the container will be green. The mechanism through which the value of certain properties is passed on from parent elements to child elements is called inheritance.

In this article, you will learn about different aspects of inheritance and how it affects the appearance of different elements.

How is CSS Inheritance Useful?

CSS Inheritance greatly reduces the time and effort required to create a website. Imagine how much CSS you would have to write to set the color on all children of the body tag. This would be time consuming, error prone, and difficult to maintain. Similarly, you can imagine what a nightmare it would be if you were forced to set the font-family or font-size on every child element of a container.

Look at the following demo:

See the Pen CSS Inheritance example by SitePoint (@SitePoint) on CodePen.

Here I’ve defined the font-family, font-size, and line-height properties on the body element but all these values are inherited by different elements nested inside body. This brings uniformity to the layout without the need to repeat the same properties on multiple elements.

Only Certain Properties are Inherited

In real life, not all attributes of parents are passed on to their children. The same is true in CSS; not every CSS property is inherited by default by child elements. In fact, if all properties were inherited, the effect would be similar to having no inheritance at all and you would have to write a lot of CSS to override this behavior.

As an example, if the border property was inheritable, setting a border on a single element would cause the same border to appear on all its child elements. Similarly, if children inherited the background-image property from their parents, the result would be messy. The following CodePen example demonstrates how this sort of thing would look using a CSS keyword value that I’ll discuss in the next section:

See the Pen How Borders Would Work if they Inherited by Default by SitePoint (@SitePoint) on CodePen.

Forcing Inheritance

Generally speaking, whether or not to make a property inheritable comes down to common sense. For example, in addition to the examples discussed in the previous section, you probably don’t want all the children of an element to inherit the padding value of their parent. However, you would often prefer if the color of text or the font used for different child elements of a container was the same.

In some cases, a specific property may not be inheritable but you might still want it to be inherited from the parent element. This can be achieved by setting the value of that property to inherit for the child element:

.some-child {
  color: inherit;
}

Let’s say you want the color of all link elements on your website to be the same as the color defined on their parent element. There are a couple of ways to do this. You could use different classes for links and container elements with different colors, for example. However, one of the cleanest ways to do this is by using the inherit keyword.

Once the color property of the link elements is set to inherit, they will start inheriting the color of their parents:

p {
  color: #f44336;
}

ul {
  color: #3f51B5;
}

a {
  color: inherit;
}

Here’s the demo:

See the Pen Using the `inherit` keyword to force inheritance by SitePoint (@SitePoint) on CodePen.

Inheritance Using CSS Shorthand

A special feature of the inherit keyword is that when you apply it to a shorthand property it will apply to all sub-properties, even ones you may not realize at first are being forced to inherit. Also, with shorthand you can’t specify that a single sub-property will inherit a value.

As an example, you might expect the following CSS to apply a solid border of 1px width whose color is inherited from the parent element. However, the declaration is actually invalid:

.example {
  /* Invalid CSS */
  border: 1px solid inherit;
}

Similarly, you cannot use shorthand properties to set margins or padding to a specific value on one side and to an inherited value on the other side. This again will make the declaration invalid:

.example {
  /* Invalid CSS */
  margin: 10px inherit 20px 15px;
}

One solution to this problem is to set the property that you want to inherit to some arbitrary value and then use inherit with the corresponding longhand property:

.example {
  margin : 10px 0 20px 15px;
  margin-right: inherit;
}

Missing Shorthand Values

When writing shorthand, any missing sub-property whose value has not been provided explicitly will be set to its initial (or default) value. Consider the following CSS:

.container-a {
  font: italic 1.2em/1.75 Lato;
}

.container-a p {
  font: bold 1em Lato;
}

Here, the paragraph text won’t inherit the value of font-style from its container. The font-style value will actually be reset to its initial value of normal. Therefore, in this case, if you want the parent font shorthand to be inherited while still making sure that the paragraph remains bold, you will have to use the longhand font-weight property.

See the Pen CSS Inheritance and Shorthand by SitePoint (@SitePoint) on CodePen.

Using DevTools to See Inherited Values

DevTools can be used to view properties that an element inherits from its parent or from another element up the DOM tree. As already mentioned, not all properties of a parent element are inheritable. Neither do all the inheritable properties make it to the end of the inheritance chain without being overridden by another CSS rule somewhere else.

DevTools gives you different visual cues to easily distinguish between all such properties, which you can see in the screenshot below, taken from SitePoint’s CSS:

Viewing CSS inheritance in DevTools

Any properties that are not inheritable by the selected element are dimmed. Properties that were inheritable but were overridden are displayed with strike-through text.

List of CSS Properties that are Inherited

There doesn’t seem to be a single definitive source that lists all CSS properties that inherit, but below is a list that’s probably correct, based on a few sources:

  • border-collapse
  • border-spacing
  • caption-side
  • color
  • cursor
  • direction
  • empty-cells
  • font-family
  • font-size
  • font-style
  • font-variant
  • font-weight
  • font-size-adjust
  • font-stretch
  • font
  • letter-spacing
  • line-height
  • list-style-image
  • list-style-position
  • list-style-type
  • list-style
  • orphans
  • quotes
  • tab-size
  • text-align
  • text-align-last
  • text-decoration-color
  • text-indent
  • text-justify
  • text-shadow
  • text-transform
  • visibility
  • white-space
  • widows
  • word-break
  • word-spacing
  • word-wrap

There are also a number of speech-related CSS properties that are inherited and that are not included in the list above.

Here are a few sources for inherited property lists:

You can also view info on an individual CSS property in the spec, or in any comprehensive CSS reference, and it will usually tell you if that property is inherited by default.

Conclusion

To summarize what I’ve discussed: inheritance allows you to avoid writing duplicated CSS rules to apply the same set of properties to all the descendants of an element. It greatly simplifies the process of adding styles to web pages and therefore is an excellent feature of CSS.

CSS also allows you to use the inherit keyword to force inheritance on properties that are not inherited by default. DevTools provide you easy access to all the properties that an element inherits from its ancestors. This can help you in quickly figuring out solutions to common layout related problems.