CSS box model tutorial
<pageby nominor="false" comments="false"/>
- Learning goals
- Understand the CSS box model
- Be able to style all parts of a CSS box
- Concurrent
- CSS tutorial (summary)
- 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.
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 defined width defined using any CSS length value (such a px, pt, cm) but not 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 */
}
The HTML example below shows two span's with different paddings:
<div style="border-style: dotted; width:70%; padding:1cm; background-color:#FCFFCD;">
Wrapping div
<span style="border-style: solid; padding:0cm; margin:0.5cm">
Inside the first embedded span.
</span>
<span style="border-style: groove; padding:0.3cm; 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.
Analyzing the box structure and other tips
Using browser-based web development tools
There exist several tools for analyzing a box structure
Using code
Displaying the borders of all or some boxes can help understanding a box structure.
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 browser padding and margins 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.
- The CSS Box Model at SitePoint.
- The CSS Box Model by Chris Coyier, June 2009.
- CSS Box Model (W3C schools)
- Borders and Box Model: Margins and Padding by Evan Goer. (Updated August 2010 or more recently)
- Lesson 9: The box model and Lesson 10: Margin and padding at HTML.net (undated)
Reference
- Box model chapter of the W3C Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification
- CSS basic box model, W3C Working Draft 9 August 2007. This is a draft module of the (future) CSS3 specification and not yet stable.