You are looking at archived content. The hot new stuff is happening at Veerle's blog 3.0. You should check it out!

Nov 22

Div thinking cap

2005 at 05.53 am posted by Veerle Pieters

Time for a bit of CSS styling fun! When working with CSS you need to have the ability to analyze your layout and see how you would place your div containers. That’s what differs from working with a classic table layout. You need a whole different approach and think more in terms of containers. Stop thinking of how you’ll slice your layout, start thinking on how to put each graphic into a container… How much containers do I need without overdoing it?

At Duoh! we've recently finished this site and I think this would suit as the perfect example to show you what I mean. Below is an image that shows the different containers of the basic template layout.

SlimBouwen website, analyzing the divs

Which background will be used for the body?

First I need to define what will be used as background for the body element. Is it the blue border or the vertical shadow lines on each side of my layout? The answer is the shadow lines. Why? Because you always have to look for the most simple solution. We put the blue background in a container and give that container a width of 100% and a height of 191 pixels which matches the exact height of the header and use the shadow lines as a body background. I'm sure there are other approaches to achieve the same result, just try to keep it as simple as possible and try to limit the nested divs as much as possible. Here's the result so far. Our styles consist of this :

  1. body {
  2. background: #fff url(../images/bg-body.gif) top no-repeat;
  3. margin: 0;
  4. padding: 0;
  5. }
  1. #headerwrapper {
  2. background: #ecf3f9;
  3. width: 100%;
  4. height: 191px;
  5. position: relative;
  6. }

Build the header

Next on the line is to build the header. Since the shadow lines are now hidden (under the blue border), we have to make sure to include them in our header background but not the logo. The logo will be added on top of this header. Why you ask again? Since it's better to threat the logo separately so we can add a rollover effect and a homepage link to it. Second reason and actually a more important reason is that we add a header 1 element to our logo which will the main title of our site. Using a text-based header 1 element (instead of placing a graphic) is very important for accessibility reasons and good for SEO as well. Here is the structure of our structural code:

  1. <div id="headerwrapper">
  2. <div id="header">
  3. <div id="logo">
  4. <h1>Slimbouwen - Bent u klaar om te bouwen?</h1>
  5. </div>
  6. </div>
  7. </div>

And this is the CSS so far:

  1. #header {
  2. width: 772px;
  3. height: 191px;
  4. background: url(../images/bg-header.jpg) no-repeat right top transparent;
  5. display: block;
  6. margin: 0 auto;
  7. }
  1. #logo h1 {
  2. width: 228px;
  3. height: 174px;
  4. display: block;
  5. margin: 0 0 0 11px;
  6. padding: 0;
  7. text-indent: -99999px;
  8. background: url(../images/logo.gif) no-repeat right top transparent;
  9. }

Adding a link with rollover effect to the logo

We also want a link on our logo title and we love some effect too. With background positioning we can! You've noticed that our logo image includes both the default and rollover state. This is needed for this technique. This way there is no (loading) delay when people mouse over the logo. Here is the CSS to achieve this effect

  1. #logo h1 a {
  2. width: 228px;
  3. height: 174px;
  4. display: block;
  5. text-decoration: none;
  6. }
  1. #logo h1 a:hover {
  2. background: url(../images/logo.gif) no-repeat right bottom transparent;
  3. }

By using display block and set width and height measurements, you make sure that the entire area is covered. To achieve the rollover effect we add hover selector and alter the position of the background to bottom right.

Adding the content

You'll noticed that I totally ignored the description text in the logo image. This text is actual content and should be placed in the code below the header 1 element between paragraphs. Again I need to make sure this text isn't visible. This is the CSS I use to do so:

  1. #content {
  2. width: 772px;
  3. margin: 0 auto;
  4. }
  5. p.hidden {
  6. position:absolute;
  7. top:-300px;
  8. left:0;
  9. }

