CSS box model tutorial

The educational technology and digital learning wiki
Revision as of 18:33, 13 November 2011 by Daniel K. Schneider (talk | contribs)
Jump to navigation Jump to search

<pageby nominor="false" comments="false"/>

Learning goals
  • Understand the CSS box model
  • Be able to style all parts of a CSS box
Concurrent
Moving on
Level and target population
  • Beginners
Teaching materials
Remarks
  • This tutorial is intended for students in a field that is technology intensive (e.g. computer applications or educational technology). For people who need less, there exist many easy CSS tutorials on the web. This text is intended for students who also must learn principles and who are willing to learn CSS by doing a project, looking at CSS code and online reference manuals.
  • Ideally, a teacher also should assign a text formatting task, during or before assigning this tutorial for reading).
  • There are some inline examples. However, they had to be created in a away that makes them fit into a wiki page. I.e. we use inline style (something we usually don't advocate) and we also had to add extra styling properties.


Introduction

All HTML elements (whether they are blocks, inline elements, list elements, etc) are a kind of box that adds margins, borders and padding to the actual content.

CSS Box model. Source: http://www.w3.org/TR/css3-box/ Copyright: Click on the picture

From this model we can define total height an width of an HTML element.

Total height
= top margin + top border width + top padding + content height + bottom padding + bottom border width + bottom margin
Total width
= left margin + left border width + left padding + content width + right padding + right border width + right margin

Normally, an element doesn't have any width, i.e. it is set to auto. This means for example, that a longer paragraph will grower wider when the user enlargens the window. An element may have no borders, margins, or padding. In that case its dimensions are indirectly defined by its content, i.e its "auto" width or width (if set). However, by default, many HTML already include some padding and some margins. E.g. there is some space before and after and HTML h1 heading.


Box border properties

Borders are usually invisible. You can style each of the four borders or all four together.


Setting the border style

By default borders are invisible. You can set the style for each border. Allowed values are:

  • none - default
  • hidden
  • dotted
  • dashed
  • solid
  • double - double line
  • groove - looks as though it were carved into the canvas.
  • ridge - looks as though it were coming out of the canvas (i.e. the opposite of groove)
  • inset - looks as though it were embedded in the canvas.
  • outset - makes the box look as though it were coming out of the canvas (opposite of inset)

Example CSS code defining four borders:

div.example {
 border-top-style: solid;
 border-right-style: dashed;
 border-bottom-style: dashed;
 border-left-style; dotted;
}

There is a shortcut property for defining all four borders at once: border-style.

div.example2 {
 border-style: solid dashed dashed double;
}

Below is an HTML+CSS example that includes two embedded div's inside a dotted div. We also used the width and margin properties in order to have a nicer rendering of the boxes.

<div style="border-style: dotted; width:70%; background-color:#FCFFCD;">
Wrapping div
<div style="border-style: solid dashed double dotted;  margin:0.5cm">
Inside the first embedded div.
</div>
<div style="border-style: groove; margin:0.5cm">
Inside the second embedded div.
</div>
</div>

It will look like this:

Wrapping div

Inside the first embedded div.

Inside the second embedded div.

The same example, using span's instead of div's would look like this:

<div style="border-style: dotted; width:70%; background-color:#FCFFCD;">
Wrapping div
<span style="border-style: solid dashed double dotted;  margin:0.5cm">
Inside the first embedded span.
</span>
<span style="border-style: groove; margin:0.5cm">
Inside the second embedded span.
</span>
</div>

It will look like this:

Wrapping div Inside the first embedded span. Inside the second embedded span.

Setting the border width

Each of the four borders can have a width defined with any length value (such a px, pt, cm) but no percentages. In addition, you can use the following keywords: thin, medium and thick.

Example CSS code:

div.example {
 border-top-width: thick;
 border-right-width: 1px;
 border-bottom-width: medium;
 border-left-width; 1px;
}

Example CSS code:

div.example2 {
 border-width: 1px;
}

Example HTML+CSS code:

<div style="border-style: dotted; width:70%;  
            margin-lef:1em; background-color:#FCFFCD;">
Wrapping div
<div style="border-top-width:thick; border-bottom-width:medium;
            border-top-style: solid; border-bottom-style: solid;
            margin:0.5cm">
Inside the first embedded div.
</div>
<div style="border-width:thin; border-style: solid; margin:0.5cm">
Inside the second embedded div.
</div>
</div>

Below, how it should look:

Wrapping div

Inside the first embedded div.

Inside the second embedded div.


Border color

Same logic as for the other parameters:

 border-top-color: red;
 border-right-color: green;
 border-bottom-color: #333;
 border-left-color: #ffff00;

To set all borders in a single instruction, use border-color.


All in one border setting

The border property allows to define all four sides with a single instruction, i.e. width, style and color:

Example:

 border: 1px solid red;


Box margins

Margins define the distance of a box with respect to other boxes. More precisely, “Margin properties specify the width of the margin area of a box. The 'margin' shorthand property sets the margin for all four sides while the other margin properties only set their respective side. These properties apply to all elements, but vertical margins will not have any effect on non-replaced inline elements.” (CSS2 specification).

By default, in HTML browsers, many HTML elements already include margins, in particular vertical margins. The specification suggests default margins, but browser makers are not obliged to implement these.

E.g. the Appendix D. Default style sheet for HTML 4 suggest the following defaults:

 body            { margin: 8px }
 h1              { font-size: 2em; margin: .67em 0 }
 h2              { font-size: 1.5em; margin: .75em 0 }
 h3              { font-size: 1.17em; margin: .83em 0 }
 blockquote      { margin-left: 40px; margin-right: 40px }
 ul              { margin: 1.12em 0; margin-left: 40px}

Setting the border margins

There exist four simple CSS2 properties: margin-top, margin-right, margin-bottom, margin-left and their meaning should be self-explaining.

Example:

p {
 margin-top: 1x;
 margin-right: 1em;
 margin-bottom: 1x;
 margin-left: 1em;
}

Below is an HTML example using inline CSS:

<div style = "border: dotted black 1px;">
<p style = "margin-top: 1x;  margin-right: 1em;  
             margin-bottom: 1x;  margin-left: 1em;
             border: solid black 1px;">
Paragraph inside a div with extra margins.
</p>
<p style = "border: solid black 1px;">Normal paragraph</p>
</div>

The result should look like this:

Paragraph inside a div with extra margins.

Normal paragraph

The shorthand notation allows to set all four borders in a clockwise order: top, right, bottom, left. You also can use just one value (all borders) two values (top+bottom right+left), or three values (top right+left bottom)

Examples:

 margin: 1x 1em 2x 1em;  /* top right bottom left */
 margin: 1x 1em; /* top+bottom left+right */
 margin: 1x 1em; 2x;
 margin: 2cm; /* all */


Collapsing margins

Margins will collapse. In the a situation where:

  • Box A has 1cm bottom margin
  • Box B has 2cm top margin
  • B sits underneath A

The distance between the two box will be 2 cm (and not 3cm), i.e. the highest concerned margin will win.

Actually it gets very complicated. Let's quote excerpts from the CSS 2 specification:


In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said to collapse, and the resulting combined margin is called a collapsed margin.

(1) Adjoining vertical margins collapse, except:

  • Margins of the root element's box do not collapse.
  • If the top and bottom margins of an element with clearance are adjoining, its margins collapse with the adjoining margins of following siblings but that resulting margin does not collapse with the bottom margin of the parent block.

(2) Horizontal margins never collapse.

(3) Two margins are adjoining if and only if:

  • both belong to in-flow block-level boxes that participate in the same block formatting context.
  • no line boxes, no clearance, no padding and no border separate them.
  • both belong to vertically-adjacent box edges.


Padding

The padding properties specify the width of the padding area of a box. The padding shorthand property sets the padding for all four sides while the other padding properties only set their respective side. (W3C CSS2 Box model - Padding properties)

Like margins, paddings can be defined with the usual length values or percentages. By default, padding is set to 0. However, you may not count on that in all and every browser.

Example CSS code:

div.example {
 padding-top: 1x;
 padding-right: 1em;
 padding-bottom: 1x;
 padding-left: 1cm;
}

The shortcut padding property allows to define the four paddings in the usual order: Example CSS code:

div.example {
 padding: 0.5cm;
}
div.example2 {
 padding: 0.5cm 1cm 0.5cm 1cm; /* top right bottom left */
}


Analyzing the box structure and other tips

Using browser-based web development tools

There exist several tools for analyzing a box structure


Using code

One way of understanding a box structure is to simply display the boxes.

Chris Coyier in, The CSS Box Model ( retrieved 18:57, 7 November 2011 (CET)) shows the simple trick you need in order to display the borders.

At the end of your CSS, add:

 * {
   border: 1px solid red !important;
 }

How it works: The "!important" keyword will override other border specifications and therefore all borders will show in red.

Of course you can change the color and the line thickness.


Compatibility issues

(1) Watch out for quirks mode - or why you must include an HTML declaration

Make sure to include a valid HTML declaration in your HTML file. Read the HTML and XHTML elements tutorial or the HTML article if you don't know how.

For example:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

If you don't include such a declaration, then browsers will fall into quirks mode and may add some padding and border to the width...

Default padding and margins still may differ

If you produce text-centric text as explained in the CSS text styling tutorial, you shouldn't care at all. If you plan to create pixel-precise web pages (something I never do) then you should care.

Some developers reset everything:

* {
   padding:0;
   margin:0;
}

.... and then restyle both block and inline elements.

I'd rather just reset some elements, e.g.

 h1, h2, h3, h4, h5, h6, p, form, ul, dl, ol, blockquote, li {
   padding:0;
   margin:0;
 }

But resetting some elements isn't so easy, e.g. for lists

ul {
  padding-left:1em; margin-left:0;
}

Finally, there also exist browser bugs, in particular in older IE version, but we will not address these problems here for the moment...


Links and references

Introductions

  • Basic CSS Box Model Demo. Actually it's a useful visualization that decomposes a flat "picture" into a faux 3D representation.


Reference

  • CSS basic box model, W3C Working Draft 9 August 2007. This is a draft module of the (future) CSS3 specification and not yet stable.