In this article I'll explain how to use the table values of the CSS
display
property to format certain sections of a simple three-columns layout.
The final layout is shown in the picture below.
The relevant sections that will be formatted with such values are highlighted in the following picture.
The navigation menu
We start with the following markup:
<div id="header"> <h1>CSS Magazine</h1> <ul id="nav"> <li><strong>Home</strong></li> <li><a href="#">Articles</a></li> <li><a href="#">Tests</a></li> <li><a href="#">Tutorials</a></li> </ul> </div>
As you can see, the navigation menu (#nav
) is contained in the #header
section, where there is also the main title of the page (an h1
element. The styles could
be the following:
#header { height: 8em; min-height: 80px; border-bottom: 1px solid #333; background: #fff url("img/banner.png") no-repeat 0 0; position: relative; } #header h1 { position: absolute; top: -1000em; } #nav { display: table; position: absolute; top: 0; right: 0; height: 100%; border-left: 1px solid; margin: 0; padding: 0; border-collapse: collapse; width: 15%; } #nav li { display: table-row; } #nav li a, #nav li strong { display: table-cell; border: 1px solid #000; font-size: 120%; width: 100%; padding: 0 0.3em; text-decoration: none; } #nav li a:hover { background: #800; color: #fff; } #nav li strong { background: #800; color: #fff; }
View the example - View the screenshot
The first two rules give a basic formatting to our header. We've set a height in ems and a
minimum height in pixels. The latter equals the height of the background image that we'll use as
a banner. A minimum height gives a full visibility to our background image even when the user
decreases the base font size or when the specified font used on the page is not available. The last
declaration of the first rule creates a new context positioning through the value relative
of the position
property. Thanks to this declaration, we can absolutely position our
navigation menu by taking the header section as a reference and not the whole viewport. Then we want
to get rid of the heading's text, since it must be replaced by the background image. We use absolute
positioning with an enormous negative value for the top
property. This value will
actually make the text disappear from the page.
Then comes our navigation menu.
The first declaration of the third rule turns our unordered list into a table.
Since we're working now with tables, we should be sure that there will be no extra space
between the cells. For that reason, we use the border-collapse
property set to
collapse
. By doing so, the borders of the single cells will collapse to form an unique
border. Tables can be floated and absolutely positioned, since they're actually block-level elements or,
more precisely, elements that work in a block-level formatting context.
Our menu will be absolutely positioned on the right and with a left border. Its height will equal the
height of its container, while its width will be 15% of the container's width.
Now we need table rows to host our cells. We turn the list items into table rows by declaring
display: table-row
on each li
element.
Finally, we create the table cells in the fifth rule by declaring
display: table-cell
on the a
and strong
elements.
The border of these cells will collapse to form an unique border, as said above.
The width of the cells will be 100% of the total, plus a 0.3em of left and right padding.
In case you're wondering, the content of the cells will not overflow its container because of the
type of table layout set on our menu. Tables can have two types of layout, controlled by the
table-layout
property: auto
and fixed
. The first value
is used by default on all tables and it's used also on our menu. With this value, the global width
of the table will be determined by the width (and the content) of its single cells. In other words,
we have a fluid table that will expand automatically together with its cells.
The sub-header
The sub-header is marked up as follows:
<div id="subheader"> <p id="issue">Issue 1, August 2008</p> <form id="search" action="#"> <div> <label for="text">Search:</label> <input type="text" name="text" id="text" /> <input type="submit" id="btn" name="btn" value="Go" /> </div> </form> </div>
We want to put the #issue
element on the left and the search form on the right.
The code could be the following:
#subheader { display: table; width: 100%; height: 1.4em; border-bottom: 1px solid #000; font-size: 120%; } #subheader #issue { display: table-cell; width: 30%; vertical-align: middle; font-weight: bold; padding: 0 0.5em; text-transform: uppercase; } #subheader form { display: table-cell; width: 68%; text-align: right; vertical-align: middle; padding: 0.5em; } #subheader form label { font-weight: bold; } #subheader form input { font: 1em Verdana, sans-serif; } #subheader form input#text { border: 1px solid #000; background: #fff; color: #333; } #subheader form input#btn { background: #800; color: #fff; font-weight: bold; border: 1px solid #800; }
View the example - View the screenshot
The first rule turns the sub-header section into a table, sets a global height and width
plus a bottom border. The second rule turns the #issue
element into a table cell, sets
a width on the element plus the vertical alignment of the text inside the cell (middle
).
The third rule turns the form into a table cell. As for the previous element, also in this case
the vertical margins of this element will be resetted, since table cells cannot have vertical margins.
The width of this element covers almost all the available space and this is actually our intended
purpose. In fact, with the declaration text-align: right
we push the form elements to
the right of the sub-header, as we do want. Also in this case the elements will be vertically
aligned, thanks to the declaration vertical-align: middle
.
The fifth rule deserves a further explanation: since the dimensions of form elements are determined
also by the type and size of the used font, a good way to get consistency across browsers is an explicit
declaration of font type/size on the elements we want to format (in this case, input
).
The post title
The markup for this section is really simple, as you can see below.
<div class="art-title"> <h2>Lorem ipsum</h2> <p class="date">8/17/2008</p> </div>
The post title has been inserted through a h2
element and the date of the post is
marked up with a paragraph having .date
as its own class. The styles could be the
following:
.art-title { background: #800; color: #fff; display: table; width: 100%; margin-top: 1em; padding: 0.3em 0; } .art-title h2 { font-size: 1.4em; display: table-cell; width: 40%; vertical-align: middle; color: #fff; padding-left: 3px; } .art-title .date { display: table-cell; width: 60%; vertical-align: middle; text-align: right; padding-right: 3px; font-style: italic; font-weight: bold; }
View the example - View the screenshot
Again, we've turned the outermost container into a table and its children into table cells.
The vertical alignment of the text is controlled by the vertical-align
property.
The width of each element can be adjusted in order to satisfy particular needs. In this case,
we could change the value 40% with 60%, since the content of a date doesn't require so much space.
looks good if used as templates blogspot ... xixixi