Practical Use of CSS3: Transforms and Transitions

Transforms and Transitions (introduced as part of the CSS3 specification) enable us to create the kind of interaction and experience previously only associated with JavaScript or Flash. You'll likely have read a lot of discussion and tutorials covering these properties, but they tend to be experimental in nature.

In this tutorial we will explore CSS transforms and transitions by creating something more useful. We're going to build a single static HTML page that will utilize transforms and transitions in a slider, plus some interesting hover effects.

Before we continue it's worth noting browser compatibility. This tutorial demonstrates modern techniques, techniques which will be commonplace further down the line, but for the time being suffer incompatibility in older browsers. Take a look at caniuse.com for more detailed analysis of which browsers support the various methods discussed here.

Preparation

Alright, at this point we already know where we are about to go, so we can decide what we need to prepare.

Before anything else, preparation is the key to success. ~ Alexander G. Bell

Basic Skills

First, we need a basic understanding of HTML and CSS. Assuming you have that, we are ready to go.

If, however, you are really new in this area, I would advise you take some time to get up to date on the topic; fortunately Envato has provided a 30 days course which will teach you all the essential things you need to know about HTML & CSS for free.

Find Images

We'll obviously need some images to make the image slider, as well as the image captions for the website. PhotoDune will serve our purposes very well. The following are the images that we will be using in this tutorial.

We will also need a texture for the background. My favorite place to find textures at the moment is Subtle Patterns and after browsing through all the pages, I finally decided to use this example.

Managing Folders

Although this is optional, I personally like to manage my project folders in the first step, this way it will ensure we remain organized from the get go. So, for this website I have created two main folders psd and html, whereby the html folder comprises two more folders for fonts and images.

The Design

Next, we mockup a website in Photoshop to reference while we're building it in HTML. I won't be going deeper in this step, as the actual design is beyond the scope of this tut. You can already find numerous layout tutorials at Webdesigntuts+, like this one.

Well, the image below is what I came up with; let's keep the file inside our psd folder.

The HTML

Before doing any coding, I have sliced some requisite graphics to be used in the layout. First the navigation background, the one with the black color on the top and the custom made pattern for the image thumbnails.

If you followed the entire 30 day course on HTML & CSS, Jeffrey went over how to slice a PSD file during day 27.

HTML5

We'll also utilize new tags from the HTML5 specification, so expect to find <nav>, <header>, <footer> and some other new tags that I (honestly) rarely use like <figure> and <figcaption>.

However, we won't discuss too much about HTML5 here, that's beyond the scope of this tutorial. Instead, you can find loads of HTML5 tutorials on Nettuts+.

Header & Navigation

Alright, let's now open up a text editor and start coding some markup.

As you can see in the final design, we won't separate the menu and the header section, so the primary navigation itself will be wrapped inside the header tag.

This is all the HTML we need to form our Image Slider. Now, let's take a closer look at each part of the markup.

Starting from the <div class="hidden">, we will use this class to hide slides that overflow from the specified dimension; in this case it would be 960 by 380 pixels.

The slides are structured using an unordered list. Each of the slides is wrapped inside a <li> tag with a unique id <li id="slide-3" class="slide"> so that we are able to select specific slide through a Fragment identifier later on.

Notice that we use figure to wrap the slide image and figcaption for the slide caption. These elements describe the roles and relationship they have perfectly (semantically).

The figure is a new tag in the HTML5 specification. This tag is intended to mark up a graphics, photos, diagrams, etc. While the figcaption, according to w3c, represents a caption or legend for the figure. So, these tags are effectively interrelated.

Footer

The Styling

In this section we will begin all the styling work. I'll assume you already know how to separate the styles from the HTML document and link it using a css file.

<link href="style.css" rel="stylesheet" type="text/css" />

Prefix-Free

The styles will utilize many new CSS3 specifications, which unfortunately for each browser will require a vendor prefix to work correctly. Such as -o-for Opera, -moz- for Mozilla Firefox and -webkit- for both Safari and Chrome. Writing bloated CSS this way can be very inefficient.

So, I've decided to add Lea Verou's prefix-free in the document; a JavaScript library to handle all these vendor prefixes automatically, so we will only need to add the official property format. For instance, normally we would need to write the following CSS rule to scale an element:

While using the prefix-free script, we can remove all vendor prefixes.

div {
transform: scale(2,4);
}

Download the prefix-free file and put it at the bottom of the document, before the closing body tag.

<script src="prefixfree.js">

CSS Reset

Another problem we'll encounter across the browsers is inconsistency. Practically every browser renders HTML elements to its own default style and these default styles often differ slightly.

