CSS3 Animation with Transitions

CSS3 is often lumped together with HTML5 as part of the post-Flash web. Just as HTML5 is bringing video to the web without Flash, CSS3 can create animations without Flash. The headline feature is that you animate a range of CSS properties directly - no Flash and no Javascript required.

And you can use this stuff now.

There are two techniques to animating in CSS - transitions and keyframes. There are also a set of transform properties to allow HTML elements be rotated, skewed and generally mucked about with in both 2D and 3D space.

Prefixes

As discussed elsewhere, CSS3 properties are in some cases not yet fully supported and as such you will need to use vendor prefixes to ensure as much cross browser support as you can. As with all things HTML5 you will of course need a 'modern' browser. Sorry IE8 just won't cut it.

Browser Layout Engine Vendor Prefix Example
Chrome Webkit -webkit- -webkit-animation-duration
Firefox Gecko -moz- -moz-column-count
Internet Explorer Trident -ms- -ms-background-position-x
Opera Presto -o- *
Safari Webkit -webkit- -webkit-animation-duration
* Opera adopting -webkit

For brevity in the following examples I will only use the -webkit prefixes.

CSS3 Transitions

To use the CSS transition property, as in other animation tools we need a start and a finish. That is we need to set the initial property value and a finishing property value. This is done through CSS rules, one rule for the start and one rule for the end. We will usually have an event to trigger the animation by adding or swapping the CSS rule that is applied to the element. With CSS the hover pseudo:class is the main way to trigger this event.

Tip: Been only able to trigger animations on hover is a limitation of CSS as 'events' are not really its bag. However, you can easily deploy a little bit of Javascript to handle a multitude of events and have it switch the class on an element to trigger the animation.

Simple Example

Take this simple HTML sample:

<h1>Hello World</h1>

We then add this stylesheet.

h1{
  width:200px;
  border:1px solid #333;
  text-align:center;
}
h1:hover{
  width:400px;
  -webkit-transition: width 2s;
}

The aim here is to increase the width of the <h1> element as we hover over it.

View Demo  CodePen Demo

The key line is in the hover rule:

-webkit-transition: width 2s;

This uses the shorthand transition property to set the property to animate and the duration of the animation. There are more values to set here but these two settings will always be needed. So in this example the CSS property of width is animated on hover and it will take 2 seconds.

The long hand version of this would use the transition-property and the transition-duration properties.

-webkit-transition-property:width;
-webkit-transition-duration:2s;

Set what you want to animate with transition-property

With the transition-property you set the CSS properties to animate. These can be comma listed or you can use the value all to animate any properties that have changed from one CSS rule to another.

The following will animate both the width and the padding properties.

width:400px;
padding: 50px;
-webkit-transition-property:width, padding;
-webkit-transition-duration:2s;

View Demo  CodePen Demo

Warning: Beware of the box. In the example above I have played around with the width and padding properties. Be careful that these don't mess your carefully calculated CSS layout.

Set how long you want the animation to last with transition-duration

With the transition-duration we can use either seconds s or milliseconds ms to set the duration of the animation ie

-webkit-transition-duration:500ms;

If you don't set this property you properties will 'jump' not animate.

Control the animation speed with transition-timing-function

If you have ever used a tool like Flash you will know that animations can be made more realistic by applying what are known as easing functions. Think of the way a train eases into and stops at a station. That would be an ease-out. The way a train starts from the station slowly and speeds up is known as an ease-in. By default CSS animations have an ease function applied to them so they start slowly and also slow down towards the end. The best way to understand the ease functions is to see them in action.

View The Demos

To change the easing function we therefore use the transition-timing-function property ie:

-webkit-transition-timing-function:ease-out;

View Demo  CodePen Demo

Delay the start of the animation with transition-delay

If you want to delay the start of the animation then use the transition-delay which like transition-duration takes a value in seconds s or milliseconds ms.

-webkit-transition-delay:1s;

