flyouts/those damn things

I fucking hate flyouts. Both as a user and as a css developer, but I hate them most of all in my role of html developer. From an html perspective flyouts make no sense at all, so for years I've been wondering what the ideal html code for a flyout would look like. Of course you could take the easy way out and simply sling a couple of divs into your document, just enough to setup the css (sometimes javascript). But if we are true to our principles, deep down inside we know this isn't really the proper way to go.

defining flyouts

Before I go any further let's make sure we are all talking about the same component here, because sometimes the terminology in itself can be confusing already (pop-outs, pop-overs, overlays, ...). For me a flyout consists of a handler and a content blob that appears when triggered by certain events (typically clicks or hovers) and only eclipses that part of the page where it resides. In this it differs from what I call an overlay, as overlays eclipse the entire page below, effectively forcing you to focus on the content in the overlay.

We make use of flyouts because we want to hide certain pieces of content from plain view, only allowing access to the data when the user specifically asks for it. A flyout is a practical way to clear up content clutter that is only needed in some particular situations but should still be available on demand instantly. They came into fashion when people started making flyout menus (usually displaying the 2nd-level navigation on hover), but they've spread to accommodate all kinds of content (help messages on form inputs, pictures references on maps, login forms in page headers, ...).

why flyouts suck

Most (if not all) flyouts are functional and visual aberrations of the actual content. Once you disable the javascript and css from a page, you'll notice that the html content that represents the flyout makes hardly any structural sense. In most cases the flyout handler is either obsolete or a snippet from the content you've hidden from view. Often the flyout handler belongs inside the content blob, but this poses many css issues (and as far as I know, a few issues that can't be solved at all) so structure is sacrificed in favor of functionality and design. Note that flyout navigation is actually a welcome exception to the rule here, where the label of the 1st-level navigation serves as a handler for the 2nd-level navigation.

ideal situation

So what would be the ideal mark-up? Well, let's look at a real-life example first. If you look at Google Maps and you flag the picture view, you'll see a map overlaid with a lot of images. Click the thumb and a flyout will appear, holding more information about that image. (As it turns out Google just made some changes where the author isn't listed anymore, but the examples below should still makes sense)

<article class="image"> <header> <h1>image heading</h1> </header> <div class="main> <img class="full" src="..." alt="..." /> </div> <footer> <div class="specs">(author etc etc)</div> </footer> </article>

The code above is a simple presentation of the content we need to build our picture list, representing one picture. The image has a heading, it contains the actual image and some additional info. This structure will not suffice for building the flyouts though, so let's add some javascript triggers to ease things along.

javascript triggers

<article class="image" data-pattern="flyout"> <header> <h1>image heading</h1> </header> <div class="main> <img class="full" src="..." alt="..." data-handler="1" data-copy="true" /> </div> <footer> <div class="specs">(author etc etc)</div> </footer> </article>

In the code above we added three data- attributes. The most important one is data-pattern, which will inform the javascript it's dealing with a flyout here. The data-handler attribute will tell the javascript which elements need to be used in the flyout hander (I'm using numbers here to determine the order if more than one element is needed), the data-copy attributes states whether we can remove the handler element from the original source once it's copied.

<div class="flyout"> <div class="header"><img class="full" src="" alt="" /></div> <div class="main"> <article class="image" data-pattern="flyout"> <header> <h1>image heading</h1> </header> <div class="main> <img class="full" src="" alt="" data-handler="1" data-copy="true" /> </div> <footer> <div class="specs">(author etc etc)</div> </footer> </article> </div> </div>

... and this is the result after javascript has done its magic. A structure was built around our original component, helping us with the styling of the flyout. It's all divs so it has no influence on the document structure but it gives us the proper hooks to do the flyout styling.

Mind that this has a rather big impact on the css, as the root tag of your component will differ after the javascript is finished. You can either choose to hide the element completely until javascript has done its thing, or you can give the initial element the same styling as the flyout handler so the whole javascript operation will have no visual effect on the component. It all depends on how much time you have and how confident you feel.

To see this in action, I made a very simple test page. The first element has no flyout behavior defined, the second one has (one important warning: javascript and css are quick hack jobs in order to show off the javascript on/off behavior, it's better not to copy them into any real-life projects).

conclusion

Maybe this all sounds like a lot of overhead, but it does allow us to use the same html data-set for a regular image list and at the same time use it for a map representation (using a flyout for the image details). Not only that, but the untampered html code makes a lot more sense too.

When writing html, check your document with javascript and css disabled to see if it makes sense. Often there will be triggers or structures that are merely there for presentation and/or functionality, but make no sense from a structural/content perspective. It's often best to remove those structures and have them added only when needed.

I think I mentioned this before but html5 web components will really come in handy when dealing with techniques like these, so lets hope they'll evolve into an actual standard real soon.