To overwrite the default style and ensure we're working from the same starting block in each browser, we will use a CSS reset. There are several options out there; like this one from Eric Mayer, YUI from Yahoo and HTML5 Reset by Richard Clark. But this time I'm interested to try out Normalize.css by Nicolas Gallagher. Download the file, and put the link inside the head tag, before any other css files are referenced.

@Font-Face

Speaking about the font, we plan to apply a few non-system fonts for the HTML, so we'll tackle that using the @font-face rule. Well, @font-face isn't really anything new in CSS, it was actually included in the CSS2 specification, but unfortunately the method was not widely adopted by web designers at that time.

To include our own font using @font-face is rather simple. In fact, the good people at font squirrel created this handy tool to generate the code you'll need.

In our design, we used ChunkFive for the resto logo and the Titillium for the menu navigation. Let's download all these fonts and apply the @font-face rules to the stylesheet:

So far, having applied all the styles above you should see something like this:

Styling the Image Slider

Now, let's apply some styles to the Image Slider. The slider including the navigation will have dimensions of 960 by 425 pixels, while the image slide itself as we mentioned above will only have 960 by 360 pixels.

The image caption will have a slightly transparent background. To achieve this transparency effect we won't use the opacity rule, as it will also affect the text inside the caption. Instead, we will achieve it using the Alpha channel from RGBA color mode.

If you have read the tip, then I assume the gradient rule should be obvious for you already. But, let's take a look another rule to figure out what the CSS actually does.

First, the <span class="shine"> will have absolute: position with z-index: 5 to bring it to the very top of other elements in the slide. The shining effect is not appearing correctly, so the element still needs to be rotated by approximately -20 degrees (transform: rotate(-20deg);).

Slider Navigation

The slider style is rather simple. By default, the menu in the navigation will have inline position so that each menu will appear side by side.

As we can see in the picture above, the thumbnail images are huddled. We need some margin to make a gap in between. Rather than defining this margin for each thumbnail, we will dictate that only the middle image has one using nth-child.

nth-child is a css pseudo-class to select specific child elements using a formula. To get more insight on this pseudo-class, you can read this comprehensive explanation.

All right, first we will select the middle images, in this case the image thumbnail number 2, 5 and its multiplication.

.thumbnail:nth-child(3n+2) {
margin: 0 23px;
}

After that, we select only the the first three images to have margin-bottom. So, the first and the second row will also have a gap in between.

.thumbnail:nth-child(-n+3) {
margin-bottom: 33px;
}

Thumbnail Captions

Referring to our design, the caption will commonly have a green color with a slight transparency and rounded border.

Alright, we have completed all the necessary styles and so far you can expect the result to look something like this:

The Effects

In this section we will begin to apply some effects to the website using transforms and transition properties.

How Do These Properties Work?

I assume you'll have come across some posts that have already discussed these properties (transforms & transitions), especially if you are a regular reader of the Tuts+ blogs network. Let me just explain a little bit about these properties for a quick recap.

Transform is a new CSS property included in CSS3 specification. Using this property we can apply various transformations such as translating (movement), rotating, skewing and scaling to elements.

Transformations can be achieved using the following css function; transform: transform-method(value). For the transform-method we can use translate, scale, rotate and skew. For demonstrative purposes we'll apply each of these methods to our image captions.

While transition is also part of CSS3 specification, this property will allow us to create gradual effect to the animation instead of instant changes. In short hand format, the effect can be applied using the following function:

transition: <property> <duration> <timing-function> <delay>

Let's apply them to our image captions for better understanding.

Color Transition

