Introduction
This page reviews the basic CSS layout strategies that a web developer can employ to layout content on a page.
Along the way I present a basic workflow for how one can go about translating a desired design
into a workable page layout. First, we start by creating a sensible DOM layout using standard
HTML tags and/or <div>
and <span>
tags. Next, we work on the
general sizing and spacing of the layout using the CSS Box Model facilities. Before going any further,
we pause to think about how the layout will work with different screen sizes, and think about how we
will use CSS Media Queries to affect a responsive design. We then consider when or where we may need
to use floats or positioning. Finally, we consider which type of layout will be most effective for our
design by considering table, list, Flexbox, and Grid layout mechanisms.
That's not to suggest that the workflow is a strictly linear progress. For example, if one knows for sure that they want or need a Flexbox or Grid layout, you may want to start there and then work your way back into the CSS Box Model margins and padding. It's an iterative process. The final design will usually involve a hybrid of all of the approaches outlined here.
HTML Tags
Before we begin to stylize and layout the page structure with CSS rules, we want to first consider a sensible DOM structure using available HTML tags.
Tag Section(s) | Purpose | Tag List | Notes |
---|---|---|---|
Phrasing Content | Presentation-Oriented Inline Content Styling | <b> , <br> , <i> |
Avoid using presentation-oriented tags. Use alternate tags with better semantic
meaning where possible. <strong> is preferred over <b> .
<em> is preferred over <i> . Use paragraphs and/or margins
and padding in place of <br> where possible.
|
Phrasing & Flow Content | Semantically-Oriented Inline Content Styling | <abbr> , <em> , <strong> , etc. |
Most other tags not listed here, with the exception of metadata tags, are part of a large category of flow content tags. They are generally used to style the actual content of the page, not the structural layout. |
Sectioning Content | Semantically Meaningful Structure |
<article> , <aside> , <nav> , <section>
|
Sectioning content tags are the first opportunity to begin considering the actual structural layout of the page. |
Flow Content | Section Headers & Footers |
<header> , <footer>
|
Technically speaking, these tags are flow content, and are not considered part of sectioning content
or heading content. They are generally placed inside of a <section> , but this is not
required. When not inside a section group, the tags should be considered to supply header and footer content
for the page body. As such, these tags should be considered for use as part of an overall page
layout strategy.
|
Flow Content | The Main Tag | <main> |
Another flow content tag, <main> designates the main body of content of page.
It should not contain any content that is repeated across pages, such as logos, top navigation bars, side
navigation bars, headers, footers, etc. This tag should be considered as part of a well-designed page layout.
|
Heading Content | Header Titles |
<h1> to <h6>
|
Use heading content tags to supply title information to pages and sections. |
Flow Content | Lists & More |
<ol> , <ul> , <li>
|
Traditionally used to format hierarchically-arranged bulleted lists, these tags have
been used creatively for other purposes. A common example is to use a formatted list to style
a set of tab header items for tab-separated content. In addition to the tags, the CSS property
display: list‑item can be used to style any element as a list item.
|
Flow Content | Tables |
<table> , <tr> , <thead> , <tfoot> ,
<th> , <td>
|
Tables should not be used for general page layout purposes. They should only be used to format genuinely
tabular data for which multiply aligned rows and columns are the most logical form of presentation. The
corresponding CSS rules display: table and its brethren can now be used to style any
element as a table-type structure, and can sometimes be a good choice for cetain layouts that are difficult
to achieve with ordinary methods, although now with Flexbox and Grid layouts they are less needed.
|
Flow Content | Generic Structure | <div> , <span> |
Because HTML provides us with so few sectioning content tags that we can use for semantically-meaningful
layout, most of the time we need to resort the the generic box tags <div> and
<span> , which provide block and inline boxes (see below for more details).
For increased semantic meaning, we can apply one or more CSS classes.
|
Box Display Types
The commonly-used block
, inline
, and inline‑block
display
values are typically used in conjunction with the <div>
and <span>
tags, but
they can be applied to any element. These properties are frequently the first line of attack when approaching
page layout.
Display Value | Description | Box Characteristics |
---|---|---|
display: none; |
The box is not rendered and no space is taken up in the document flow. To reserve space in the
document flow, but make the box invisible, use visibility: hidden; instead.
|
|
display: block; |
Displays the element as a block element (like <p> ) |
|
display: inline; |
Displays the element as an inline element (like <span> ) |
|
display: inline‑block; |
Displays the element as an inline-level block container. The inside of this block is formatted as a block-level box, and the element itself is formatted as an inline-level box. |
|
Other Display Values |
See other layout alternatives below for more possible display values, such as flex
and grid .
|
|
More Information
Basic Box Model Layout
After laying out the page with well-chosen HTML tags, and choosing block
, inline
,
and inline‑block
box types as-needed, the next step in a typical layout workflow would
be to turn our attention to the CSS Box Model styling attributes to size the boxes as we'd like.
The CSS Box Model is a very power and flexible mechanism for controlling the margin, border, and padding of the boxes.
More Information
Advanced Box Model Layout
Beyond the basic box model usage, there are some advanced, trickier, and less known techniques we can consider.
Technique | Notes |
---|---|
Box Sizing |
The
It's often the case, especially when focusing on the outer, overall layout of the page, that this doesn't
give us what we want. If we change the sizing property to |
Negative Margins |
Although not immediately obvious, negative margins are valid on boxes. While its best not to misuse this feature, there are legitimate use cases for negative margins. More Details |
Auto Margins |
The keyword
Unfortunately, |
CSS calc() Function |
The introduction of CSS3 gave us the
The most common use case is to calculate the actual width based on a percentage value and a fixed unit value. For example,
suppose my box has left and right margins of 10px each, and I want my width to be 100% of the width of my parent. Without
The
The |
Setting Body Height |
It doesn't happen to me as much anymore, but when I was new to CSS layout I'd often get burned by this one. I'd have a layout that I intended to fill the full page of the browser. I was certain everything was correct, but my inner child element wouldn't expand to fill the full height of the browser. Instead, it would collapse down to the height of its children. The problem is that the html and body tags themselves were not expanding to the full browser height. We can set those easily enough. I also usually set padding and margin to 0 on those element as well. My CSS generally has a rule it it like:
|
Other Display Types |
In the old days of CSS 2.1, we only had the lowly display: block and display: inline to
work with. But with the introduction of CSS 3, we gained a whole host of new display options. We now have display types
dedicated to list and table displays, and with the new Flexbox and Grid layout modules, we've gained even more flexibility.
The layouts are discussed further down the page.
|
Media Queries
Media queries allow us to design interfaces that are responsive to a wide variety of device capabilities. Our page layouts should contemplate how the user experience will behave on different screen sizes and different device capabilities.
Originally introduced as media types in CSS 2, which provided some limited responsive design constructs, these capabilities were greatly expanded in CSS 3 with the introduction of media queries. CSS 2 only allowed us to query the type of the device, but with CSS 3 we can query the capabilities of the device. Does the device have a mouse? Does it support stylus or touch input? What is its aspect ratio? Etc.
Some measure of responsive design can be accomplished without media queries. When we use percentage height and widths in our CSS rules, telling the browser to stretch out our content to fill the space of the parent box, we're doing responsive design that can accommodate the user resizing their browser ... but only to a degree. That approach won't accommodate radical changes in screen size. What happens if the user accesses the site from their smartphone or tablet? It won't look good. We need more than just stretching our box to fill the space, we need a way to choose between entirely different layout options based on the capabilities of the device. Our beautiful side navigation pane looks great when the browser is at least 1200px wide, but for smaller sizes we want a dropdown list at the top of the page that doesn't require as much space. Those are the kinds of choices we can build into our CSS rules using media queries.
More Information
W3Schools - Responsive Web Design
W3Schools - Media Query Examples
W3Schools - Media Queries Overview
W3Schools - The @media
CSS Rule
MDN - Media Queries Overview
MDN - Using Media Queries
MDN - @media
Floats
Originally designed for floating blocks of text around images, the float
property became, prior
to Flexbox and Grid layouts, one of the most commonly used tools for creating multiple column layouts on web pages.
Another common use case is laying out a top navigation bar. You want some content in the navigation bar aligned to
the left hand side, and other content aligned to the right hand side.
Floats are tricky to use, because after using the float to align the desired content, we need to clear the floats so that the follow-on content goes back normal. This makes the designing clean, well-organized, independently-formatted content more difficult. Floats are less needed now that we have Flexbox and Grid layouts, but they can still be useful in some situations.
More Information
Positioning
Positioning allows you to take elements out of the normal document layout flow, and make them behave differently, for example sitting on top of one another, or always remaining in the same place inside the browser viewport.
Position Value | Description |
---|---|
position: static; |
The default position of every element. It means put the element in it's normal position in the document layout flow. |
position: relative; |
Once the positioned element has taken its place in the normal layout flow, you can then
modify its final position (using the CSS properties top , left , bottom ,
and right ).
|
position: absolute; |
An absolutely positioned element no longer exists in the normal document layout flow. It sits on it's own layer,
separate from everything else. It's position is anchored by it's closest statically positioned ancestor, and
is controlled with the CSS properties top , left , bottom , and right .
You can also use z-index to control its position in a z axis, which can be affected by the opacity
if it overlaps other elements.
|
position: fixed; |
Similar to absolute positioning, except the element is positioned relative to the browser viewport
itself (as opposed to its closest static ancestor).
|
position: sticky; |
An experimental position that is not yet widely supported, it is a hybrid of relative and fixed. The element is relatively positioned until it is scrolled to a certain threshold point, after which it becomes fixed. |
More Information
List Layouts & Styling
We tend to think of ordered an unordered lists as inherently being a way to style hierarchically
arranged, bulleted lists. That is the default styling applied to those elements, but semantically
speaking, the <ol>
and <ul>
are only meant to define a block
that contains a list of items. They may be displayed as bulleted lists, and are by default, but
ultimately it is up to the designer to style them. CSS provides us with mechanisms for doing so.
Lists can sometimes be used as a layout mechanism. For example, this article from MDN describes how to use lists as a way of composing a tab control, and this article describes how to use lists to create multi-column layouts. Lists can also be an effective way to mark up the items in a top or side navigation pane.
CSS Property | Description |
---|---|
display: list‑item; |
Let the element behave like a <li> element
|
list‑style: [<type>] [<position>] [<image>] |
A shortcut property to set all list item properties with a single setting. |
list‑style‑image: url(image‑location) |
Replaces the default item marker (typically a bullet) with an image. |
list‑style‑position: inside; |
Indents the marker and the text. The bullets appear inside the content flow. |
list‑style‑position: outside; |
The default. Keeps the marker to the left of the text. |
list‑style‑type: value; |
Sets the type of bullet or number. There are over 20 bullet and numbering styles to choose from. More details. |
More Information
Table Layouts
Using the HTML table tags for layout purposes has always been frowned upon, primarily for these reasons.
The dogma always seemed a bit silly to me, especially considering how difficult is was to create certain layouts
without tables, and how easy it was to do with tables. Take for example the so-called
Holy Grail layout, and various
attempts over the years to create them with tableless CSS rules. It hardly seems fair to give something the mystique
of the Holy Grail, when there's a beautiful, solid gold, jewel-encrusted chalice laid out
directly before you, surrounded by flashing neon lights emblazened with the headline Jesus Drank from this Cup
.
But, using CSS tables instead of hard-coded HTML elements, we can avoid some of the downsides of tables. With Flexbox
now becoming ubiquitous, there's less reason to consider CSS tables, but even so, it's good to keep CSS table layout
tucked away in your bag of tricks. Any HTML element can be made to act as a table element using the CSS display
property.
Display Setting | Element Behavior |
---|---|
display: inline‑table; |
The element is displayed as an inline-level table |
display: table; |
Let the element behave like a <table> element
|
display: table‑caption; |
Let the element behave like a <caption> element
|
display: table‑column‑group; |
Let the element behave like a <colgroup> element
|
display: table‑header‑group; |
Let the element behave like a <thead> element
|
display: table‑footer‑group; |
Let the element behave like a <tfooter> element
|
display: table‑row‑group; |
Let the element behave like a <tbody> element
|
display: table‑cell; |
Let the element behave like a <td> element
|
display: table‑column; |
Let the element behave like a <col> element
|
display: table‑row; |
Let the element behave like a <tr> element
|
More Information
The Anti-hero of CSS Layout
Why Tables Are Bad (For Layout)
W3Schools - The display
Property
Flexbox
A new technology, but with support now fairly widespread across browsers, Flexbox is starting to become ready for widespread use. It allows for rapid creation of complex, flexible layouts, and features that have historically proved difficult with CSS.
More Information
Flexbox Examples
W3Schools - Flexible Box
MDN - Flexbox
CSS-Tricks - A Complete Guide to Flexbox
Solved by Flexbox
Grid Layouts
A nascent new browser feature that makes implementing a grid design much easier. Grid designs, such as those popularized
by Bootstrap and other similar CSS toolkits have traditionally used floats
or other layout features, and
can sometimes prove tricky to implement.
The main difference between Flexbox and Grid is that Flexbox is designed for a one-dimensional layout, whereas Grid is explicitly designed to create two-dimensional layouts.
More Information
MDN - GridsMDN - CSS Grid Layout
CSS-Tricks - A Complete Guide to Grid