main content, site navigation, search

Episode Four: Create bullet-proof, eco-friendly CSS

This is the fourth part of the series, “Environmental friendly CSS

In the previous episodes we’ve created a creative/technical brief, mocked-up design in Photoshop and decided on proper markup for the category cloud. Finally, we turn our design into web page element with some nifty CSS.

For those of you who better understand from live examples, here’s a little treat for you. If you’re beginner in CSS, read on.

From the outside to the inside

It is common sense to most of us, but nevertheless here’s an advice — don’t get into details too early, because you will have to go forth and back in the code too often.

Let’s pull the markup on stage:

<div id="categories">
	<h4>Most popular joke types and categories</h4>
	<ul>
		<li><a href="#">Political jokes</a></li>
		<li><a href="#">Professional humor</a></li>
		<li><a href="#">Mathematical jokes</a></li>
		<li><a href="#">Ethnic jokes</a></li>
		<li><a href="#">British tell jokes</a></li>
		<li><a href="#">Self-deprecating humor</a></li>
		<li><a href="#">Blonde jokes</a></li>
		<li><a href="#">Redneck jokes</a></li>
	</ul>
</div>

First set-up the main frame: set the dimensions and positioning of the <div id="categories">. The width is fixed, but we let the height stay flexible, so if more content gets in there in the future, the box won’t break.

If you haven’t done so yet, Download .PSD file and open it with Photoshop.

The rounded box has a width of 300px, so here the CSS goes:

#categories { width: 300px; }

The area below links to the bottom of the lowest character shadow is approximatelly 275px high. We add bottom padding, so there is always plenty of room for the comic dialog, no matter how many links is displayed:

#categories {
    width: 300px;
    padding-bottom: 275px;
}

Next, slice the top part of the box, name it box-top.gif and Save it in the same folder where the CSS file resides. It should look something like this:

Now add background to the box:

#categories {
    width: 300px;
    padding-bottom: 275px;
    background: #000 url(box-top.gif) no-repeat 0 0;
}

Detail 1: the heading

We are not going to use the copy in the markup. Instead, there is a dialog bubble which is supposed to do the communication.

You’ve noticed that the bubble (i.e. h4) is off-set to the right. We have also set fixed width to <div id="categories">. With position: absolute we’re going to shift the bubble outside the box. It will not break layout because absolute positioned elements are out of the document flow, which means they don’t affect their surrounding elements.

We already made some room for the dialog with bottom padding. Now we only have to add one more rule to <div id="categories"> so we can position h4 relatively to the container:

#categories {
    width: 300px;
    padding-bottom: 275px;
    background: #000 url(box-top.gif) no-repeat 0 0;
    position: relative;
}

Remember, we left 275 pixels in height, so we use it to dimension the h4. Width is set to 100% by default, since h4 is a block level element, but we need to push it outside the box, so we also need to increase its default with from 300 pixels (100%) to 350 pixels.

Finally, we use bottom and left CSS properties to set coordinates.

#categories {
    width: 300px;
    padding-bottom: 275px;
    background: #000 url(box-top.gif) no-repeat 0 0;
    position: relative;
}

#categories h4 {
    position: absolute;
    height: 275px;
    width: 350px;
    left: 0;
    bottom: 0;
}

Now, go back to Photoshop and slice the bottom of the box and the dialog. You should get 350 x 275 pixels .GIF. Name it — you guessed it — box-bottom.gif and Save it in the same folder where the CSS file resides:

Add background to CSS:

#categories {
    width: 300px;
    padding-bottom: 275px;
    background: #000 url(box-top.gif) no-repeat 0 0;
    position: relative;
}

#categories h4 {
    position: absolute;
    height: 275px;
    width: 350px;
    left: 0;
    bottom: 0;
    background: url(box-bottom.gif);
}

And shift the remaining text to the left, by text-indent:

#categories {
    width: 300px;
    padding-bottom: 275px;
    background: #000 url(box-top.gif) no-repeat 0 0;
    position: relative;
}

#categories h4 {
    position: absolute;
    height: 275px;
    width: 350px;
    left: 0;
    bottom: 0;
    background: url(box-bottom.gif);
    text-indent: -9999px;
    overflow: hidden; /* with this rule
        the container doesn't stretch to the left */
}

So far, so good: only the category links have been left to be done.

Detail 2: list of categories

At the beginning of the list styling, remove bullets and the default display behavior:

#categories {
    width: 300px;
    padding-bottom: 275px;
    background: #000 url(box-top.gif) no-repeat 0 0;
    position: relative;
}

