justuptime.com - monitor your servers & websites

Creating a semantic FAQ page with definition lists and advanced CSS, Part 1

Most websites have FAQ pages, but few put much effort into creating an attractive and usable interface. This article will explain one method of creating a nice FAQ page using definition lists with advanced CSS and JavaScript.

Why definition lists?

I wasn't sure at first what to use for the mark-up for this page. It is definitely a list of questions (as opposed to some headers and paragraphs), so that narrowed it down. The list items are made up of two parts: a question and an answer. Definition lists seemed to match this description, although questions and answers are not exactly definitions.

To be sure, I consulted the W3C specification on definition lists. Towards the end of their description, they note that definition lists can be used for marking up dialogue with the dt containing the speaker's name and the dd containing the words spoken. Well, if you can use a definition list for that then it certainly makes sense to use it to mark up a set of questions and answers.

Step 1: Create the definition lists

First we'll mark up all our questions and answers as definition lists. The code looks like so:

<dl> (start the list)

     <dt>This is the first question</dt>
     <dd>This is the answer to the first question</dd>

     <dt>This is the second question</dt>
     <dd>This is the answer to the second question</dd>

    <dt>This is the third question</dt>
    <dd>This is the answer to the third question</dd>

</dl> (end the list)

File: faq1-basicstructure.html

Step 2: Applying some simple CSS

This looks like a jumbled mess, so we need to add some CSS to make it look a little nicer. We want to remove the indent on the dd, make the question (dt) bold, and add some spacing around both elements:

dt {
     font-weight: bold; 
     margin: 15px 0;
}
dd {
    margin: 10px 0 30px;
}

Our list now looks pretty good on it's own. It's a basic question and answer format, easy to read and understand with no bells and whistles. But wouldn't it be fun to play a bit and make this look a little more interesting? Lets try that next.

File: faq2-basicCSS.html

Step 3: Advanced CSS Wizardry

Now it's time to have some fun. When browsing around for good examples of FAQ pages, I admittedly didn't find much inspiration. However, I did see a few examples with a big Q and A next to the questions and answers (respectively). I thought this looked nice. It was a good way to make the page look more interesting and add some visual indicators for each part of the question.

Choosing a method

So what would be the best way to do this? I could just put in the Q and A as text, wrap them with a span tag, and style them accordingly. Then I have to go though my whole list and put in a Q and A before every question, and this isn't exactly meaningful semantic text anyway. It could be, if you wanted to look at it that way, but I wanted to try something more interesting.

I could also do them as background images and align them to the side of the dt and dd tags. It is kind of silly to put text in a background image, don't you think?.

What I needed is some way to insert the letters before the dt and dd elements. Well, what do you know, CSS 2 includes that very functionality with the :before pseudo-element. The biggest problem is that :before and :after are not supported by Internet Explorer, even in version 7.