First I add an id for the content area and give it the width (same as the header id) and make sure it is centered aligned. Within the content div id will come all our content text. Next step is adding a style for the paragraph and give it a class (hidden) since this is an 'exceptional' paragraph of text. We want to exclude this from the rest of our 'normal' paragraphs. The absolute positioning and top and left coordinates make sure the text is outside the viewing area of my browser window. This and the method of using a negative text-indent (as used for the header) are by my knowledge the only CSS tricks I know, and which I think are better then using display:none or visibility:hidden.

Implementing the special button

Last but not least is the tabbed button. As this button is at a specific position, we use top and left coordinates to make sure it appears on the exact place. But we can't use absolute positioning since this would mean that the button stays at this location even if we resize our window. That's why we use relative positioning. This way the left and top coordinates are always in reference with the container it is in. In our example that is the content div container since the button is part of the content. This is the structural markup:

  1. <div id="content">
  2. <p class="hidden">Hoe krijgt u het meeste huis voor uw geld?... </p>
  3. <div id="testnav">
  4. <ul>
  5. <li><a href="quiz1.html">Doe de test</a></li>
  6. </ul>
  7. </div>
  8. </div>

Here is the CSS I have added:

  1. #testnav ul {
  2. width: 173px;
  3. height: 35px;
  4. position: relative;
  5. top: -25px;
  6. left: 289px;
  7. }
  1. #testnav ul li a {
  2. background: url(../images/bttn-doe-de-test.gif) no-repeat top left;
  3. width: 173px;
  4. height: 35px;
  5. display: block;
  6. text-indent: -9999px;
  7. text-decoration: none;
  8. }
  1. #testnav ul li a:hover {
  2. background: url(../images/bttn-doe-de-test.gif) no-repeat bottom left;
  3. }

Again I'm using background positioning to create the rollover effect. Here is the final result.

After revising everything in I.E. 6 it seems I need to add this little fix:

  1. * html #testnav ul {
  2. top: -35px;
  3. }

The star html makes sure only I.E. reads this style. You could of course also use conditional comments in the structural markup to implement this fix. It just all depends what the outcome will be once I.E. 7 is released.

Feel free to play the quiz if you can read Dutch or go to BâtirMalin if you prefer the French version. Sorry no English version, it is a Belgian site and aimed to Belgians only.

UPDATE This article is now also available in Portuguese.




permalink this comment David Tue Nov 22, 2005 at 07.15 am

This is very interesting - thank you (as well as timely - I’m about to slice up a photoshop document for this purpose also!).

I’m dying to attend Dave Shea’s workshop in London this January where he goes from Photoshop document to live HTML and CSS in 90 minutes or something ...

thanks again.




permalink this comment Benjamin Tue Nov 22, 2005 at 07.35 am

Nice article!

I do tend to use the min-height CSS property (it doesn’t work in IE, but it gracefully fails) so the layout isn’t squished too much to the top on larger screens.




permalink this comment huphtur Tue Nov 22, 2005 at 08.01 am

[slightly offtopic]Why didn’t you use label’s for the radioboxen?



permalink this comment Magicsoul Tue Nov 22, 2005 at 08.32 am

Wow, cool artilce Veerle, thx for all.

i have a only question…

you desing all the web in photoshop and later cut (with sectors)?

or you make image by image (in photoshop), background, body, buttons, etc…



permalink this comment Veerle Tue Nov 22, 2005 at 11.53 am

@Benjamin, the page described in this article isn’t finished so normally we have some content below the header and the tabbed button. But yes min-height is a nice solution indeed.

@huphtur, it seems that this caused some problems since every radio button requires its own id and because each Q&A is dynamically generated (the client can adjust/add/delete the Q&A). The system was generating the same id for each Q&A group. I’m not sure if this is easy solvable.

@Magicsoul, I design the layout in Photoshop and then I export each image I need to jpeg or gif. I use the eye icon in the layers palette, to hide certain layers if necessary (for example for exporting the background image), I select the area I need to export and hit command+shift+c (=Copy Merged) then I paste this in a new Photoshop document (or I fire up FireWorks since this app gives better jpeg compression), I paste my image and export it to the best possible jpeg or gif. As for the logo and tabbed button, I do the same but I enlarge my canvas size by doubling its height and I paste the rollover effect below the default image. Hope this answers your question.



