The perfect FAQ page ! – by Thierry Koblentz

— This was originally published on Visit the original site for updated code and to see a working copy of the script. Thierry has created a Dreamweaver plugin to make this super-easy to add to your site!

This is about using a Definition List and the DOM to create a nice FAQ page where clicking on the DTs (the questions) “toggles” the associated DDs (the answers).

Note: If you’re already using this solution, please check your version number (this is version 1.5.4). Before you download the newest version I suggest to go through the entire article again (since a few things have changed).

This is what it does:

Open AllClose All

Question 1?
The vitality of conceptual synergies is of supreme importance exploiting the productive lifecycle working through a top-down, bottom-up approach. To focus on improvement, not cost, from binary cause and effect to complex patterns, while those at the coal face don’t have sufficient view of the overall goals.
Question 2?
To focus on improvement, not cost, from binary cause and effect to complex patterns, while those at the coal face don’t have sufficient view of the overall goals. To ensure that non-operating cash outflows are assessed.
Question 3?
The vitality of conceptual synergies is of supreme importance exploiting the productive lifecycle working through a top-down, bottom-up approach. To focus on improvement, not cost, from binary cause and effect to complex patterns, while those at the coal face don’t have sufficient view of the overall goals. To ensure that non-operating cash outflows are assessed. The vitality of conceptual synergies is of supreme importance exploiting the productive lifecycle working through a top-down, bottom-up approach.
Question 4?
The vitality of conceptual synergies is of supreme importance exploiting the productive lifecycle working through a top-down, bottom-up approach. To ensure that non-operating cash outflows are assessed.
Question 5?
The vitality of conceptual synergies is of supreme importance exploiting the productive lifecycle working through a top-down, bottom-up approach. To focus on improvement, not cost, from binary cause and effect to complex patterns, while those at the coal face don’t have sufficient view of the overall goals. To ensure that non-operating cash outflows are assessed.

The main advantages of the basic technique (related to the DL):

  • It uses semantic markup.
  • It degrades nicely (hidden elements are visible in script-disabled UAs).
  • DTs do not appear as links without script support.
  • It does not use inline event attribute (onclick()).
  • It does not require A elements in the markup.
  • It is screen-readers “friendly”.
  • It is keyboard “friendly”.
  • It is IE Mac compatible.
  • It relies on one single hook.
  • It allows the author to add/move/delete DT/DD pairs easily (there is no variable in the script to edit and there are no class or ID to include nor change).
  • It is “powered” by a very light script (3Kb).

About the “Show All/Hide All” “links”:

  • they let the user expand all answers at once, so it is possible to search the document.
  • they are hidden from Javascript-challenged browsers.
  • they can be “Named Anchors”, images or SPANs (actually they can be any inline elements or any other elements styled as inline).

This is more or less a plug-and-play solution (script and stylesheets are at the bottom of this page).
You’ll need to:

  1. Create a Definition List (do not use more than one DD per DT.); the markup for the one above looks like this:

    Question 1
    The vitality of conceptual synergies...
    Question 2
    To focus on improvement, not cost, ...
    Question 3
    The vitality of conceptual synergies...
    Question 4
    The vitality of conceptual synergies...

  2. Assign a specific ID to your DL:

    <dl id="TJK_DL" />
  3. Download this ZIP File (3Kb) and unzip its content in the same directory as your FAQ page.
  4. In your FAQ page, right above the closing headtag cut and paste the following:
    <script type="text/javascript" src="TJK_ToggleDL/TJK_ToggleDL.js"></script>
  5. Call the script, for example using:

    <body onload="TJK_ToggleDL()">

    Note: In case you want to add multiple onload handlers to a page, make sure to read executing JavaScript on page load.

  6. In order to use the “Show All” / “Hide All” feature, you will need to create 2 named anchors with specific IDs (TJK_ToggleON and TJK_ToggleOFF). Dreamweaver users can take advantage of the “Named Anchor” icon in the toolbar to easily create the required markup. Dreamweaver will plug the name attribute as well, but that’s OK, you can either delete it or ignore it.
    This is the markup I’m using in this page:

    <a id="TJK_ToggleON">Open All<<a id="TJK_ToggleOFF">Close All</a>

    Note: adjacent anchors are confusing in text-browsers.

    important noteYou can also replace these Named Anchors with other inline elements, for example SPAN or IMG (yes, images). Just make sure to set the proper IDs.

  7. Because we want to hide these “links” from script-challenged UAs, you need to include the following rule somewhere inside your stylesheet:
    #TJK_ToggleON,#TJK_ToggleOFF {display:none}

    Note: You can also use a style element to include this rule in the head of your document (your FAQ page).

