Being Aware of Initial Values in Your CSS

on | 3 Comments

In CSS, every property has what’s referred to as an initial value. Sometimes this is called the default value, but the spec uses the term initial, which I think is a slightly better term.

Technically speaking, the initial value of any given property needs to be declared only if that value is overriding a previously-defined value that’s not the initial value. But initial values are often present even when they’re not necessary.

For example, suppose I have a block-level element that I want to take up the full width of its parent. I want it to sit on its own “line”, so to speak, in the layout, so I add the following CSS:

.element {
  float: none;
  width: auto;
}

That’s cool, right? It’s not going to float (thus it’s going to drop to the next line, rather than bump horizontally against other elements). Also, it’s not constrained by a width value so the width is automatically calculated based on the width of the parent.

If you’re an experienced CSS developer, or even fairly new to CSS, you can probably see right away what’s wrong with the code above. It’s superfluous. It’s not erroneous code; it’s just not necessary for a block-level element. Every block-level element that doesn’t have a float value defined is automatically set to float: none because none is the initial value for the float property. The same is true for width: auto, so neither of those lines is needed.

Sometimes Initial Values are Necessary

But what if you come across CSS like the above in your code or in code that you’ve inherited. There could be one of a few things going on here:

  • The CSS in question is overriding something earlier in the stylesheet (e.g. print styles overriding screen)
  • That particular class name is added to the document via JavaScript which likewise overrides something elsewhere (it could also be an HTML element added with that class name applied)
  • The code author is being really explicit about what’s happening in the code (either intentionally or in ignorance)

There might be another scenario at work here that I haven’t thought of, but that more or less covers most, if not all, possibilities.

The following is an example of the first scenario that I listed above:

@media print {
  .column, aside {
    float: none;
  }
}

Due to this being inside a media query, that one would be fairly easy to spot as to its purpose (thus you’re not going to suspect it’s superfluous and remove it), whereas the following would be a little trickier:

h2 {
  background-color: #444;
  color: white;
  padding: 7px;
}

/* ...hundreds of lines of code here... */

aside h2 {
  background: none;
  color: #444;
}

Here the background is set to none to override the background color previously set on the same element. These style rules aren’t necessarily going to appear one after the other to allow you to figure out what’s happening. When scanning the CSS, you might just see the background: none declaration and wonder if it’s necessary since <h2> elements don’t have backgrounds by default.

(I should note here that none is not the initial value for the background property. background is shorthand, so it has no single initial value. However, none is the initial value for the background-image property. And, as you might know, usually when you write one or more values in a shorthand declaration, all the other shorthand values are reverted to their initial state. In the case above, the background-color property would be set to transparent, so the result is what’s desired.)

Using Browser Developer Tools to Find Initial Overrides

If you’re working in your CSS while viewing the live page that the CSS in question is dealing with, then it’s not difficult to see what’s happening should you come across a CSS value declared explicitly to its initial state.

Here’s what you would see in Chrome’s DevTools if you had the aside h2 example from the previous section:

Viewing CSS overrides in Chrome's DevTools

The DevTools make it abundantly clear that the background: none value is not unnecessary. All browser developer tools will do the same and this is the kind of thing that makes these tools so helpful in tracking down CSS issues.

Being Explicit in Your CSS

You’ll notice that I gave a third option for why you might find initial values declared in stylesheets: The code author is being really explicit about what’s happening in the code (either intentionally or in ignorance).

I don’t necessarily agree with adding initial values for this reason, but I also wouldn’t necessarily say it’s bad code. A perfect example of this is CSS for relatively new technologies that might be copied and pasted from online tutorials or that are relatively unfamiliar to the person writing the code.

For example, when reading tutorials on new-ish CSS features like flexbox, you might see code that looks like this:

.container {
  display: flex;
  flex-wrap: nowrap;
  flex-direction: row;
  order: 0;
  border: solid 1px #444;
}

