I aim to code up my HTML semantically. There are a number of reasons to do so:
- It’s part of good MVC separation, which is always a win when you reach the inevitable re-design of how the site looks;
- It’s better for search engine optimization;
- It makes your page more forwards-compatible, since Web devices that haven’t yet been invented will reliably display your page with some semblance of accuracy;
- It’s simply the Right Thing to do.
For similar reasons, my workplace espouses unobtrusive JavaScript, again for good MVC reasons.
All of this came to mind when I recently built a new FAQ page for work. There’s nothing about this page that’s particularly revolutionary or awe-inspiring, but it did occur to me that this was a great example of how my own coding principles have improved over time.
Take a look at the page. The designers wanted a list of questions, each a clickable link, with an arrowhead next to each question. Click on a question and the answer would “pop open” below, with the arrowhead now pointing downward to indicate the “open” state. Click the question again and it closes.
Here’s how I would have done this five years ago: each question and answer would be a <div>, with ids with similar names, e.g. question2 and answer2. The questions would have hyperlinks in them, with an inline onclick handler like
<a href="#" onclick="javascript:toggleAnswer('2');">
That handler would take the argument and append it to the word “question” or “answer”, then use that result as the document ID to set style.display to "display" or "none". It would also change the src on the arrowhead image.
Yuck.
Instead, I did it the right way. First off, I recognized that this FAQ is a bullet list, so I coded it as a <ul>, using CSS to hide the standard bullets and instead use the arrowhead image. Each list entry has two elements inside it, with classes “q” and “a”; by default, “a” is hidden with display:none. Class “q” has CSS to make it blue and underlined so that it looks like a hyperlink. (Since it’s not actually a link, just a clickable element, I avoid the <a> tag here.)
Then I made a CSS class, li.open. That class uses the other arrowhead instead, and furthermore has
li.open .a {display:block}
Now we have a class that, when set on a list entry, puts it into its “open” state, with the proper arrowhead and with the answer visible.
Finally, we add the click handlers dynamically, using a JS library (in our case, Prototype). We take each element with class “q” in the list, and add a click handler that sets or removes class “open” as appropriate:
$$('#faqs .q').each(function(s) {
s.observe('click', function() {
this.parentNode.className = (this.parentNode.className=="open") ? "" : "open";
});
});
And that’s it. Clean HTML, CSS to handle the visuals, dynamically-added handlers to keep M, V and C separate. It’s a thing of beauty, baby.
Posted in CSS, JavaScript |
Follow responses via RSS 2.0 feed
You can leave a response, or trackback from your own site.
That’s great — as someone who hasn’t touched web design in a while this makes me want to get back into it.
I’m guessing you didn’t write the copy, but it still bugs me that “This sounds too good to be true?” is not a question.
You’re darned tootin’ I didn’t write the copy. If I wrote our site’s copy, you’d never see a single instance of the phrase “Click here” used in a hyperlink, and there wouldn’t be any passive voice constructions.