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:

  • The first rule applies to all div elements, and changes the background, the text color, and the font family. The gray background is necessary so that we can easily see padding for all divs, while the other two properties are purely cosmetic.

  • The second rule applies only to div elements with a class of padded. Any div with this class will have special, non-uniform padding.

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:

  • padding: 20px — Padding for all four sides is 20 pixels.

  • padding: 20px 80px — Padding for the top and bottom is 20 pixels, the left and right is 80 pixels.

  • padding: 20px 80px 10px — Padding for the top is 20 pixels, the left and right is 80 pixels, and the bottom is 10 pixels.

  • padding: 20px 80px 10px 40px — Padding for the top is 20 pixels, the right is 80 pixels, the bottom is 10 pixels, and the left is 40 pixels.

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:

  • the margins are vertical (horizontal margins never collapse)
  • and:
    • the blocks are directly adjacent (if there is anything between the blocks, the margins do not collapse)
    • or the blocks are nested and the parent block has no vertical borders or padding (if the parent block has vertical borders or padding, the margins do not collapse. For an example, refer to “Fancier Blockquotes”)
  • and the blocks are left in the normal “flow” of the page (something you only need to worry about when using CSS for more advanced things, such as page layout)

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.

  • If each paragraph has a top and bottom margin of 10px, then the margin at the top and bottom of the group of paragraphs would be 10px (good), but the spacing in between each paragraph would be 20px (bad).

  • Okay, what if we just specify margin-bottom as 10px, and leave margin-top as 0px? That’s better, but we still would have a problem at the very top, where the first paragraph butts up against the top of the page (or whatever is above the paragraph).

  • Specifying margin-top as 10px creates a similar problem: there would be no spacing between the bottom of the last paragraph and the top of the next element.

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.

Last updated December 17, 2023 at 11:33 am. © 2001 – 2024 by Evan Goer