In the navigation section we will demonstrate a simple example of the transition effect. We will change the menu color from white (#FFFFFF) to orange (#FFB400) smoothly by specifying the transition-property when we hover over the menu.

The CSS rule above will specify only the color property that will be transitioned with 500ms as the duration. And notice that I didn't add a specific timing-function. If we do not specify it, the browser will use ease by default.

Now we will step up to the next, more challenging section.

Image Caption Effects

In this section we will apply various transformations and transition effects to the image captions. To begin with, we specify common rule for the image thumbnail transition.

.thumbnail img {
transition: all 350ms;
}

We didn't add a specific property in the rule, instead, we used "all" for it. This means the transition effect will be applied to all the properties around the image.

In this case, the image will be 30% transparent when we hover over it.

.thumbnail:hover img {
opacity: 0.3;
}

In the next step we will define each of the caption transition behaviors.

Caption 1: Moving Upwards

The first image caption will have a linear timing-function, so the movement is steady from the start to the end.

Then, when we hover over the thumbnail, the caption will move to the top. We can achieve the movement using the translate method. The translate method will make the element move from one point to another point specified in the translate value.

We used a percentage for translation rather than giving specific value in pixel unit. This way, the caption will move relative to the image height, regardless of the actual value of the height. Also, notice that we added margin-top.

Caption 2: Moving Downwards & Transition Delay

The second caption will have full height and width so that it will cover up the image thumbnail. We will use ease-in for the caption so expect the caption to start slowly. We also add transition-delay for about 350ms, which means the effect will start right after the image transition completes.

Then, when we hover over the thumbnail, the caption will eventually move down.

.thumbnail-2:hover figcaption {
transform: translateY(190px);
}

Caption 3: Zoom-in Effect

For the third caption, we will use ease-out. Using this will make the caption transition end slowly. We plan for the caption zoom-in when we hover over the respective thumbnail, so we specify the caption scale as zero for its starting point.

And below is the CSS set of rules for the hover state. When we hover over the third thumbnail the caption will scale up, back to its original dimension.

.thumbnail-3:hover figcaption {
transform: scale(1);
opacity: 1;
}

Caption 4: Multiple Transformations

The fourth caption will have rotating transformation and in order that the text is not reversed we will rotate the caption first for -180 degree.

Both the caption and text inside will have transition property and this time we will use ease-in-out. Judging from the function name, as you can guess, it will make the transition effect start and end slowly.

Then, when we hover over the thumbnail, the caption will eventually move to the top from its initial position and rotate at the same time. This is a simple, practical example of how we can apply multiple transformations in one element.

For the text transformation, it will be zooming-out as we've mentioned before.

.thumbnail-4:hover figcaption p {
transform: scale(1);
opacity: 1;
}

Caption 5: Playing with Cubic-bezier

Speaking about transition timing-function, we already used ease, linear, ease-in, ease-out as well as ease-in-out. These keywords are actually representations of specific values from bezier curves. Such as:

linear is equal to cubic-bezier(0,0,1,1)

ease is equal to cubic-bezier(0.25,0.1,0.25,1)

ease-in is equal to cubic-bezier(0.42,0,1,1)

ease-out is equal to cubic-bezier(0,0,0.58,1)

ease-in-out is equal tocubic-bezier(0.42,0,0.58,1)

This time, for this caption, we will try to use a cubic-bezier with a custom value. It's actually very difficult to predict how the changes work if we are not seeing the actual act. Fortunately, there is a handy and very helpful tool to play with cubic-bezier, so we can see the instant result of the changes.

Visit cubic-bezier.com where you can play around with bezier curves, created by Lea Verou, the same person behind the prefix-free.

In the following CSS, I've set the cubic-bezier values to run the transition quite fast at the start and significantly more slowly at the end.

Caption 6: Transform Origin.

We have applied scaling and rotating method for the previous captions. You may have noticed that the rotation and the scale began from the center point of the element. This was because the transform-origin is 50% 50% by default .

transform-origin is a property that allows us to specify the transform starting point in the element. It can be achieved using the following syntax transform-origin: x y.

Brief Introduction to :target pseudo-class

The Image Slider will be driven by a click. When we click on the slider menu the respective slide/image will eventually show up, usually with slide-in or fade-in effects. These sorts of navigations and slider effects are generally built upon JavaScript or Flash technology.

However, in this tutorial, we will try to achieve it using CSS exclusively, that is by using the :target pseudo-class.

The :target is one of the distinctive features in CSS3 that will allow us to select an element within an HTML document with a specific id that matches with the fragment identifier in the URI.

For instance, a URI; http://www.somedomain.com/page/#section-1 will select an element with id="section-1" on the page. Thus, similarly with the :hover, any styles around the :target would be applied.

All right, let's take a look at the following CSS rules:

The CSS rule below will turn the image opacity into 1 when the respective li is acting as the :target. Remember that we marked up the slide/image using unordered list tags.

#image-slider li:target img {
opacity: 1;
}

The caption inside it should slide up by 100% of the width; please, do not omit the !important declaration. This is !important.

And when the menu has no user activity, it will revert back to its original condition very slowly, by about 1s as we have specified in the .nav-slider li aabove.

The Limit

Such as with any another technology, CSS is no different. It still has some limitations.

If you refresh your browser (I assume you are still on your practice page of this tutorial), you will notice that the caption in the first slide did not show up upon the first page load. Well, this is because we only stated in the CSS to show up the caption once a li is targeted. So, here we need to add specific translation to the caption.

We select the first slide using :first-child selector and translating the caption to move upwards for 100% of its height.

Refresh your browser, now the first caption should show up in the first load. Remember that we have added 300ms delay transition in the previous step, so the caption will start showing up after that specific amount of time.

There is one problem though, the CSS statement above will make the caption remain in place, although we have navigated to the other slide. So, we need to create a counteraction rule for it.

We will add a .hide class for the caption (in the first slide) and define it to go back to its initial position.

I'm a web designer, living in Indonesia. I love trying new things around CSS3 and HTML5. I also authored a book, Responsive Web Design by Examples, which covers practical approaches on building responsive websites rapidly with frameworks.