I decided that this wasn't a big problem for me. The letters are just extra visual elements that don't affect the usability of the page. For the site I am working on, about 30% of visitors are using Firefox, Opera, and Safari so they will see the letters. Other visitors will get a plain list of questions and answers. No problem! (and if you do feel that it's important for your IE users to see the letters, you could aways use the inline Q & A solution that I mentioned above). This is one of the many wonderful things about CSS: you can easily provide extra bells and whistles without compromising the experience for user agents that don't support it.

How to do it:

It's actually pretty simple. All we need to do is apply the :before pseudo-element to the dt and dd tags, then add in the generated content. This is what it looks like:

dt:before {
     content: "Q";
}
dd:before {
     content: "A";
}

File: faq3-advancedCSS-before.html

Ta-da! Now we've got our Q and A displaying before our questions and answers. All we need to do now is add some ordinary CSS to make them look pretty:

dt:before {
     content: "Q";
     font-size: 2.5em;
     font-family: Georgia, "Times New Roman", Times, serif;
     margin-right: 5px;
     padding: 0 8px 5px 8px;
     color: #FFD87D;
     background-color: #BD4A18;
     font-weight: normal;
}

dd:before {
     content: "A";
     font-size: 2.5em;
     font-family: Georgia, "Times New Roman", Times, serif;
     margin-right: 5px;
     padding: 0 8px;
     color: #752E0F;
     background-color: #FFD87D;
}

File: faq4-advancedCSS-formatting.html

Lookin good! It would be nice if we could make this look even better by putting the letter in the left margin and aligning the text along a straight edge beside it (rather than wrapping around the letter as it currently does). This can be accomplished by applying some margins to all four selectors:

dt {
     font-weight: bold; 
     margin: 15px 0 15px 50px;
}

dt:before {
     content: "Q";
     font-size: 2.5em;
     font-family: Georgia, "Times New Roman", Times, serif;
     margin-right: 7px;
     padding: 0 8px 5px;
     color: #FFD87D;
     background-color: #BD4A18;
     font-weight: normal;

     margin-left: -48px;
}

dd {
     margin: 10px 0 30px 50px;
     }

dd:before {
     content: "A";
     font-size: 2.5em;
     font-family: Georgia, "Times New Roman", Times, serif;
     margin-right: 7px;
     padding: 0 9px;
     color: #752E0F;
     background-color: #FFD87D;

     margin-left: -48px;
}

The final problem we have is that the baseline of the letters line up with the baseline of the first line of text. It would be great if we could move that letter down so the top of it lines up with the top of the first line of text. Unfortunately, Firefox currently does not support positioning of generated content. As of the CSS 2.0 specification, this was correct behaviour: browsers were instructed to ignore float, position, list, and table properties on generated content. This restriction was removed in CSS 2.1, and positioning of generated content is supported by Opera and Safari.

Since we have already decided that it's okay if the page doesn't look perfect in all browsers, we can apply some positioning to the letters that will only be displayed in browsers that support CSS 2.1 (Opera and Safari). What we'll do is position the letter relative and move it up a few pixels. This code goes on both the dt:before and dd:before selectors:

position: relative;
top: 13px;

Finally, I added a few more properties just to make things look a little nicer: a line-hieght on the dd so that there wasn't a noticeable gap after the first line, and a bottom border just to provide an extra visual marker between questions. My final CSS looks like this:

dt {
     font-weight: bold; 
     margin: 15px 50px 5px;
}

dt:before {
     content: "Q";
     font-size: 2.5em;
     font-family: Georgia, "Times New Roman", Times, serif;
     margin-right: 7px;
     padding: 0 8px 5px 8px;
     color: #FFD87D;
     background-color: #BD4A18;
     font-weight: normal;

     margin-left: -47px;
     position: relative;
     top: 13px;
}
 
dd {
     margin: 25px 50px 0px;
     border-bottom: 1px solid #ccc;
     padding-bottom: 20px;
     line-height: 150%;
}

dd:before {
     content: "A";
     font-size: 2.5em;
     font-family: Georgia, "Times New Roman", Times, serif;
     margin-right: 7px;
     padding: 0 9px;
     color: #752E0F;
     background-color: #FFD87D;

     margin-left: -47px;
     position: relative;
     top: 13px;
}

File: faq5-advancedCSS-positioning.html

So that's it: a semantic FAQ list with some CSS fun. In the next part of this series, we will create a way to easily navigate the FAQ list withouthaving to scroll through the whole thing. We will look at two methods ofdoing this this: a simple HTML list with some basic CSS, and a dynamic JavaScript hide and show display.

References

AttachmentSize
faq1-basicstructure.html6.06 KB
faq2-basicCSS.html6.13 KB
faq3-advancedCSS-before.html6.2 KB
faq4-advancedCSS-format.html6.55 KB
faq5-advancedCSS-position.html6.79 KB
Megan McDermott's picture

About the Author

Megan is co-founder and editor of A Padded Cell and lead administrator at The Webmaster Forums. She has been designing websites for over 10 years and is currently Manager of Web Communications at the University of Waterloo. In her spare time she likes practicing yoga and being nice to the environment. Read her web design blog at MeganMcDermott.com.