This tutorial will walk you through the concept of iconification — taking content on a page and applying CSS to transform it into a simplified, icon-sized preview of itself.
Let’s dig into an example. This demo shows iconifying applied to calendars. Click on the month icons to expand them.
In the calendar example, the icon view uses simple colored squares to indicate that a month contains dates of interest. Each icon can be clicked to trigger the full view with more details, such as date numbers and names of holidays. The smooth transition between the two maintains context, so the relationship is very intuitive.
This is where iconification really shines. It’s great for presenting a compact overview of content while still having the details available in an instant. In other words, it allows for visual abstraction of information.
Here’s the HTML for a single month.
No surprises there. Calendars are really just days organized in a tabular format, so
<table> is the obvious semantic choice. Each month is wrapped in an
<article> to convey that it’s a self-contained piece of content. Every
tabindex="0" on it to enable tabbing, which is important for keyboard accessibility (more on this later).
There’s a lot of CSS, so I’ll just cover the highlights. The full CSS is available in the source and includes comments for a couple of browser-specific fixes.
<article> is centered within an
<li>, which is positioned within a
<ul>. The centering technique I use on
<article> allows it to overlap surrounding content and stay centered when expanded to full-size. Relevant declarations are shown below.
transform property also has
scale(.25) on it. This isn’t for centering, rather it’s what creates the 1/4th icon sizing.
<article> to full-size is done by adding the
active class to its parent, causing the
transform property on
<article> to change.
scale(1) is self-explanatory, but it’s worth noting that
translate(-50%, -50%) needs to be restated, otherwise
<article> will shift back to its non-centered position.
At the same time, the
inactive class is added to sibling elements so that another
<article> cannot be expanded until the active
<article> is dismissed. This is done by blocking pointer events.
z-index stacking requires some finesse. The active
<article> needs to appear above neighboring content. This means increasing the
z-index when the expanding animation starts (easy part) and not resetting the
z-index until the shrinking animation ends (tricky part). Fortunately,
z-index is animatable, so we can use
transition-delay to make this happen.
active class also triggers
opacity changes on various child elements, giving us that nice fade in/out effect on the details.
Of course, none of this would be animated without the
transition declarations on
<article> (for scaling) and the various child elements (for fading).
Achieving pixel perfection with transformed elements — before, during, and after animation — takes patience. There are many quirks to battle, but fortunately, there are a few tricks and best practices that help.
All pixel sizes in the CSS are multiples of 4. This is no coincidence. The content is scaled to 1/4th size when displayed as an icon, so using multiples of 4 ensures that fractional pixel sizes don’t happen. This keeps pixels perfectly aligned and edges crisp.
Defining the widths and heights of elements can help. Not only does this make it easier to achieve the pixel alignment just discussed, but it can also prevent post-animation jiggles. Browsers will often readjust text when an animation ends. If an element containing such text doesn’t have a set width/height, then it’ll resize accordingly, causing a chain reaction of positional shifting to elements after it.
Iconifying content naturally involves a lot of elements in a small space. With so many elements to animate, it’s important to keep performance in mind, otherwise you’ll end up with a poor framerate and ragged transitions.
There are two things you should avoid: repaints and reflows. Repaints are caused by animating properties that force your browser to redraw elements. This includes
box-shadow, and more. Reflows are caused by animating properties that force your browser to update the layout of elements. This includes
left, and more.
Repaints and reflows aren’t the end of the world, but they can hurt performance. You can avoid these by sticking with two properties that are very efficient to animate because they get help from the GPU:
transform (when used for position, rotation, or scale).
This explains some of the decisions made in the CSS. There are places where animating
background-color would be more intuitive, but opting for an approach that uses
opacity allows for better performance.
activate(), which applies the
active class to the appropriate element and the
inactive class to the others.
Clicking the dismiss icon or tabbing/clicking away from an
dismiss(), which simply removes the
checkKey() brings support for certain key presses. Hitting
enter will toggle the current
escape will dismiss the current
<article>, if it’s expanded.
That wraps up my first example. You can check out the finished demo, in case you missed it earlier.
Next up is a concept for iconifying profile cards. Go ahead and check out the demo.
A lot of techniques from the first demo are reused here. The new point of interest is in turning the individual words in the profile text into abstract blocks. The first step to accomplishing this is to wrap each word in its own
That snippet simply grabs text within
<p> tags, breaks it apart wherever it sees a space, then wraps each piece with
<span> tags. Now we can use those
<span> tags to apply some CSS.
<span> tag is mostly left alone. Instead, an
::after pseudo-element is used to cover each word with a block of color. The
bottom properties are given slightly negative values in order to stretch the block to cover letters that stand tall or hang low (“g”, for example).
Sadly, this makes the blocks a bit thick, which isn’t as visually appealing. The solution is to use a carefully crafted linear gradient that pads the top and bottom with white (to match the background). The blocks appear thinner, the text is still covered, everyone is happy.
Be careful though, this “spanifying” technique should be used in moderation. It’s very easy to get carried away and blow up your DOM tree with way too many
<span> elements, each one being animated, which can lead to performance issues. It’s best to stick with small blurbs of text, like in the example.
My final demo shows iconification in the context of an analytics dashboard.
This demo has a lot going on, but doesn’t really introduce any new techniques for iconifying content, so I’ll leave it at that. If you want to see all the glorious details, the source is all yours.
I can see iconification being used in many other situations beyond the 3 I’ve shared here. It’s a great tool to help with visual abstraction and information hierarchy. There’s also a sort of slick elegance in being able to show a true icon-sized preview of real content by applying a coat of CSS to the content itself. Just be mindful to keep your pixels sharp and don’t forget about performance.