One of my interests is making proof-of-concept navigation templates 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 HTML 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 <nav>
. 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:
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 HTML and a little JavaScript.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.