.container div {
  justify-content: flex-start;
  align-content: stretch;
  align-items: flex-start;
  padding: 10px;
}

I’ve exaggerated my point in the above example, but certain online code examples bear some similarity to that. If you’re new to flexbox, then you probably don’t see a lot of problems with the code. But guess what? The following is equivalent to the above (assuming no other CSS is applied to those elements):

.container {
  display: flex;
  border: solid 1px #444;;
}

.container div {
  padding: 10px;
}

Six of the seven flexbox-related properties that I included in the previous example were removed because they were all set to their initial values, so those lines were superfluous.

In this case, I don’t mind including those extra lines because it can be educational to see some of the potential flexbox properties available, along with a few of the values. So this is a case where the code is being explicit with some benefit to code scanning. After all, although it’s clear in the stripped-down version that the .container element is a flex container, it might not be immediately clear that the nested div elements with the 10px padding are flex items.

Indicating Initial Values in Comments

So if we take a more realistic example that uses some explicitness with initial values, I think something like the following might be helpful:

.container {
  display: flex;
  flex-wrap: nowrap; /* initial value */
  border: solid 1px #444;
}

.container div {
  align-content: stretch; /* initial value */
  align-items: flex-start; /* initial value */
  padding: 10px;
}

In the example above, there are only three superfluous lines (more realistic than six) and each of them is commented to indicate that the code author is aware of this but prefers the lines to stay.

And of course, this could be done for any CSS property that’s set to its initial value, including CSS that overrides previous CSS. Here’s the aside h2 example again:

h2 {
  background-color: #444;
  color: white;
  padding: 7px;
}

/* ...hundreds of lines of code here... */

aside h2 {
  background: none; /* initial as an override */
  color: #444;
}

And I suppose in certain cases the following would be even better:

aside h2 {
  background-color: initial; /* override */
  color: #444;
}

Here I’m using the fairly well-supported initial CSS keyword value, which is one of the universal features of the language. In either case, even without the comment, assuming an override is fine, but adding the comment makes it even more clear.

Final Thoughts

I don’t necessarily think superfluous initial values are a huge problem in CSS. A couple extra lines are not going to break a code base or cause major performance issues.

My primary concern is with initial values that aren’t clear that they are overrides and stuff that’s been included (or copy-pasted) for educational reasons using CSS features that are new to the author of the code.

So my final suggestions for declaring initial values are:

  • Take the time to understand what initial values are and how they work (including within shorthand).
  • Add a comment to indicate if an initial value is an override. Even though developer tools will help make this clear, it won’t hurt to indicate it in comments.
  • Take care that you’re not including superfluous lines in new features like flexbox (or else use comments).
Web Tools Weekly

3 Responses

  1. Konstantin:

    Nice article. I think that it’s vital to know the basics of the language you are using and as for initial values of the CSS properties it can be thought of as basics. Regarding example with flex default values. I think that align-items initial value is normal which can be interpreted differently according to the element it’s applied, but for the plain static positioned elements it will be evaluated to stretch rather than flex-start.

    • Yes, that’s correct. For example, I believe when using the Grid Layout techniques, the initial value is “stretch” but it changes in a Flexbox context. It’s a little odd that way, but this allows the same properties to be useful in different layout contexts, which I guess is beneficial, though it can be confusing.

  2. Andy:

    Some good points here. Personally, whenever I find myself overriding a CSS rule, I realize there must be something wrong. I would rather go back and review the codes rather than resetting its initial values.

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field. If you use keywords, your comment will be deleted, or your name will be replaced with the alias from your email address. No foul language, please. Thank you for cooperating.

Instructions for code snippets: Wrap inline code in <code> tags; wrap blocks of code in <pre> and <code> tags. When you want your HTML to display on the page in a code snippet inside of <code> tags, make sure you use &lt; and &gt; instead of < and >, otherwise your code will be eaten by pink unicorns.