Friday

CSS Only Accordion Menu

A project on my radar is to add accordion functionality to some existing elements on the page. The tried and true method is to use javascript for this (e.g. jQuery's Accordion), and in fact I may very well end up using .js for my project. But, I got to thinking that maybe I could use the CSS3 :target pseudo-class, and skip javascript altogether.

HTML

The markup is really pretty semantic and straight forward. Your markup may differ of course, but I'm thinking of this as a list of 3 Groups of content that I want to accordion navigate between. I'll call each of my list items a class of "top-level", each of which must have a unique ID that will serve as our target anchor; because CSS doesn't much like numeric classes or IDs (it's supported, but you have to escape them), I'm going to be careful to define each of my IDs as "group-n", where n is the unique Group number. Within each of my list items, I need an anchor where the href is a hash followed by the ID of the anchor's top-level Group ID. Then, I'll create whatever content I want to show/hide with the accordion action, and just call each of these a class of "sub-level". So, my markup is going to look a little something like so (forgive the code formatting):

  • Group 1

  • Group 2

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam nec dolor non lacus pharetra dapibus eu at tortor. Sed dictum blandit metus a rhoncus. Vestibulum consectetur fringilla velit eu aliquam. Etiam sodales libero velit. Morbi hendrerit, risus vel faucibus elementum, justo augue scelerisque magna, nec posuere velit nisl at nisl. Donec auctor venenatis nulla quis lacinia. Nullam id blandit nibh.


  • Group 3

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam nec dolor non lacus pharetra dapibus eu at tortor. Sed dictum blandit metus a rhoncus. Vestibulum consectetur fringilla velit eu aliquam. Etiam sodales libero velit. Morbi hendrerit, risus vel faucibus elementum, justo augue scelerisque magna, nec posuere velit nisl at nisl. Donec auctor venenatis nulla quis lacinia. Nullam id blandit nibh.

You'll notice that I chose another list, and a couple of paragraphs as my sub-level content; this is because we can put just about anything we want here.

CSS

So now let's look at how to make this work. It turns out to be super easy:
.accordion .sub-level {
    height: 0;
    overflow: hidden;
}

.accordion li:target .sub-level {
    height: auto;
}
That's it. With just the above CSS, and our nice semantic HTML, we can have an accordion menu in almost all browsers (sans IE8 and older - see below). So what's going on here? Well, really all we're doing is telling CSS to make our sub-level a height of 0px, and hide it (overflow: hidden) until later when we hit our li:target, we will change our sub-level to height: auto, to expand to show our content. DONE!

Making it pretty

From here you can start using your imagination, including adding some sweet, sweet, animated CSS easing of the height of as you navigate through your accordion's content. NOTE: For your height animations to work, you need an actual height value for your sub-levels; I'm not sure how to get around this just yet.

In my demo's case, I've just added some quick styles to help make it a bit more obvious what's happening, as well as showing the addition of arrows through CSS content, which is I think a pretty nice usability addition to an accordion menu. The rest is up to you!

DEMO


Full Demo w/Code

Support

The reason I think I may end up using javascript after all is because this is a CSS3 feature, and so isn't supported in many of the browsers that are used in referencing my site. Primarily, it's and IE issue (surprise!), as IE8 and older will not support this feature. Still, I'll try and make the case that the  overhead just to support IE8 and older isn't worth it, and those users can continue seeing the old, non-accordion version...

Thursday

Animated text depth with gradient text-shadow on hover

For fun, I thought I'd add some light pizazz to the page title (i.e. "Behind my Monitors") when a user hovers over the text. Go ahead and hover over that text and (hopefully!) you'll see what I'm talking about.

This is really pretty straight forward:
h1 {
   position: relative;
   top: 0;
   left: 0;
   -webkit-transition: all .25s ease-in-out;
   -moz-transition: all .25s ease-in-out;
   -o-transition: all .25s ease-in-out;
   -ms-transition: all .25s ease-in-out;
}

h1:hover {
   text-shadow: -1px 1px 0 #000, -2px 2px 0 #333, -3px 3px 0 #666, -4px 4px 0 #999, -5px 5px 2px red;
   top: -5px;
   left: 5px;
   -webkit-transition: all .25s ease-in-out;
   -moz-transition: all .25s ease-in-out;
   -o-transition: all .25s ease-in-out;
   -ms-transition: all .25s ease-in-out;
   color: #fff;
}
  1. I first set relative positioning to my h1, because I'll be animating a position offset, and set the top and left values to 0.
  2. I then add a :hover state and add some comma separated text shadows. I've added 5 different colored shadows, with no spread (so they're sharp), and offset them by 1px at each step. This creates the effect of a 5px multi-colored gradient text shadow.
  3. Then I added the animation to both the h1 and h1:hover.
And that's it. It's a bit cheesy; not unlike old school blink tags and marquees, but it also is an example of something that could be useful in the right context. Have fun!