permalink this comment jean-christophe Tue Nov 22, 2005 at 03.30 pm

Hi Veerle!

I am really glad i read this article as i also use and found by myself some methods and tricks you use (it proves i am not a total idiot ^^).

Recently i have downloaded a copy of dreamweaver 8 demo to see how it could help me to increase my productivity. So far i only find really useful the panel to quickly access css properties instead of typing them and the ftp connection front-end. I disgress. I also use photosho to design and slice images and i was thinking to try out fireworks as weel to see if it could help me too. Do you have any advices to share about using fireworks instead of photoshop?




permalink this comment Chris R. Tue Nov 22, 2005 at 03.45 pm

Nice writeup on the positioning. I’m sure alot of us will find these techniques usefull ... on the other hand i think the design of the page (graphics wise) is brilliant. This is hands down a perfect example of what can be achieved with CSS styling and valid semantic markup in XHTML ... thumbs up veerle!



permalink this comment quinn Tue Nov 22, 2005 at 05.37 pm

Hi Veerle,

I have been enjoying reading your articles for some time. Thanks for all your sharing with us. Anyways, I usually try to make title and h1 of HTML document to discribe the page the best way it can and make it unique to each page in the site. However, I use probably too many of span tags to control which part of h1 should be displayed as text or graphic. I also use display:none. I like the way it is for now. Any suggestions?



permalink this comment Nicole Hof Tue Nov 22, 2005 at 10.54 pm

Hello Veerle,

How do you create the faded border? I’ve wanted to do this accurately for ages but with no luck. I end up using an outer glow then using the eraser tool… IT doesn’t look tapered like yours though.

Thanks for explaining the other points too.



permalink this comment Veerle Wed Nov 23, 2005 at 01.49 am

@jean-christophe, I’m afraid I am not a ‘real’ FireWorks user. It’s just that I have the app because I have the suite but I don’t use it much. I use it mostly to get a good jpeg compression (much lower size then Photoshop) and that’s it. I used to work with FW a lot years ago. It was perfect to slice and export my page. But that was back then when I used table-based layouts and javascript rollovers etc. All of this is totally past and a closed chapter.

@quinn, display:none is something you should try to avoid if possible because some screenreaders might actually skip this text, so blind people may not now it’s there. Also, in the future Google might penalize you, because this text might be seen as spam (since you’re not displaying it). At the moment things are fine, but who knows in the future?

@Nicole, I’ll explain this soon in a next article. Seems like a good idea ;-) I can tell you though that I add a mask to this layer, and I add a gradient to the mask to make the nice transition.



permalink this comment quinn Wed Nov 23, 2005 at 05.05 am

Oh, I think I need to try out those screen readers. I didn’t know about that one. Thanks for the tip. However, I’ve seen nasty spam with positioning text outside of the browser window. That was really aweful.



permalink this comment Tabitha Wed Nov 23, 2005 at 07.31 am

Veerle, great article once again. I’ve learned a lot bout CSS & semantics since discovering your blog. So now i’m striving to make my html & css as crispy and logical as possible (i still sometimes fail horribly, i admit) and in those optics i was wondering:  Is there a specific reason you added an ul around the “Doe de test”-button in #testnav, instead of putting the link directly in the div (and styling that)?



permalink this comment Damien Guard Wed Nov 23, 2005 at 08.41 am

One thing I will mention regarding usability and that site, though HTML not CSS is that of using the <label> tag.

If you go this this page you will see there are a number of radio buttons to be filled in.

It is a good idea to actually associate the label text with the corresponding input element, in this case the radio buttons.  As well as those using impaired browsers being able to tell which control relates to which field it also means that you can click the label and it will either set the focus or set/toggle the field itself depending on the type.

Taking that page for example, the following snippet;

<td><input name=“a3” value=“5” type=“radio”></td><td>4 m</td>

should become

<td><input name=“a3” value=“5” type=“radio” id=“a3id”> </td><td><label for=“a3id”>4 m</label></td>

Oh, and form fields should use id’s now, name is being deprecated.




permalink this comment Veerle Wed Nov 23, 2005 at 08.55 am

