Box Model: Margins and Padding

Now that we’ve covered borders, let’s return to our examination of the box model.

Figure 3.2. The Box Model (Again)

The Box Model

Padding

In “Borders”, you might have noticed that in all border examples, the text and the borders were rather close together.

An element’s padding is the element’s “extra space inside the border”. There are four padding properties: padding-top, padding-bottom, padding-left, and padding-right. You may set these values to px, em, percentages, or any other valid length unit.

Let’s take a look at an example. Example 3.19, “Non-uniform Padding” specifies two CSS rules:

Example 3.19. Non-uniform Padding

<html>
<head>
  <style>
    div {
      background: #444;
      color: white;
    }

    div.padded {
      padding-top: 10px;
      padding-right: 0px;
      padding-bottom: 0.25in;
      padding-left: 5em;
    }
  </style>
</head>
<body>
  <div>
    No padding (but some style added)
  </div>
  <br>
  <div class="padded">
    Padded<br>
    Top: 10px; bottom: 0px<br>
    Left: 5em; right: 0px
  </div>
</body>
</html>

The example includes a padded div, followed an ordinary div for comparison. The padded div has padding that varies for each side of text, as we specified. It turns out that 5em (”five m-widths”) is considerably larger than 10px, so the text looks shoved over to the right. As for the ordinary div, we didn’t specify any padding rules for it, so it takes the browser default padding: 0px on all sides.

Padding Shorthand Notation

There is also a shorthand property, padding. This property allows you to specify all your padding on one line:

As with the previous example, Example 3.20, “Shorthand Padding” provides basic styling for all divs, and then uses classes to change the padding for specific divs. For additional decoration, we’ve also added a dark red border to each div.

Example 3.20. Shorthand Padding

<html>
<head>
  <style>
    div {
      background: #444;
      color: white;
      border: #600 6px ridge;
    }

    div.one {
      padding: 20px;
    }

    div.two {
      padding: 20px 80px;
    }

    div.three {
      padding: 20px 80px 10px;
    }

    div.four {
      padding: 20px 80px 10px 40px;
    }
  </style>
</head>
<body>
  <div class="one">
    padding: 20px (all)
  </div>
  <br>
  <div class="two">
    padding: 20px 40px (top/bottom, right/left)
  </div>
  <br>
  <div class="three">
    padding: 20px 40px 10px (top, right/left, bottom)
  </div>
  <br>
  <div class="four">
    padding: 20px 40px 10px 30px (top, right, bottom, left)
  </div>
</body>
</html>

The padding is completely contained within the borders. For example, the inside edge of the first div’s border is 20px from the far left edge of the text. Try changing the size of the borders. Even if you make the border very thick, the padding stays the same thickness.

Of these four notations, the first (same padding for all sides) is the most commonly used and the easiest to remember. However, if you want to baffle and impress your web designer friends, you should memorize all four.

Margins

Margins are similar to padding. There are four margin properties: margin-top, margin-bottom, margin-left, and margin-right. There is also a shorthand property, margin, which uses the same syntax as the padding property.

The key difference between margins and padding is that padding adds extra space inside the border, while margins add extra space outside the border:

Example 3.21. Two Margin Blocks

<html>
<head>
  <style>
    div.even {
      background: #cfc;
      border: 1px solid;
      padding: 5px;
      margin: 40px;
    }

    div.uneven {
      background: #fcf;
      border: 1px solid;
      padding: 5px;
      margin-top: 20px;
      margin-right: 10px;
      margin-bottom: 40px;
      margin-left: 80px;
    }
  </style>
</head>
<body>
  <div class="even">
    margin: 40px (all)<br>
    padding: 5px (all)
  </div>
  <div class="uneven">
    margin-top: 40px<br>
    margin-right: 30px<br>
    margin-left: 20px<br>
    margin-bottom: 10px<br>
    padding: 5px (all)
  </div>
</body>
</html>

We’ve set the padding to a uniform 5px, and we’ve set the background color to provide a little contrast. The first box’s margin is set to a uniform 40px. The second box’s margin is set to four different values. (The equivalent shorthand setting is “margin: 20px 10px 40px 80px”.)

Collapsing Margins

Without a border, it’s hard to tell the difference between the padding and the margin. One key difference is that the element’s background color applies to the padding, but not the margin. Another key difference is that vertical margins collapse.

At first glance you might guess that in Example 3.21, “Two Margin Blocks”, the vertical separation between the two inner blocks would be 60px: 40px for the bottom margin of the first block plus 20px for the top margin of the second block. However, the margins collapse to 40px.

To simplify things greatly, margin collapse occurs when:

Margin collapsing sounds pretty complicated, and it is. You might be wondering why it’s there in the first place.

Suppose we lived in a world where there is no such thing as margin collapsing. If we had a sequence of five paragraphs, and we want even spacing of, say, 10px between each paragraph, how would we achieve this, exactly? In short, you’re not going to get nice spacing without a lot of hand-tweaking.

