SYSK 185: CSS as a Replacement of Tables? Yes!

Did you know that you can design complex web pages without a single table by using cascading style sheets?  Generally, this type of design results in smaller (as measured in downloaded bytes) pages, and (arguably as, if not more, importantly) pages that are easier to understand and maintain because it allows for a clear separation of content and formatting.


But first, one must understand CSS selectors, which is the topic of this post.


There are four kinds of CSS selectors:

  1. Tag selectors – the defined formatting applies to elements with matching type; e.g. div { … } will apply to all <div>…</div> elements

  2. Class selectors – formatting applies to all elements that use that class name; e.g. .redText { color: red; } will apply to all elements that have matching class attribute as in <div class=”redText”>Hello World!</div>. Note: you can specify multiple class names separated by space, e.g. <div class=”contents evenrow value”>123</div>

  3. Id selectors – formatting applies to a specific element with that id; e.g. #PageHeader { … } will apply to an element with id  PageHeader as in <div id=”PageHeader”>XYZ</div> 

Note:  HTML elements on the page must have unique ids.

  1. Composite selectors – a combination of the above.  Note:  the order in which the tags appear will match the html element flow.  For example,

#PageHeader .redText span


color: blue;



will apply blue color formatting whenever a span element is found as an inner element of another element with class=”.redText”, which, in turn, is an inner element of an element with id=”PageHeader”


Here is an example:

<style type=”text/css”>

    #PageHeader { font-size: 20px; }

    .redText { color: red; }

    #PageHeader .redText span { color: blue; }



<div id=”PageHeader”>

    <p class=”redText”>

        <span>Blue Text</span>

        Red Text


    <span>Guess what color 🙂</span>


Other text


results in:

Blue Text Red Text

Guess what color 🙂

Other text


Another common variation of a composite selector is:

#SomeID div.myclass

which applies to all DIVs of class=”myclass” that are inner elements of an element with id=”SomeID”



Finally, you can apply the styling based on a behavioral attribute, e.g.

#SomeID a:hover

results in applying the rule to all links inside the element of id=”SomeID” but only when the mouse is hovering over.



So, check this out…  The following CSS/HTML produces the result below:


<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “”>

<html xmlns=”” >


    <title>CSS Demo</title>

<style type=”text/css”>



        width: 200px;

        border: 1px maroon solid;

        border-bottom: 0px;

        font-family: Verdana, Arial, Helvetica, Sans-Serif;


    #LeftSideBar div.header


        background: maroon;

        color: white;

        font-size: 110%;

        font-weight: bold;

        padding: 2px 0;

        text-align: center;


    #LeftSideBar div.contents


        background-color: #FFD9D9;       


    #LeftSideBar a


        display:block;  /* turn an inline link element into a block element, so the entire area is clickable */

        color: #0C0C0C;

        font-size: 80%;

        padding: 3px 3px 3px 5px;

        border-bottom: 1px maroon solid;

        text-decoration: none;


    #LeftSideBar a:hover    /* invert the back-color and fore-color when mouse is hovering over */


        background-color: #C0C0C0;

        color: white;

        font-weight: bolder;


    #LeftSideBar a.selected


        border-right: 8px maroon solid;


    #LeftSideBar a.selected:hover


        color: #0C0C0C;

        background-color: #FFD9D9;





    <div id=”LeftSideBar”>

        <div class=”header”>Possible Options</div>

        <div class=”contents”>

            <a href=”HTMLPage.htm”>Option 1</a>

            <a href=”HTMLPage.htm”>Option 2</a>

            <a href=”HTMLPage.htm”>Option 3</a>

            <a href=”HTMLPage.htm” class=”selected”>Option 4</a>

            <a href=”HTMLPage.htm”>Option 5</a>






Stay tuned for tomorrow’s post for more on using CSS instead of tables.


Special thanks to Erik Saltwell who introduced me to the better way of designing web pages by using CSS instead of tables.



Comments (7)

  1. Good example… but i think ul/li layout is better

  2. Greg says:

    That’s great, now do a complex form layout for me… say 30 field and label sets of varying sizes or and make sure it renders completely in IE6 and 7, and Firefox.

  3. Rosyna says:

    Except Internet Explorer doesn’t support display:table, display:table-cell so you cannot use any css selectors that only effect real tables like vertical-align.

  4. Patrick Rikhof says:

    For webpages this is great, but not for html e-mail.

    Many webmail clients filter CSS. I bumped into that last week when i tried to send an image in an email with text over the image (z-index). Wasn’t possible with css in Hotmail/msn, yahoo and g-mail. Creating a table with a background image resolved my problem.

  5. Adam says:

    Hmmm….you could at least use their proper names and link to the relevant part of the spec for people to find out more on their own. According to:

    there are:

    Type selectors ("Tag selectors")

    Descendent selectors ("Composite selectors")

    Child selectors (not mentioned)

    Adjacent sibling selectors (not mentioned)

    Attribute selectors (of which "Class selectors" are a subset)

    ID selectors (Hey, you got one right 🙂

    plus pseudo-classes and -elements.

  6. nd says:

    As you have it, the code does not need to dispense with tables.  The advantage of tables is that legacy systems can use them, even if they can’t use CSS.

     The following code changes are rudimentary, but still allow table formatting, for older browsers:

     #LeftSideBar td.header

     #LeftSideBar td.contents

    instead of

     #LeftSideBar div.header

     #LeftSideBar div.contents

    then changed the three div tags to table formatting, you would end up with the same results – modern, yet supporting legacy.

  7. Adam says:

    Hmmm….the collection of links you have there appears to be a list – so a better way than to use tables for that would be to use an appropriately styled HTML list.

    By using either "ol" or "ul" as the container and setting "list-style-type: none" on it, and then using styled "li"s ("display: block" to override the default "display: list-item" and get rid of the bullets/numbers, you might also have to set margins and padding) for each list item, the content is even more semantically correct, which means that older browsers, screen readers, braille readers, HTML->{Docbook,pdf, word} converters, etc… will do even better at figuring out what you’re trying to convey.

    Using "div"s for /everything/ is almost as bad as using tables for everything. Part of the point of separating presentation from content is that you can make the content meaningful. "div"s aren’t meaningful; they have no semantics at all.