Not something that you would really make much use of but the option is there.

Setting an animation back to its default

With hovers you'll often want an animation to animate back to its default state. To achieve this simple add a transition to the default CSS rule.

h1{
 width:200px;
 border:1px solid #333;
 text-align:center;
 -webkit-transition: width 1s;
 transition: width 1s;
}
h1:hover{
 width:400px;
 transition: width 2s;
 -webkit-transition: width 2s;
 transition: width 2s;
}

View Demo

Shorthand with transition

As we saw when I introduced the transitions properties we also have a shorthand transition property that can be used to set all four CSS properties.

transition: property duration timing-function delay;

For example:

-webkit-transition:width 1s ease-out 0.5s

Build a Playground

Finally on the topic of transitions I mentioned earlier how the animations especially if you change box model properties like width and padding will potentially have a knock on effect for the layout of your page. In this exaggerated example you'll see when you hover over the left hand menu its padding is increased and the layout is disrupted.

Always ensure your changes to the CSS don't have a negative knock-on effect to other parts of your page. If, for example, you wanted to create a self contained animation - very much like the familiar Flash banner ads - then create a 'playground' in the CSS where this can happen.

In this example the red ball will move within the right hand box on hover. The animated ball is 'contained' within its parent div of id 'rightBar', so doesn't negatively impact on the rest of the design.

The CSS used here is as follows:

#rightBar{
	width:120px;
	height:600px;
	float:left;
	border:1px solid #000000;
	margin-bottom:10px;
	overflow:hidden;
}
#ball{
	border-radius:120px;
	width:150px;
	height:150px;
	background-color:#F00;
	position:relative;
	transition:top 1s;
	-webkit-transition:top 1s;
	top:0px;
}
#rightBar:hover #ball{
	transition:top 5s;
	-webkit-transition:top 5s;
	top:450px;
}

Notice how the hover is added via the selector #rightBar:hover #ball so that the #ball is animated. Also how the original #ball rule includes a transition which is designed to reset the animation when the user hovers away from the #rightBar

View Demo  CodePen Demo

Using Javascript

In this example Javascript is used to add the interaction with mouseover and mouseout. Each Javascript event attaches a different CSS class rule to the element #adMsg.

The key HTML used is:

<div id="rightBar">
   <div id="adMsg" class="startPoint">
        <p>Fab offers and such like</p>
        <div id="ball">
         </div>
        <p>Blah blah de blah</p>
    </div>
</div>

Notice how #adMsg is nested inside of #rightBar.

The key CSS then applied to this HTML is:

#rightBar{
	width:120px;
	height:600px;
	float:left;
	border:1px solid #000000;
	margin-bottom:10px;
	overflow:hidden;
	position:relative;
}
#adMsg{
	position:absolute;
	width:120px;
	overflow:visible;
}
#ball{
	border-radius:120px;
	width:150px;
	height:150px;
	background-color:#F00;
}
.moveMe{
	transition:top 1s;
	-webkit-transition:top 1s;
	top:450px;
}
.startPoint{
	transition:top 1s;
	-webkit-transition:top 1s;
	top:-50px;
}

Notice how the CSS position: absolute is used on the #adMsg. The #adMsg is itself a child of #rightBar which is position: relative. Therefore we can move the #adMsg element freely around inside #rightBar without impacting any other elements of the page.

Finally overflow:hidden is used on #rightBar to stop the moving #adMsg appearing outside the #rightBar container.

The classes 'moveMe' and 'startPoint' are toggled by Javascript events to enable the transitions. The Javascript used here is:

document.getElementById('rightBar').addEventListener('mouseover', function(){
	document.getElementById('adMsg').setAttribute('class', 'moveMe');
});
document.getElementById('rightBar').addEventListener('mouseout', function(){
	document.getElementById('adMsg').setAttribute('class', 'startPoint');
});

View Demo  CodePen Demo

Leave a Reply

*