demosthenes.info

I’m Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with , and . To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

web developer guide

my books

Book cover of Pro CSS3 AnimationPro CSS3 Animation, Apress, 2013

my projects

CSSslidy: an auto-generated #RWD image slider. 1.5K of JS, no JQuery. Drop in images, add a line of CSS. Done.

tipster.ioAutomatically provides local tipping customs and percentages for services anywhere.

Electronica Music Site Navigation, Part 1: CSS3 Gradient Animation

css / navigation

Estimated reading time: 3 minutes, 21 seconds

One of my interests is making proof-of-concept navigation templates using HTML5 and CSS3 for different kinds of music websites. Previously, I’ve created a Rock Band design; this time, my thoughts turned to electronica.

My idea was to create an interactive menu that resembled a graphic equalizer, with frequency bars going up and down as the user ran their cursor over the options. In part two of this article, I’ll add audio effects to each link.  Given that HTML5 has built-in support for audio, it made sense to code the navigation bar from scratch in that language.

The basic markup for the menu bar is very straightforward:

<nav id=equalizer>
<a href="#">Beats</a>
<a href="#">Samples</a>
<a href="#">Loops</a>
<a href="#">Rhythms</a>
</nav>

The trickiness all lies in the CSS: I wanted the links to be at the bottom of the nav, with space left above them for the animated frequency bars. Placing height alone on the nav would leave the links at the top:

nav#equalizer { background: black; position: height: 150px; width: 600px; padding: 0 1em; }
nav#equalizer a { text-decoration: none; color: white; font-family: Highway, Arial, sans-serif; text-transform: lowercase; letter-spacing: .3em; }

After a little fooling around, I decided that our old trick of using position: absolute for elements inside a container with position: relative set on it would work best.

(Note that using display: table-cell and vertical-align: bottom on the links would also have worked, except for the fact that we will be altering the implied height of each link to achieve the graphic equalizer animation; if we do that to an element with display: table-cell applied to it, all other “cells” in the same “row” will have the same effect applied, which we don’t want in this case).

nav#equalizer { background: black; position: relative; height: 150px; width: 600px; padding: 0 1em; }
nav#equalizer a { text-decoration: none; color: white; font-family: Highway, Arial, sans-serif; text-transform: lowercase; text-align: centre; letter-spacing: .3em; position: absolute; bottom: 0; display: block; width: 130px; }

The links are given display: block in order to be the same width; unfortunately, position: absolute means that they will all stack on top of each other in the lower left corner of the nab. The only way to get around this is to give each link an offset from the left, which I will do inline:

<nav id=equalizer>
<a href="#" style="left: 20px;">Beats</a>
<a href="#" style="left: 170px;">Samples</a>
<a href="#" style="left: 320px;">Loops</a>
<a href="#" style="left: 470px;">Rhythms</a>
</nav>

I’ll use a repeating linear gradient with a sharp transition to create the frequency bar effect; this is the same idea as I’ve used in previous CSS3 gradient examples to create patterns. Again, I’m using the most recent, standardized version of the gradient syntax:

nav#equalizer a { background: repeating-linear-gradient(top, #1E5799 0%, #1E5799 50%, #000000 51%, #000000 100%); }

There are a few problems: the background gradient is a little large, and extends behind the link text. The first is easy to fix, by using background-size:

nav#equalizer a { background-size: 100% 10px; }

The second problem is slightly harder to solve. We can tell a gradient to start at a certain point, but a linear repeating gradient will extend in both directions. The easiest way I found to hide the gradient behind the links was to surround the text of each link with a span tag:

<nav id=equalizer>
<a href="#" style="left: 20px;" id=beats><span>Beats</span></a>
<a href="#" style="left: 170px;" id=samples><span>Samples</span></a>
<a href="#" style="left: 320px;" id=loops><span>Loops</span></a>
<a href="#" style="left: 470px;" id=rhythms><span>Rhythms</span></a>
</nav>

… and then to use the span as a mask to hide the gradient where we don’t want to see it:

span { display: block; background: black; padding-bottom: .6em; padding-top: .3em; }

(If you wanted greater cross-browser compatibility, you could use a repeating background image to achieve the same effect).

After all this, the animation couldn’t be simpler: change the height of the links on hover with padding-top:

a:hover { padding-top: 80px; }

…and animate the transition:

a { transition: all .2s linear; }

We’re not truly animating the gradient, per se: we’re just giving the impression of doing so by allowing the gradient more room to “breathe”.

Next, we’ll add sound effects to each hover state using HTML5 and a little JQuery.

comments powered by Disqus

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.