Back in the real world, margin collapsing is in effect, and so the aforementioned problem doesn’t exist. If you write a bunch of paragraphs in a row, the browser just “does the right thing”, collapsing margins so that even though each paragraph defines a top and bottom margin, the space between paragraphs doesn’t get doubled.

Styling with the Box Model

Now that we’ve covered the components of the box model, you might be thinking, “Sure, it’s nice that you can surround every paragraph with a bright lavender ridged border, but is that really all that practical?” Let’s step through a couple of more real-world examples.

Text Decoration with Borders

Selective borders enable you to add styling to inline text that you couldn’t ordinarily apply. As an example, one popular convention on the Web is to style abbr with a dotted underline. It would be nice if we could use text-decoration to simulate this effect. Creating a dotted underline using text-decoration might be possible in the future, but at the time of this writing this CSS feature is still in draft status. However, we can use borders to work around this problem:

Example 3.22. Dotted Underline

<html>
<head>
  <style>
    abbr {
      border-bottom: 1px #000000 dotted;
    }
  </style>
</head>
<body>
  <p>
    When my
    <abbr 
      title="Person of Opposite Sex Sharing Living Quarters"
    >POSSLQ</abbr> 
    and I went
    <abbr 
      title="Self-Contained Underwater Breathing Apparatus"
    >SCUBA</abbr> 
    diving yesterday, we were attacked by
    <abbr 
      title="North Atlantic Treaty Organization">NATO</abbr>-controlled 
    sharks with frickin'
    <abbr 
      title="Light Amplification by Stimulated Emission of Radiation"
    >LASER</abbr>
    beams attached to their heads.
  </p>
</body>
</html>

Once the latest CSS specification solidifies, the browsers will be able to follow suit and implement true dotted underlines, and the recipe above will become obsolete.

Fancier Blockquotes

The blockquote element is for quoted text that consists of one or more full paragraphs. By default, blockquote indents everything to the right. In the past, people abused blockquote (and ul and ol) to simply indent text. But there are much better ways to indent text, and so it’s best to use blockquote for its original purpose: quoting paragraphs of text.

Let’s say that simply indenting the text is too plain. We’d like to add some color. In Example 3.23, “Blockquotes”, we change the appearance of the blockquote element step-by-step until we achieve the desired effect.

Example 3.23. Blockquotes

<html>
<head>
  <style>
    blockquote { background: #ccccff; }
    blockquote.padded { padding: 3px; }
    blockquote.bordered { padding: 3px; border-left: 3px #0000cc solid; }
    blockquote.bordered p { margin: 10px; }
  </style>
</head>
<body>
  <blockquote>
    <p>"I also have a paper afloat, with an electromagnetic theory of light,
    which till I am convinced to the contrary, I hold to be great guns."</p>
  </blockquote>
  <p>- James Clerk Maxwell</p>

  <blockquote class="padded">
    <p>"An expert is a person who has made all the mistakes that
    can be made in a very narrow field."</p>
    <p>"Your theory is crazy, but it's not crazy enough to be true."
  </blockquote>
  <p>- Niels Bohr</p>

  <blockquote class="bordered">
    <p>[As a student, attending a lecture by Einstein]
    "You know, what Mr. Einstein said is not so stupid..."</p>
    <p>[On his wife leaving him for a chemist]
    "Had she taken a bullfighter, I would have understood, but an
    ordinary chemist..."</p>
  </blockquote>
  <p>- Wolfgang Pauli</p>
</body>
</html>
  1. blockquote { background: #ccccff; }

    First, we try setting the background to pale blue. Unfortunately, since the blockquote has no padding, the colored space looks crowded.

  2. blockquote.padded { padding: 3px; }

    Next, we’ll try fixing this up by creating a new class, padded. This class inherits the background color assigned to all blockquotes, and includes a little extra padding so that the child paragraphs don’t look so crowded. Whoops! A whole lot of extra space appears above and below the paragraphs. This looks even worse. What happened?

    Adding padding to blockquote has triggered an interesting side-effect of the rules for collapsing margins. As soon as you add padding or borders to the parent blockquote element, margin collapsing goes away. This causes the paragraph’s margins to suddenly push out the blockquote above and below.

  3. blockquote.bordered { padding: 3px; border-left: 3px #0000cc solid; }

    Let’s try one more time. We’ll create another class, bordered, that includes the padding and adds a decorative dark blue border to the left side of the blockquote.

  4. blockquote.bordered p { margin: 10px; }

    Finally, we’ll try to account for the problem introduced by the padding. The selector blockquote.bordered p directs the browser to “apply this style to all p elements that are inside a blockquote with a class of bordered.” As a quick fix, we’ll assign these paragraphs a uniform margin of 10px. This pushes the paragraphs out to the right, and provides a more uniform spacing around each paragraph. The spacing between each paragraph is 10px, while the spacing between the blockquote and the paragraphs is 13px. To make the spacing even more uniform, you could reduce the blockquote padding to 1px, or play a few more tricks with margins and padding, but let’s move on.