CSS box model tutorial: Difference between revisions

The educational technology and digital learning wiki
Jump to navigation Jump to search
Line 422: Line 422:


</div>
</div>
Notice: The dotted border border around the pre tag is defined by our MediaWiki style sheet.


== Analyzing the box structure and other tips ==
== Analyzing the box structure and other tips ==

Revision as of 18:38, 13 November 2011

<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 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.


Box size

By default, width and height of all boxes are set to auto, i.e. they will adapt to the size of the content and the available horizontal space.

Width and height

Box dimensions, i.e. their horizontal and vertical width can be set through CSS properties using either absolute values or percentages. Percentages refer to the dimensions of the parent box.

List of size-related CSS properties

  • width - sets the horizontal size of a box
  • height - sets the vertical size of a box
  • min-width - sets the minimal width, box can be larger if there is space
  • min-height - sets the minimal height, box can be higher if there is space
  • overflow - defines what to do when there isn't enough space for showing a content.

In most cases, it is best to set only a min-width' for large text boxes and a width for menu boxes and let the browser display contents in the vertical axes. Min-width will not set an initial width for display, but it defines just how small a box can get. Therefore it is often combined with a width using percentages. In the past, many web designers forced fixed width pages on the user. This strategy has two problems: Such pages won't display well on small screens (e.g. cell phones) and will look ugly on large screens (1900 px and wider).

  • In most cases, the best solution is to create so-called fluid web pages where box width adapts to the browser width, i.e. use percentages and allow boxes to float down if the screen gets really narrow (read the CSS positioning tutorial for the latter).
  • One also can use overflow for content that must not wrap, e.g. computer code. Overflow values are by default = visible (i.e. no overflow). Other values are hidden, scroll and auto.

Below is an example that shows various settings. Play with your browser window, i.e. reduce its width.

<div style="border-style: dotted; width:30%; background-color:#FCFFCD;">
Wrapping div.

<p style="border-style: solid;  margin:0.5cm">
Inside the first embedded p. No width set.
</p>

<p style="border-style: solid; width:4cm; margin:0.5cm">
Inside the second embedded p. margin=0.5cm, width=4cm.
</p>

<p style="border-style: solid; width:80%; min-width:3cm; margin:0.5cm">
Inside the 3rd embedded p. margin = 0.5cm, width = 80%, min-width = 2cm.
</p>

<div style="border-style: solid; width:4cm; min-width:2cm; margin:0.5cm;
          max-height:2cm; overflow:auto">
<p>Inside the 4th embedded p. margin = 2cm, width = 4cm, min-width = 0.5cm, overflow = auto.</p>
<pre>
fixed code - fixed code - fixed code - fixed code 
</pre>
</div>

</div>

This is how is looks:

Wrapping div.

Inside the first embedded p. No width set.

Inside the second embedded p. margin = 0.5cm, width = 4cm.

Inside the 3rd embedded p. margin = 0.5cm, width = 80%, min-width = 2cm.

Inside the 4th embedded p. margin = 2cm, width = 4cm, min-width = 0.5cm, overflow = auto.

fixed code - fixed code - fixed code - fixed code 

Notice: The dotted border border around the pre tag is defined by our MediaWiki style sheet.

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.


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.