#categories h4 {
    position: absolute;
    height: 275px;
    width: 350px;
    left: 0;
    bottom: 0;
    background: url(box-bottom.gif);
    text-indent: -9999px;
    overflow: hidden; /* with this rule
        the container doesn't stretch to the left */
}

#categories li {
    list-style: none;
    display: inline;
}

Then we tell text to go into center, add some padding to ul element and remove possibly inherited margins:

#categories {
    width: 300px;
    padding-bottom: 275px;
    background: #000 url(box-top.gif) no-repeat 0 0;
    position: relative;
}

#categories h4 {
    position: absolute;
    height: 275px;
    width: 350px;
    left: 0;
    bottom: 0;
    background: url(box-bottom.gif);
    text-indent: -9999px;
    overflow: hidden; /* with this rule
        the container doesn't stretch to the left */
}

#categories ul {
    text-align: center;
    padding: 1em 1.5em;
    margin: 0;
}

#categories li {
    list-style: none;
    display: inline;
}

And FINALLY add Comic Sans font to links:

#categories {
    width: 300px;
    padding-bottom: 275px;
    background: #000 url(box-top.gif) no-repeat 0 0;
    position: relative;
}

#categories h4 {
    position: absolute;
    height: 275px;
    width: 350px;
    left: 0;
    bottom: 0;
    background: url(box-bottom.gif);
    text-indent: -9999px;
    overflow: hidden; /* with this rule
        the container doesn't stretch to the left */
}

#categories ul {
    text-align: center;
    padding: 1em 1.5em;
    margin: 0;
}

#categories li {
    list-style: none;
    display: inline;
}

#categories li a {
    font-family: 'Comic Sans MS', sans-serif;
    text-decoration: none;
    color: #fff;
}

Links are now perhaps too crowded, so we tweak them with some right and left padding. Also don’t forget :hover and :focus states:

#categories {
    width: 300px;
    padding-bottom: 275px;
    background: #000 url(box-top.gif) no-repeat 0 0;
    position: relative;
}

#categories h4 {
    position: absolute;
    height: 275px;
    width: 350px;
    left: 0;
    bottom: 0;
    background: url(box-bottom.gif);
    text-indent: -9999px;
    overflow: hidden; /* with this rule
        the container doesn't stretch to the left */
}

#categories ul {
    text-align: center;
    padding: 1em 1.5em;
    margin: 0;
}

#categories li {
    list-style: none;
    display: inline;
}

#categories li a {
    font-family: 'Comic Sans MS', sans-serif;
    text-decoration: none;
    color: #fff;
    padding: 0 .2em;
        /* equals to 2px if calculated font-size is 10px */
}

#categories li a:hover,
#categories li a:focus {
    text-decoration: underline;
}

Excellent! Here is the final working example. Go ahead, resize the text in your browser, or add more items — it won’t break. Everything is done except…

Different font sizes?

We miss one more thing — the different font sizes. But, it’s not done in CSS file, but with some inline HTML attributes. Basically, it all comes down to two approaches:

  • a set of distinctive class names or
  • inline styles.

Either way, you’ll have to do it server side or with JavaScript (both methods coming-up early in 2009.).

What have we learned?

With lean markup, but smart CSS, almost any design can be sliced to a high quality web interface. Not only that — we also managed to make it bullet-proof, so the various scenarios (text resize and different amounts of content) don’t break the layout.

5 shouts to “Episode Four: Create bullet-proof, eco-friendly CSS”

  1. Marko
    001—2008.12.18.12:33

    Now this is excellent! I’ve learned something new now. I used to have “Divitis” but now I’m cured :) Thanks.

  2. marko
    002—2008.12.18.12:37

    Haha, great! My mission is done :)

  3. Medo
    003—2008.12.18.13:33

    The CSS medicine man! I must say I’ve enjoyed reading your episodes from start to finish (this one is the icing on the cake) and its always nice seeing how other people approach things. Though do my eyes deceive me …. Comic Sans MS!!!!!!! :)

  4. zytzagoo
    004—2008.12.18.17:25

    Nice series! Keep it up!

    One tiny addition: if the order of the list items matters (that is, if the first item in the list really is the most popular joke type), I’d go with an ordered list (markup-wise).

  5. marko
    005—2008.12.19.05:48

    @Medo: Haha, every font has its place. Even if it’s only to shock/amuse friends… In fact I declare Comic Sans to be bold and provocative.

    @zytzagoo good point… if the first item is the most popular, then if styled respectively, we’d end with some kind of slanted texture, i.e. the most prominent words in the upper left, the less prominent bottom right.

    It would be nice to see an experiment (JavaScript perhaps) that would position list items randomly, so we still get the cloud pattern.

main content, site navigation, search