Part 1 - Creating an animated menu

As part of a little side project I am doing at the moment, London to Paris in 24 hours, I wanted to create an animated menu icon to use. I thought I would start documenting some of my design / development decisions throughout projects I am working on.

Things to achieve

  • A purely CSS solution to the animation of the menu.
  • An elegant animation of the menu icon and menu.
  • Must be accessible for screen readers.

For part 1 we are only going to be concentrating on the menu icon, rather than the whole menu. However, we will be considering the menu as a whole when making decisions for DOM structure and CSS.

Here is what we will be creating, view codepen

See the Pen Pure CSS animated menu icon by Michael Tempest (@mike-tempest) on CodePen

DOM structure

Something that a lot of developers seem to be forgetting in the current age of front end development is keeping good semantic code, but most of all accessible code. In the age of JavaScript, people seem to have forgotten that screen readers still have a hard time reading purely JavaScript driven websites. It is our responsibility as developers to make websites that are accessible for all users who may visit the site.

With this in mind I decided to keep a fairly standard DOM structure for the menu navigation and icon, please bear in mind I am using the inuitcss framework and BEM syntax:

<nav class="nav caps">
  <ul>
    <li class="nav__item"><a href="#">About</a></li>
    <li class="nav__item"><a href="#">The Charity</a></li>
    <li class="nav__item"><a href="#">Sponsor Me</a></li>
  </ul>
  <a href="#" class="menu-icon">
    <span class="menu-icon__text">Show Menu</span>
  </a>
</nav>

Basic styling of menu icon

First things first, let's forget all about the fact we want to animate this icon, the main objective for now is to style the menu icon.

I am going to use CSS3 pseudo elements for our icon to make it easy for the animation of the icon, I am also using SASS to speed up the writing process of CSS in projects. (It also allows for the powerful use of mixins)

One thing to note about the use of pseudo elements is that they only work back to IE8. The reason I have made this decision, is down to this only being a visual problem in version of internet explorer below IE8. If it is a must the site is visually perfect below IE8, there is a shim available here.

Here is our basic markup for the icon:

.menu-icon {
  display:block;
  width:40px;

  &:before,
  &:after,
  .menu-icon__text {
    background: #fff;
    @include vendor(border-radius, 3px);
    content:'';
    display:block;
    height:4px;
    width:100%;
    margin:6px 0;
  }

  .menu-icon__text {
    text-indent:-9999px;
  }
}

Don't forget the hover state

For the hover state we are going to manipulate the pseudo elements and the span, the span (.menu-icon__text) will fade out. Whilst our two pseudo elements will rotate and translate to form a cross. Here is the styling we need to add, take note that our translate is both in an x and y position.

&:hover {
  &:before {
    @include vendor(transform, rotate(45deg) translate3d(5px,10px,0));
  }

  .menu-icon__text {
    opacity: 0;
  }

  &:after {
    @include vendor(transform, rotate(-45deg) translate3d(5px,-10px,0));
  }
}

It's time to animate!

Now we are done with our basic styling of the hover state, it's about time we animated the icon. Luckily for us, because we have done all of the groundwork properly on the icon, to animate it is simple. We just have to add transitions to our elements. In my case I am using the mixin provide by inuitcss, vendor, to do the same simply put the following on your elements that will animate:

@include vendor(transition, all .2s ease-out);

This compiles to the following:

-webkit-transition:all 0.2s ease-out;
-moz-transition:all 0.2s ease-out;
-ms-transition:all 0.2s ease-out;
-o-transition:all 0.2s ease-out;
transition:all 0.2s ease-out;

That's it for this part, we now have a fully animated menu icon. Please come back to see the next post on creating our fully animated menu.

Comments