You’re done!

Feel free to edit the rules in the CSS file to fit your needs.

important noteNote: in case your questions are more than one line long, you may want to change this: “background:0 50%” to this: “background:0 0” and add “display:block” to the #TJK_DL dt a {} rule (to avoid any “wrapping”).

For the curious


// Copyright 2006 | Thierry Koblentz - All Rights reserved
// TJK_ToggleDL() Version 1.5.4 report bugs or errors to
if (document.getElementById && document.getElementsByTagName){
document.write("<link href=\"TJK_ToggleDL/TJK_ToggleDL.css\" type=\"text/css\" rel=\"stylesheet\" />")
document.write("<link href=\"TJK_ToggleDL/TJK_ToggleDL_ie5mac.css\" type=\"text/css\" rel=\"stylesheet\" />")
function TJK_doToggleDL(x){
var zDD=document.getElementById('TJK_DL').getElementsByTagName('dd');
var zDT=document.getElementById('TJK_DL').getElementsByTagName('dt');
function TJK_ToggleDLopen(){//we open all of them
var zDD=document.getElementById('TJK_DL').getElementsByTagName('dd');
var zDT=document.getElementById('TJK_DL').getElementsByTagName('dt');
for(var i=0;i<zDT.length;i++){
return false;
function TJK_ToggleDLclose(){//we close all of them
var zDD=document.getElementById('TJK_DL').getElementsByTagName('dd');
var zDT=document.getElementById('TJK_DL').getElementsByTagName('dt');
for(var i=0;i<zDT.length;i++){
return false;
function TJK_ToggleDL(){
if (document.getElementById && document.getElementsByTagName){
var zDT=document.getElementById('TJK_DL').getElementsByTagName('dt;
var zDD=document.getElementById('TJK_DL').getElementsByTagName('dd');
var ToggleON = document.getElementById('TJK_ToggleON');
var ToggleOFF = document.getElementById('TJK_ToggleOFF');
if (ToggleON && ToggleOFF){
ToggleON.onclick = TJK_ToggleDLopen;
ToggleON.title = "Show all answers";
ToggleON.href = "#";
ToggleOFF.onclick = TJK_ToggleDLclose;
ToggleOFF.title = "Hide all answers";
ToggleOFF.href = "#";
for(var i=0;i<zDT.length;i++){
var zContent = zDT[i].innerHTML;
var zHref = "<a href='#' onclick=\"TJK_doToggleDL("+i+");return false\" title='Show/hide the answer'>";
zDT[i].innerHTML = zHref + zContent + "</a>";


/* "Show All" + "Hide All" links */
#TJK_ToggleON,#TJK_ToggleOFF {border:1px solid #333;padding:0 5px;margin-right:5px}
/* zeroing out padding and margin */
#TJK_DL dd,#TJK_DL dt {margin:0;padding:0}
/* margin for the DTs (shorthand) */
#TJK_DL dt {margin:7px 0}
/* image and left padding for DDs */
#TJK_DL dd {background:url(answer.gif) no-repeat;padding-left:55px}
/* styling all anchors in the DTs */
#TJK_DL dt a {background:0 50% no-repeat;padding-left:32px;color:#000;text-decoration:none}
#TJK_DL dt a:visited {color:#666}
#TJK_DL dt a:visited:hover, #TJK_DL dt a:hover, #TJK_DL dt a:active, #TJK_DL dt a:focus {font-weight:bold}
/* the + and - gif in the anchors */
#TJK_DL .DTplus a {background-image:url(toggleDLplus.gif)}
#TJK_DL .DTminus a {background-image:url(toggleDLminus.gif)}
#TJK_DL .showDD {position:relative;top:0}
#TJK_DL dd,.hideDD{top:-9999px;position:absolute}
#TJK_ToggleON,#TJK_ToggleOFF {display:inline;cursor:pointer; cursor:hand}

Note: “cursor:hand” is for IE5 Win, but this declaration will make this sheet fail Validation. If Validation is important to you, you can either delete this declaration or move it inside a Conditional Comment.


#TJK_DL .showDD {display:block}
#TJK_DL dd,.hideDD {top:0; position:relative; display:none}

For the DOM police

Earlier versions of this script did not use document.write(), I was using the DOM to plug the stylesheets in the HEAD element. Unfortunately, setting the rel attribute of the LINK element makes Safari “go blank” and STYLE fails in IE Win. So, I decided to go with what works!

important noteThis script should work in HTML and XHTML documents.

Should a web site open pdf files in a new window?

A few years ago, I was visiting some friends in Paris. One is a fairly conservative priest and the other a socialist teacher.
I asked them a seemingly innocent question: What’s the deal with Robespierre? Why do people feel so strongly one way or another about him?

I had just begun learning about the French Revolution and was not prepared for the argument that arose. Robespierre and the
Reign of Terror still divide people into camps.

pdf file icon
It’s rare to find a topic with such strong opinions expressed in web design (not counting Internet Explorer). However, I recently found the
standardista populace building ramparts in the streets of the city when I asked the seemingly innocent question: “Should .pdf files be
opened in a new window?”

The answers fall into two main camps:

  1. Do not hijack the browser; let the user determine the behavior of their browser.
  2. Make it easier for visitors that are not savvy enough to know how to control their browser’s options.

Hypothetical vs. Reality

In a perfect world, information is provided efficiently in all browsers to people of all abilities. HTML code should not interfere with the
browser’s native behavior, allowing the user to establish preferences for font size, background-color, and file downloading.

In the real world, the visitor has to wait for files to be presented, can lose track of the original web page, and can accidentally shut down
the browser instead of the file. Therefore, the programmer can assist the viewer by opening the file in a new window.

I’ve summarized the recent comments over this question (from the web standards group mailing list) to decide which is the best approach.

Basic standards

Regardless of the window option you choose, there are some elements that everyone agrees upon. The link must let the visitor know that
they are opening something other than another web page. The file type and file size should be attached to the link, i.e.: <a href="foo">contact list (.pdf, 25kb). This gives the visitor the basic information needed to make an informed decision about how the file should be opened.

The developer could also give the link more information to assist the visitor: >a href="foo">contact list (.pdf, 25kb). If the visitor does not have the required plug-in, they should be given
a link to the appropriate download site. <a href="foo">contact list</a> (<a href="foo" title=”Download the plugin required to view a Portable Document Format file”>.pdf, 25kb </a>) .
CSS can also be used to place the Acrobat icon next to the link:

Version 1:

<a href="foo">contact list (.pdf, 25kb)</a>
.pdfFile {background: url(pdflogo.gif) no-repeat 0 0; padding-left:25px;}

Version 2:

Use JavaScript to find links with .pdf in the href and insert the class=”.pdfFile” dynamically

Version 3:

Use CSS3 syntax to add the icon to all links with .pdf in the href. IE6 does not support this, which makes this option impractical for now.

Let the visitor know that the link is to something other than another web page. The easiest method is to follow the link with the file name
and size; all other additions are usability gravy.

Do not open new windows

"pop-up" windows are bad for accessibility and usability. The WAI answers the "pop-up" question quite plainly:

WAI Checkpoint 10.1

Until user agents allow users to turn off spawned windows, do not cause "pop-ups" or other windows to appear and do not change the current window without informing the user.

However, the first part of this rule has been satisfied. Modern web browsers now block unwanted popup windows. This rule seeks to prevent web sites from launching new windows when a visitor comes to the site. The second part of the rule requires the visitor to be warned that such behavior may happen. This requirement does not banish new windows altogether, rather those that the visitor has no control over.

Many people believe that the visitor should have control over their browser or other rendering device at all times. The savvy user will know how they prefer to see a file and the web site should not pre-determine this action.

I would say let the user decide. Wherever possible I try to provide enough information in the link itself so that the user knows what to
expect and can proceed as they wish. Many people will set up their browser to deal with different file types according to their preference
(open the document in the browser, open it in the application, download the file). Opening in a new window removes user choice. By providing a
plain link you give users the option … of `right-click - open in new window`.

- Damian

Users with assistive technology or portable devices also have difficulties with multiple windows.

Accessibility considerations would be ensuring that users are advised of what will happen when they activate the link, either that the
document would be opened in a new window, or that it will be downloaded. Also that opening a new window does not adversely effect users
accessing a website with assistive technologies (screen readers, etc.).

- Andy Kirkwood | Creative Director

These issues need to be addressed if the web site chooses to open these links in a new window.

The argument for opening new windows

The Internet is not full of expert users. That is the simple reality. An effective web site compensates for visitor behavior and creates a seamless experience. While this is not always possible, the programmer can minimize frustrations. Opening a document in the original window creates its own set of problems for the user. Even the savvy visitor will sometimes forget to right-click on a link and choose “open in a new window” or “save target as.”

Many of our users are very computer illiterate and giving them too many options confuses them. We do open our PDF documents in a new window and never have any complaints about it.

We DO get complaints, though, when things are too hard to use or if the page they were on "disappears" because we opened a "document" in that same window or if the file downloaded and they can’t find it (happened regularly before we launched the PDF in another window).

Gary Menzel, Senior Software Engineer, Med-E-Serv Pty Ltd

Many users have become accustomed to having windows appear to log-in, handling web applications, for advertisements, help sections, and more. Further, they are used to closing the windows by clicking on the browser’s close button. When the PDF document loads in the original window, the visitors will often close the browser, expecting the original web site to appear. Instead, they have closed the web browser and will have to navigate their way back to the original page. For many, this may involve doing another search if they are not comfortable using the history feature.

… I’ve had users report that they close the window thinking that they’re exiting the document, but they’re actually closing the browser.


Opening the documents in a new window can create a friendlier environment for the user. It preserves the original page and allows the visitor to continue reading the web site while the new file is being prepared in another window. However, it needs to be done in a manner that does not violate accessibility requirements.

JavaScript to the rescue

In the past, links were given a target to choose which window a link was opened in. This was meant for web sites using frames. Open the
link in the top, side, body, footer, etc. A new window could also be generated if the page was not using frames or if the targeted id did
not exist in the frameset. Target=”_blank” became the standard code for opening a new window: <a target="blank" href="foo" />.

However, this assumes the visitor is able to keep visual track of the windows. It also does not account for browsing devices that do not
recognize multiple windows.

There are two methods for using JavaScript to make a link open a new window.

Insert the script into the link code

<a onclick="; return false;" href="foo">PDF file in a new window” class=”pdfFile”>contact list (.pdf, 25kb)

This script tells the browser to open a window with the URL listed in the href. If the browser does not recognize the command,
ignore the function and open the link in the original window.

Removing the script from the link

Thierry Koblentz of TJK Design developed the following JavaScript for this article. The script searches for any file downloaded as application/pdf, that sits in a folder named “PDF”, or has the extension of .pdf. It then adds class=”pdfFile” for the CSS, a title attribute to notify the visitor that the link will open a new window, and gives the programmer the option of using target=”_blank” or to create the new window.

<a href="foo">contact list (.pdf, 25kb)</a>
JavaScript (

  1. function TJKpopAppPdf(){ // v1.0 |
  2. var zA=document.getElementsByTagName(’a');
  3. for (var i=0;i
  4. // This is if the href value contains the string “.pdf” or if the anchor contains the correct “type” attribute or if the file is stored in a PDF folder
  5. if (zA[i].getAttribute(’href’) != null &&
  6. (zA[i].getAttribute(”type”)== “application/pdf” ||
  7. zA[i].getAttribute(’href’) .toUpperCase().indexOf(”.PDF”) >= 0 ||
  8. zA[i].getAttribute(’href’) .toUpperCase().indexOf(”PDF/”) >= 0)){
  9. // This is to include a title attribute or attach a string to an existing title’s value
  10. zA[i].title+=’ (opens in new window)’;
  11. // This is to include a class or attach one to an existing class’ value
  12. zA[i].className+=zA[i].classNam e?’ pdfFile’:'pdfFile’;
  13. // This spawns multiple windows, but works fine with popup blockers
  14. // zA[i].target=’_blank’;
  15. // This opens a unique window and brings it in front of the opener each time the user clicks on the link
  16. zA[i].onclick=function() {,’TJKWin’,'toolbar=no’);
  17. if( window.focus){newWin.focus()} return false;}
  18. }
  19. }
  20. }
  21. window.onload=function(){if(document.getElementById) TJKpopAppPdf()};

The name TJKWin is given to the new window to assure that all PDF links open in the same window. This keeps the visitor from ending up with a plethora of new windows for each PDF they open. If the browsing device is not capable of opening new windows, it will ignore the script and simply open the link in the existing window.

If you expect your audience to compare multiple files, you may want to remove the window name designation from the script.

Opening all documents in a window with the same name is obviously ‘tidy’, but problematic if a user wants to open and compare the contents of two documents simultaneously.

Andy Kirkwood

Other file types

This still leaves the discussion open for other file types. Should a new window be opened for spreadsheets, PowerPoint presentations, Visio documents, XML files, and more? Some of these files can be viewed in the browser, but they would be better left as a downloaded document to be viewed natively. The visitor still needs to be notified the link is for a non-HTML link:

<a class="”exceldownload”" href="foo">contact.xls (.xls, 25kb)</a>

The previous javascript could also be modified to give .xls files the appropriate class and title, making the code even cleaner.


Web site visitors expect to find information in an efficient, user-friendly manner. It is up to the web designer to create this experience. While opening new windows may be considered a faux pas, the average user will actually appreciate its convenience. JavaScript offers the most convenient method of giving a visual reference and functionality. Placing a helpful title attribute within the link further informs the visitor about the link’s behavior.

To further avoid confusion for the visitor, Thierry changed the code slightly today. He added ,'toolbar=no' to remove the browser’s toolbar: (,'TJKWin','toolbar=no');). This approach was suggested by Jacob Nielsen’s Alertbox Open New Windows for PDF and other Non-Web Documents.


Attribute selectors to provide language information

Attribute Selectors for International Web Sites

Sébastien Guillon, recently wrote a post about using the CSS2 attribute selector and content rule
to let visitors know what to expect when clicking on a link to an international web site. Inspired by his approach, I’ve simplified some of the code and added background images to
represent the countries.

Guillon’s original project focused on adding a text description after the link in the site’s native language. To do this, he used a set of descending selectors to look at the page’s language declaration and the link’s hreflang attribute. I am assuming the site that hosts this CSS is in english. However, it would not be difficult for you to simply change the generated content if your site is written in French, Spanish,
Swahili, etc.

Sample list of international Yahoo sites


Now look at the final version with new CSS. Internet Explorer users will not see a difference, try Firefox or Opera. Internet Explorer 7 beta 2 shows the flags but does not show the generated content.

The hreflang Attribute

The hreflang allows the user/browser to define the language of a link’s targeted page to avoid presenting
unreadable information:

The hreflang attribute provides user agents with information about the language of a resource at the end of a link, just as the lang attribute provides information about the language of an element’s content or attribute values.

The hreflang attribute defines the language of the web site you are sending someone to. The language is defined with a two letter abbreviation, such as en, fr, sp… You can also define the locality of this language by adding the country code to this language. This is particularly helpful for languages that have dialects. A Mexican site would have this attribute: hreflang=”sp-mx”.

The Attribute Selector

CSS2 allows us to look for tags that contain specific attributes. We can look for blockquotes with cite attributes, tables with summaries, table cells with header attributes,
and our little friend, the link with an hreflang attribute.

/*English */
a[hreflang="en"]:after, a[hreflang|="en"]:after {content:"\A0(In English)";}

Breaking it down

This rule uses a combination of attribute selector and pseudo-class to transform the link from common to fabulous.

Look for a link with an attribute
The hreflang attribute must include the letters “en”. This allows the CSS to work on links that do not define a country variation
This pseudoselector defines the space after the link
{content:”\A0(In English)”;}
After the link, place the following text: (In English)
The hreflang attribute must include the letters “en” within a hyphenated set, i.e. en-us, en-ca, …

Adding the flag

Now that we’ve notified the user about what language the link will be in, let’s tell them the country the site is from. Once again, we will look at the hreflang attribute for this information. This rule is not as neat and tidy. For each country, we are going to look for all of the possible language attributes. For instance, Canadian links could have hreflang=”fr-ca” and hreflang=”en-ca”.

/*Canada */
a[hreflang="en-ca"], a[hreflang="fr-ca"] {background:URL(flag-sprite.png) no-repeat 0 0; padding-left:35px;}

This time, we will give links that have Canadian country codes 35px padding to the left side and a background image of the Canadian flag that sits to the
left edge of the link’s text. This style sheet is using an image sprite to keep the server requests to a minimum. See the article about using
image sprites for more information on this technique.

Et Voilà

There we have it. A set of international links with the country of origin and language clearly defined. All of this has been made possible by our friends, the
attribute selector, the pseudo-class, and the content style. Tune in next week as we learn how to make a cruise ship out of two
shoe-boxes and an XML schema.

Fine Print

This has not been tested in Safari, but it shouldn’t be a problem. The pretty and useful presentation elements will not appear in IE6, NN4, and probably
most alternative devices (My Treo shows the flags but not the added content). I do not know how assistive devices would render these styles, more than likely they would be ignored. This project falls under
the “build for the best, don’t hurt the rest™” protocol.


Z-index conflict with Flash and DHTML widgets

I’m working on a project that has a Flash movie and a DHTML dropdown menu on the same page. Flash movies like to sit on top of the page and the dropdown would slide behind the movie. Since this isn’t what I wanted, I needed to find a way to make the it have a lower z-index than the dropdown.

I did a Standardista Search for a cure and didn’t see it. But a quick message to the Web Standards Group returned the solution. It’s actually pretty easy.

UFO Flash detection and insertion script

I’m using the UFO JavaScript to detect the browser’s compatibility with the Flash movie and insert it on the fly. This method provides good default content to those without Flash and valid, shiny, happy Flash to those with it.

UFO gives you the ability to insert parameters into the movie and this is what you need to cure the z-index issue. You need to set the wmode parameter to “transparent.”

var FO = { movie:"swf/myMovie.swf", width:"300", height:"120", majorversion:"6", build:"40", wmode:"transparent" }

That’s all there is to it.