@Damien Guard, I have already commented why I haven’t used labels (see 5th comment, answer to huptur). Like I said the system generates the same id for each Q&A group. So the problem is that I need a unique id for every radio button :-S So I don’t know how to solve this, I’m no PHP expert. I’m even wondering if this is possible?



permalink this comment lazymouse Wed Nov 23, 2005 at 08.58 am

Thanks again for the info - as you know, your CSS tutorials have convinced me to get away from tables and I don’t think I could design a site in tables anymore if I tried!

I urge all designers to ditch tables and use CSS - it’s a steep learning curve, but worth it in the end.

I look forward to more on this, Veerle, thanks again!




permalink this comment Biggi Wed Nov 23, 2005 at 09.03 am

Very nice article.
I like these articles which describe the process of coding step by step. And I learn a lot from them. Thanks - and more of them please.



permalink this comment Leonieke Wed Nov 23, 2005 at 12.35 pm

great explanation - I’ve been looking for one for quite some time.

who knows, now I might even start using CSS for real!



permalink this comment Roger Johansson Wed Nov 23, 2005 at 02.50 pm

@Veerle: If the system can’t be tweaked to generate unique id values for each radio button, you could put the radio buttons inside the label element:

<label><input type=“radio”>Label text</label>

Better than not having labels at all :-).



permalink this comment vanni Wed Nov 23, 2005 at 03.43 pm

nice veerle. one question: why does the page “shift left” as you click on tehe various buttons on teh left hand side of the main page: Start,  Schrijf, Contacteer?



permalink this comment koen Wed Nov 23, 2005 at 11.20 pm

A unique id with php is not hard, but I don’t know how you build the list. If there’s a loop, you can use a variable that is incremented and use that to assign a unique id. Eg: loop with $x always +1, in that loop id=“somename_$x” or something like that. Don’t know how usefull that is as I don’t know exactly what you’re using. Just goes to show that with a loop this could be a way of assigning a unique id.



permalink this comment Veerle Thu Nov 24, 2005 at 03.08 am

I have been able to fix the labels, thanks to Damien who helped me by e-mail. Thanks a lot ;-)

@vanni: hehe, I think it’s because on the homepage you don’t have a scrollbar, but once you go to another page the scrollbar appears. This takes some room of the browser window and because the layout is centered it moves to the left a bit, so you get the illusion that the page shifts. That’s all there is ;-)



permalink this comment martin Thu Nov 24, 2005 at 04.55 am

Thanks for this superb artcile.



permalink this comment Ber Thu Nov 24, 2005 at 06.46 am

Malarkey and Eric Meyer had a shot at some default layer system. They deconstructed a whole lot of sites and came up with a very good set of Divs and classes that you can use for most sites.



permalink this comment lazymouse Thu Nov 24, 2005 at 09.02 am

@vanni @veerle ... I found a neat trick to avoid that annoying shift when navigating from one page that has a scrollbar to one that doesn’t. (and vice versa).

I found it the other day and it seems to work fine, I’m afraid to say that I can’t remember who noted it originally, but thanks to whoever you are anyway!!

Here’s the CSS:

