Website layout design can be described as a game of stacking boxes. All website elements are rectangular, and our job is strategically place them in the layout. Today's HTML layout follows the box model, where each element is equipped with height and width (and optionally margins, paddings, and/or borders).
All HTML elements fall into one of two categories: block and inline elements.
Block elements, by default, span across the page layout, taking up all of the available horizontal space and pushing subsequent elements to the next line. Some examples include the following:
p
h1
, h2
, h3
...div
(discussed below)Inline elements, on the other hand, can sit adjacently in the same horizontal line until the space runs out, where they will continue in the next line. Some examples include:
a
img
strong
em
div
elementDivision elements offer structure to HTML layout. Written as <div>
, division elements are considered to be block elements with the following qualities:
It is also important to note that the above characteristics are merely defaults, and can be overridden with the following CSS properties:
width
(100%
by default; can use px
or %
to define)display
(block
by default; can be changed to other values such as inline-block
or flex
)The Web, even nowadays, is not a friendly place for layout columns. Many designers have come up with different techniques to build columns within the layout, and there still is no universally agreed-upon approach.
Designers have moved from using table
elements to relying on div
elements, and we now have the flex
CSS technique that is not necessarily supported by older browsers and devices. Look at the appendix for one of the techniques for creating columns using div
elements and display:inline-block
(later display:flex
).
Since the beginning of the Web, each browser was equipped with its own user agent stylesheet to render HTML pages without CSS code. While this default stylesheet renders stylesheet-less websites more legible, it does bring a different challenge to designers as the stylesheet provides default styling that the designer may not be aware of.
CSS reset is a technique that allows the developer to nullify all user agent stylesheets and start from scratch. This technique removes all the default styling, including page paddings and margins, giving the developer complete control over each page.
div
-based Columns with inline-block
<div id="index">
<div id="left">
</div>
<div id="right">
</div>
</div>
We can create child div
elements to serve as the two columns housed in the original div
.
#left
{
height:300px;
width:25%;
background-color:skyblue;
}
#right
{
height:300px;
width:75%;
background-color:pink;
}
Because div
is a block element by default, the boxes will stack on top of each other.
#left
{
height:300px;
width:25%;
background-color:skyblue;
display:inline-block;
}
#right
{
height:300px;
width:74%;
background-color:pink;
display:inline-block;
}
Note that both boxes are equipped with display:inline-block
. width
is set to 74%
to accommodate the white space issue represented below.
<div id="index">
<div id="left">
</div><!--
--><div id="right">
</div>
</div>
The whitespace issue can be resolved by "closing the gap" between the end tag of the #left
and the start tage of #right
.
#left
{
height:300px;
width:25%;
background-color:skyblue;
display:inline-block;
}
#right
{
height:300px;
width:75%;
background-color:pink;
display:inline-block;
}
Once the whitespace issue is resolved, we can revert to width:75%
.
This approach continues to prove reliable, especially with older browsers such as Internet Explorer 11. For a more contemporary approach refer to the addendum below.
div
-based Columns with flex
With HTML5 and CSS3 standards finally adopted by contemporary browsers, we can now embrace the more reliable flexbox approach to build columned layouts, free of any whitespace hack. Refer to the following code samples:
<div id="index">
<div id="left">
</div>
<div id="right">
</div>
</div>
#left
{
height:200px;
width:25%;
background-color:skyblue;
}
#right
{
height:150px; /* Note that this column has been purposely set to a smaller height */
width:75%;
background-color:pink;
}
Instead of inline-block
, let us try flex
instead. However, note this property needs to be applied not to the child elements (#left
and #right
), but instead to their parent (#index
):
#index
{
display:flex;
}
#left
{
height:200px;
width:25%;
background-color:skyblue;
}
#right
{
height:150px;
width:75%;
background-color:pink;
}
Just like that, we can achieve a two-column layout with ease. However, note that the right column, despite its different height value, stretches vertically to fit its taller sibling. This is the default behaviour set for all flexboxes, and we can override this by using one extra property:
#index
{
display:flex;
align-items:center;
}
#left
{
height:200px;
width:25%;
background-color:skyblue;
}
#right
{
height:150px;
width:75%;
background-color:pink;
}
align-items
allows us to dictate whether we want the child elements of a flexbox parent to 1) align to a specific axis or 2) stretch to match in height. You may experiment with start
and end
which will align the elements to the top and the bottom respectively.