Tabs are a common UI component on websites—one that is used in a variety of places for different purposes. They help us save screen space and show only what is immediately important to the user. Tabs come bundled with many JavaScript libraries, but as Nicholas Zakas has explained in one of his presentations, including a 90kB script on the page just to have the tab functionality doesn't seem appropriate. He said that he managed to create tabs in 1.9kB (compressed) / 5kB (uncompressed). I was interested to see how he achieved this, but the prototype I saw said that a file was missing, one that I couldn't find. But I still wanted to see something working, so I tried to create my own version. It's not perfect, but maybe you can find a way to improve it so that it works for you.

My first attempt was with an unordered list and a separate content area where the user is sent once he clicks on a tab. This can be seen very often with different tab implementations. I took some data from Wikipedia to populate the contents for a couple of tabs. But I noticed some imperfections. First, when the tabs are placed next to each other, they could easily exceed the length of the tab list area, which meant that they needed to flow to another line without breaking the layout or be hidden with the help of some horizontal scrolling mechanism. Second, this version lacked keyboard support, which meant that only users with a mouse can use it. Third, hidden contents are still completely loaded which isn't always good with heavy websites. Lazy loading can prevent this, but it probably has its own implementation cost. At the same time, if the tab content is loaded on-demand every time, the site may be perceived to be a bit slower. I decided that to keep everything as simple as possible.

My second attempt was slightly different. It uses a definition list, because I think that it better describes the relationship between a tab and its content. The terms resemble the tabs and the descriptions the contents for each individual tab. The list is a single element, which makes it easier to use it as a component in other contexts. I have slightly changed the initial script. One difference is that I have chosen to load the tab contents only in the last <dd> element, as this fixes the floating behavior of the tabs, who would be otherwise torn apart because of the alternations between the terms and descriptions. A better way would have been to achieve this with CSS only.

Tab contents must be also visible without the use of JavaScript. In this case, we can just show all of the content and make sure that it can still be accessed. Progressive enhancement is something we should think of while we are writing the code and not only during testing. With definition lists, we can draw the line where each tab's content starts and ends. In the first variant, it's probably not that easy without introducing additional elements.

Ideally, a component would be included on a page as many times as possible without impacting its performance. In practice, this is rarely achievable, but we still need to strive for it. The more efficient a single, small component is, the more efficient the site as a whole. In other words, performance is affected by the smallest of details. We can easily take the markup for a single component and multiply it with the help of our server-side language of choice (e.g. PHP). Here are some measurements I did on my local machine:

Load time increase

As we can see, using 10 tab areas with 5 tabs each (for a total of 50 tabs) weights 10kB without any content inside of these tabs. Even 100 tab areas have a weight of 34.4kB, which is an average of 344bytes per tab area! As the number of tab areas grows, the full load time grows exponentially and this is mostly because of the DOM.

Tab performance data

We need to consider that each tab content area will contain many other DOM elements, and then the number of tab areas we can show will shrink accordingly. It's still possible to have 50 thousand empty tabs on a page, but we'll need to wait 40.49s seconds. This is not ok when on the web every millisecond counts.

Tabs, although widely spread, aren't the solution to everything and should not be overused. But they can complement different means of presenting site content. We can see their usefulness when we consider how the average content size has grown in recent years. When tabs respond fast, they can hide more content than what the user is able to perceive at once. The screen space is always limited and tabs can multiply its efficiency. But they create a possible usability problem, because every time a user wants to see more, he needs to point and click. Human operations are much slower compared to those of a machine, so at the end a user that has to click too often to reach smaller and smaller pieces of content (in a tiled screen of tab lists) will perceive the site as being slow.

You probably know of much better ways to implement tabs, sliders and other UI components. I'll be glad to hear your opinion.