from details to accordion
With lots of smart people working on exciting, new html tech (the html component module in particular), I find myself more and more occupied with cleaning up my own html code. One way to do that is to remove functional elements from the html that serve as script toggles. These elements should ideally be added by the script itself. So today, let's take a look at details (or expand/collapse structures if you like), their relation to the accordion pattern and where to reduce redundant html.
expand collapse
One of the new (and often contested) additions of html5 is the details element. While it has (some) semantic value, people have been ogling it because it provides out of the box expand/collapse functionality. Click the handler (summary element) and the content of the box will reveal itself. Super handy, but it doesn't take a genius to predict that many are lining up to abuse the element just for its functionality (remember the days when people used paragraphs just for the default margin that came with them?) rather than use it for its semantic value.
One other (and quite serious) issue with the current proposition of the details element is that the hidden elements are not contained by a single wrapper, so styling them as a separate box is virtually impossible for now. On top of that, I'm not entirely sure myself whether I appreciate this out of the box functional behavior handled by browsers, so for now I'll just stick to regular html enhanced with some good old javascript. I will use the semantics proposed by html5 though, as this will ease a possible future transition.
detail pattern
<section data-pattern="details"> ... </section>
The most basic code for the expand/collapse functionality is little more than a single data-pattern attribute warning javascript it should do something with the container. Javascript will then need to create its own handler and show/hide section, like so:
<section data-pattern="details"> <header data-unit="toggle"> ... </header> <div class="main" data-unit="body"> ... </div> </section>
The toggle section will function as a handler for hiding and showing the content, the body section defines the part to be show and hidden. In most cases though a toggle and body will already be available in the html (usually the toggle is the entire heading of the section), so the two data-unit attributes will be available in the html already.
<section data-pattern="details" class="jOpen"> ... </section>
Opening and closing the content section will be handled by alternating between two classes on the root (.jOpen and .jClose). Putting a class on the root allows us to style the state of the toggle (usually there is a different open/close state) and the state of the body.
A quick fallback reminder
Make sure that the non-javascript version of your site shows the content of the block by default, especially when the hidden information is critical to the use of the site. If the content is available through other means on your site (separate page, specific help section, ...) this isn't a real necessity, but it's still considered a best practice.
If the content of the block should be hidden by default, make sure you hide it with javascript (the fastest way, avoiding content jumps, is to remove html#noJs with a single line of javascript embedded directly into the head of your document. This way you can use css selectors to determine the correct state of the content in your css file). If the new media query propositions get approved, we'll have a script media query feature that will help us with this, but that's still wishful thinking for now.
accordions
The accordion pattern is little more than a list of detail patterns that interact with each other. If you open one detail block, you close all the others. The html code should reflect that.
<section data-pattern="accordion"> <section data-pattern="details"> ... </section> <section data-pattern="details jOpen"> ... </section> ... <section data-pattern="details"> ... </section> </section>
This code is pretty sweet as you don't need a lot of extra javascript to implement the accordion behavior. Just make sure the current jOpen class is removed and copied to the actual details block and that's pretty much it.
conclusion
If elements in your html have a purely functional purpose, you're good to remove them from your html source completely and have them set by javascript. An easy way to check this is to disable javascript and css and to check whether the content on screen makes actual sense. Clearly an "open" or "close" link (to show or hide the content of a block) makes no sense at all when you have no javascript available, so you're welcome to simply remove those from your source.
Using a data-pattern attribute to trigger functional behavior is a pretty neat way to alert javascript of its possible tasks, it keeps the html clean and allows for clear functional structures. The details-accordion patterns make for a nice couple to demonstrate how easy it is to clean up your html, getting rid of all unnecessary cruft and ultimately resulting in easier to read code. And when the html component module finally lands we'll be able to further abstract the additional html from the javascript, separating structure from functionality completely. What a dream.