Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Inheritance: Friend and Foe


WebReview.com: Inheritance: Friend And Foe

One of the most fundamental aspects of Cascading Style Sheets (CSS) is the concept of inheritance. This refers to the way in which a style is passed from an element to its children, so that styles appear to be consistent. This mechanism is indispensible, but it can also be a source of confusion and annoyance-especially if you aren't careful. We'll take a quick look at how inheritance works, and why some properties are inherited while others are not. Then we'll touch on a few ways in which inheritance can actually be an obstacle, albeit one which is easily overcome.

The basics

First, a quick review of the terms we'll be using. A child element is an element which is part of another, and a parent element is an element which has children. For example, given the markup in Figure 1, the <p> element is a child of the <body> element, and the <a> and <em> elements are children of the paragraph. Conversely, the paragraph is the parent to the <a> and <em> elements, and the <body> is the parent of the paragraph.

<p>
This paragraph contains <em>emphasized text</em> and 
a hyperlink created with<a href="http://style.webreview.com/">
an anchor tag</a>.
</p>

<em>Figure 1. Example markup.</em>

Inheritance, then, is the process by which a style is passed from a parent to a child. For example, if you define a paragraph to be purple in color, then it stands to reason that the text in the paragraph should all be purple. It wouldn't look right if plain text was purple, and <em> text in the middle of that paragraph was not purple. However, without inheritance, that's exactly what you'd have. Since color is an inherited property, its values are passed from a parent element to its children. Figure 2 shows the difference between the two possibilities-the first way is the correct way, and the second is a hypothetical screenshot from an evil parallel universe where CSS has no inheritance.

Figure 2.  Text color with and without inheritance
Figure 2. Text color with and without inheritance.

All right, so we know how inheritance works. Not all properties are inherited, however. For example, most of the box properties (margins, padding, and borders) are not inherited. This makes sense, since if they were, elements inside an element with a border would themselves have borders. Figure 3 shows the difference; again, the first image shows the right way, and the second is the wrong way.

Figure 3.  Borders with and without inheritance

Figure 3. Borders with and without inheritance.

(For a complete list of CSS1 properties which are not inherited, see the table at the end of this article.)

Oops! Inheritance!

Great stuff, right? How could inheritance possibly be bad?

As it happens, there are circumstances in which inheritance can be a little confusing. It isn't really bad, of course, but it can bite you in unexpected ways. One way is when a style is inherited when you don't expect it.

A few months back, I got e-mail from a developer who had a big problem: His boldface tags were working fine in one browser, but not the other. His markup was clean, there was nothing wrong with the tags, and the styles all checked out as correct. There was no apparent reason why the boldface refused to work in one browser. So he asked me to take a look.

It took me a few minutes, but eventually I figured it out:

BODY {font-weight: normal;}

What was happening was that in one browser, the weight value of normal was inheriting into the <b> tag, thus suppressing the boldface style. The fix was simple enough:

BODY {font-weight: normal;}
B {font-weight: bold;}

That was all it took. This works because inheritance always loses to a direct style assignment. If an element (such as <b>) inherits a value (such as font-weight: normal), but has a more direct rule associated with it (see above), then the assigned rule overrides whatever value was inherited.

Let's take that a step further. Remember the "wrong" example in Figure 1? Let's assume that you actually want your paragraph to look like that, with the <em> and other elements in black, not purple. In order to do that, you would need the following styles:

P {color: purple;}
EM, STRONG {color: black;}

Figure 4. Overriding inheritance
Figure 4. Overriding inheritance.

Instead of inheriting the value purple, the <em> and <strong> element use the declared value of black instead.

Inheritance tax

Now, let's go back to the boldface problem. It doesn't really make sense that a browser would inherit a style into an element which would override its usual behavior, right?

As usual-yes and no. From a CSS point of view, elements don't have "usual behavior." They only have whatever styles are specified. The reason that the browser overrides the font weight of the <b> element is that it doesn't have a predefined CSS rule regarding the weight of that particular element.

This isn't really a good thing, obviously. There are some elements which should have a small set of pre-defined styles. <b> is one of them, as we've seen. On the other hand, there is such a thing as taking it too far. Inheritance into tables is one area of possible trouble.

As you may know, some styles just won't inherit into tables. For example, try creating a document in which the color for the body is green and monospace, and inside that document, include a table with some text in it. Now, load that file into Explorer 4.x for Windows, or Navigator 4.x on any platform. Odds are, you'll see green body text, but black text in another type of font inside the table.

This could be written off as a simple breakdown in the chain of inheritance, and that could well be the case. But another explanation is that the browser already has a predefined style for the color of the text, and at least one or two developers have told me that this is the case. In fact, some browsers appear to have preset styles for the font, size, and color of text inside tables.

This is a major problem, because your styles combined with the browser's built-in styles could come out something like this, assuming your browser's preferences are set to use black serif text for document display:

BODY {color: green; font-family: monospace;}
TABLE {color: black; font-family: serif;}

The best fix would be for browsers to not assign these kinds of styles to tables. Failing that, however, you can beat the problem like this:

BODY, TABLE, TH, TD {color: green; font-family: monospace;}

Now, you have specific styles which will override the browser's built-in styles, and text inside of tables will be consistent with the text in the rest of your document.

Trickling down

Despite the problems one can encounter, we're definitely a lot better off with inheritance than without it. Over time, we can hope that browsers become more intelligent about how their built-in styles should be written, and we all can worry a little less about trying to cover every last detail of the document's appearance.

On the other hand, this is a good lesson to learn: The less you assume about how a document will be displayed, and the more comprehensive your styles are, the less likely you'll be to trip over problems like those explained in this article. Just because you think the <strong> element should be boldfaced, that doesn't necessarily make it so. If you really think that it should be boldfaced in your documents, then make sure you declare that in your style sheets. Otherwise, a browser might come along with different assumptions, and people using that browser won't see any boldfaced text at all.

Figure 5. CSS1 properties which are NOT inherited.

background-color
background-image
background-repeat
background-attachment
background-position
background
text-decoration
vertical-align
margin-top
margin-right
margin-bottom
margin-left
margin
padding-top
padding-right
padding-bottom
padding-left
padding
border-top-width
border-right-width
border-bottom-width
border-left-width
border-width
border-color
border-style
border-top
border-right
border-bottom
border-left
border
width
height
float
clear
display

Previously in Sense of Style

Styling Buttons
Who Owns the Patent to Style Sheets?


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.