html {



permalink this comment vanni Thu Nov 24, 2005 at 10.17 am

@lazymouse. I am glad i asked! nice trick! I can use that…



permalink this comment Diego Sat Nov 26, 2005 at 08.08 am

Great article… and… I love you.



permalink this comment jason Mon Nov 28, 2005 at 09.53 am

Nice article.  I’ve been following this site for a while and the css articles have really helped out a lot.  I’m going to be using a lot of what I’ve learned here when I convert my site to a nearly-pure CSS design.

One thing i’m curious about though is having the rollover images as a single file that is “shifted” either vertically or horizontally on the mouse-over/hover.  Why is that?  I see the same thing used a LOT in CSS design and I don’t really understand why it’s preferred over using two seperate images as is/was normally done when using javascript mouseovers for the same rollover effect. 

You mentioned doing it that way so there’s no load delay on the first mouseover, but is that the only reason?  Why not use javascript to preload the rollover images so there’s no delay (which is what I do on my site)?  Or is getting away from javascript part of the purpose?



permalink this comment Veerle Mon Nov 28, 2005 at 10.55 am

@jason, yes it’s also because with this technique you don’t need javascript. Your code stays very clean and it’s also better for accessibility. Using javascript with preload etc. is more of a hassle compared to this technique. And if you keep things textbased then you don’t have to use Photoshop if you need to add a button in your navigation. Just type the extra list and that’s it, very flexible. If the navigation is graphically then it’s better to have just one file (the entire navigation with all the mouse states) instead of several separate gifs 1 for each button and again each state. It’s much easier to maintain.



permalink this comment giovanni Mon Nov 28, 2005 at 12.11 pm

@ray. thnx. But i think i would rather stick with Open Source stuff as much as possible. (although, like Veerle, i do use pMPro and soon will be using EE… both of them retail SW using PHP). ColdFusion leaves me well cold & unconvinced… If i were to switch from PHP it would most likely be to the very enticing RubyOnRails ...



permalink this comment Mario De Zutter Mon Nov 28, 2005 at 02.50 pm

Great article, and i use it on my website.

But how can i make it scalible?



permalink this comment Ray Williams Sun Dec 4, 2005 at 02.09 pm

I know I’m a bit late commenting here, but I just wanted to say a quick thanks for the article. Especially some of your CSS you spelled out for hiding text:

p.hidden {

I had always used “margin-left: -10000px;” before but found that it would sometimes, inexplicably, leave a 1px line all the way over to the hidden text in certain browsers. I was hung up with a design because of that problem until I ran across this article. I used “position:absolute; top:-300px;” and now the ugly line no longer appears! Thanks so much.



permalink this comment Marc Kohlbrugge Sat Dec 17, 2005 at 11.07 am

Hi Veerle,

I spotted an error on the BâtirMalin-website. When you take the quiz and don’t answer a question it says:

“Votre réponse: geen antwoord gegeven”



permalink this comment Veerle Wed Dec 21, 2005 at 09.51 am

@Marc kohlbrugge: I fixed it. Thanks for spotting this ;-)



permalink this comment Fred Tue Jan 3, 2006 at 06.35 am

Hi Veerle,
I found your weblog by random and I’m happy to have find it. Very nice tutorials.

But now, I’m posting a comment about the french version of SlimBouwen: there is a lot of french nonsenses. I guess it’s because the translation but some words don’t exist in french. (ie “optimaliser” standing for “optimiser” and a few others). Really, you should correct them or maybe change of localization partner (Systran? ;-) )




permalink this comment Veerle Tue Jan 3, 2006 at 06.56 am

Hi Fred, thanks for mentioning this, I’ll pass it on when time permits. The translation was not our responsibility, the client delivered us the text. The content/idea/text etc. was something another partner took care of in association with the client. We just designed and developed the site, so we did purely the production work.



permalink this comment Donny Burnside Fri Mar 10, 2006 at 09.03 am

Hey, just want to thank you on a great article. This has been useful to me already.



permalink this comment barberboy Tue Apr 18, 2006 at 03.37 pm

Thanks for the article, Veerle.

Just so you know, Opera 8 has a maximum negative text-indent value. So the text-indent: -99999px; causes a huge horizontal scrollbar in Opera 8, in addition to the :hover effect being lost. Chilling out a little and keeping it below (or above, i guess) -30000px makes everyone play along nicely. (Alternatively, you could add overflow:hidden;, but you don’t need to add it if you just trim the negative text-indent.)

Thanks again, Veerle. Peace.




permalink this comment barberboy Tue Apr 18, 2006 at 03.49 pm


And apparently clicking “Preview” in my Opera 8 is the same as clicking “Post Comment.” Sorry for the mess!




permalink this comment Veerle Wed Apr 19, 2006 at 01.29 am


And apparently clicking “Preview” in my Opera 8 is the same as clicking “Post Comment.” Sorry for the mess

It still does the same in Opera 9 but not in any other broswer such as firefox, IE, safari, camino etc. So it’s a browser bug in Opera as far as I can see.

Commenting is not available in this weblog entry.


buy something from my Amazon wishlist