Case Study: Getting Hardboiled with CSS3 2D Transforms

This is part of a series of guest posts covering tips and tricks for working with CSS. These techniques, along with web fonts, make rich interactive sites achievable with simple and accessible standards-based markup and CSS. Today’s guest post was written by Andy Clarke, author of Hardboiled Web Design.
In this example we’ll use CSS3 two-dimensional transforms to add realism to a row of hardboiled private detectives’ business cards.
The final hardboiled result using CSS transforms
There are a number of transform properties we can use, including:
  • translate: moves an element horizontally and vertically
  • skew: distorts an element horizontally and vertically (not covered in this article)
  • rotate: rotates an element
  • scale: increases or decreases the size of an element
The basic syntax for transforms is simple:
transform: transform type(value);
There’s no getting away from the fact that CSS transforms are an emerging standard. But there’s already widespread support for them in contemporary browsers; Firefox, Google Chrome, Opera, and Safari have all implemented transforms using vendor-specific prefixes and Microsoft is soon to follow. For the transforms we’ll be covering in just a minute, we’ll need vendor-specific prefixes for Mozilla, Microsoft, Opera, and WebKit, followed by the W3C’s official transforms syntax. (From now on, I’ll use only the W3C’s official transforms syntax. I’ll leave it up to you to add the corresponding vendor-specific prefixes.)
.vcard {
  -webkit-transform: translateY(90px);
  -moz-transform: translateY(90px);
  -ms-transform: translateY(90px);
  -o-transform: translateY(90px);
  transform: translateY(90px);
}
Quite a fistful I know, but necessary, because these vendor-specific prefixes allow each browser maker to perfect their implementations as the standard develops. Two scripts make Hardboiled Web Design possible. First, selectivizr enables CSS3 selectors in older versions of Internet Explorer. Then, Modernizr tests a browser’s ability to render CSS3 two-dimensional transforms and adds class attribute values of csstransforms or no-csstransforms to the HTML element, depending on the result.

Setting up the HTML

Here we have four microformat hCards, each with its own set of values to describe a detective’s contact information. These act as styling hooks and enable our users to extract the data from each hCard more easily:

The Fat Man

Private Investigation $50 a day plus expenses. By appointment only Dial: M for Murder

Nick Jefferies

Private eye WA6-0089

Shoes Clues

Finding the footprints they leave

Hartless Dick

Private investigations
Dial #333 for a quick fix

Laying out the hCards

Let’s start by writing styles that will be common to every card. We’ll float each one to the left and give them identical dimensions:
.vcard {
  float: left;
  width: 300px;
  height: 195px;
}
Our next task is add individual background images to each card. But how? Remember there are no id attributes anywhere in our HTML?
The :nth-of-type pseudo-element selector targets an element based on its type and position in the document. Want to target the first, second, third, or fourth card, no matter where they appear in the document order? Not a problem. This makes :nth-of-type pseudo-element selectors one of CSS’s best-kept secrets:
.vcard:nth-of-type(1) {
  background-image: url(c01.jpg);
}

.vcard:nth-of-type(2) {
  background-image: url(c02.jpg);
}

.vcard:nth-of-type(3) {
  background-image: url(c03.jpg);
}

.vcard:nth-of-type(4) {
  background-image: url(c04.jpg);
}
As we only want the background images to show and not the HTML text, indent every element inside those cards to move them off-screen:
.vcard * {
  text-indent: -9999px;
}
Just the cards, no text
The best way to learn transforms is to see them in action, so we’ll use scale, translate (move), rotate, and a combination of all three to adjust the size, position, and rotation of each card.

Transform ‘scale’

When we use the scale property, we make elements appear larger or smaller. By how much and on what axis is determined by a scaling factor, which can range between 0.99 and 0.01 to make an element smaller, or 1.01 and above to make it larger. A scaling factor of 1 maintains the intrinsic size of an element. You can scale elements along the horizontal (X) or vertical (Y) axis, or a combination of the two. Other elements remain unaware of a new size and so don’t reflow around it.
To vary the size of several hardboiled cards, we’ll scale them in two dimensions using the combined scale property. Scale the first card down to 80% (.8):
.csstransforms .vcard:nth-of-type(1) {
  transform: scale(.8);
}
Next, increase the size of the second and third cards by 10% (1.1):
.csstransforms .vcard:nth-of-type(3),
.csstransforms .vcard:nth-of-type(4) {
  transform: scale(1.1);
}

Transform ‘translate’

Moving elements with translate behaves in a similar way to relative positioning, where an element is offset visually but keeps its position in the document’s normal flow; translate moves elements on the x- and y-axes. We can specify how far they move by using pixels, ems, or percentages that are relative to the size of the element. We’ll translate each card along both the horizontal (X) and vertical (Y) axis:
.csstransforms .vcard:nth-of-type(1) {
  transform: scale(.8) translateY(90px);
}

.csstransforms .vcard:nth-of-type(2) {
  transform: translate(150px, 60px);
}

.csstransforms .vcard:nth-of-type(3) {
  transform: scale(1.1) translate(144px, 55px);
}
Look carefully and you’ll notice that in that last example, we combined two transform values into a single declaration. To set multiple values, string them together and separate each with a space. A browser applies these transforms in order — reading from the left.
Laying the cards out with transforms
The space you see between the first and second cards is a perfect spot into which we can position the fourth and final card.

Transform ‘rotate’

We can rotate an element between 0 and 360 degrees (clockwise) and even use negative values to rotate an element counterclockwise. The syntax is quick to learn. First, declare the rotate value, then the angle inside parentheses. The fourth card’s artwork has a portrait orientation whereas all others are landscape. Fix this by rotating that errant card ninety degrees clockwise (90deg), scale it by 10% (1.1) and finally move it into position by translating it down 20px and left 630px:
.csstransforms .vcard:nth-of-type(4) {
  transform: scale(1.1) rotate(90deg) translate(20px, 630px);
}
The last card in place

Embracing the natural differences between browsers

No two browsers are the same, so to make the most from emerging technologies such as HTML5 and CSS3, we need to banish the notion that websites should look and be experienced exactly the same in every browser. We should design around browser differences instead of hacking around them. That will likely mean that designs will look different — sometimes very different — across browsers.
To make this simple alternative, adjust each card’s margins to float them into a simple grid.
.no-csstransforms .vcard {
  margin: 0 20px 20px 0;
}
The graceful fallback styles
How adventurous your alternatives are depends on you, your clients, and the project you’re working on. Be under no illusion though: CSS3 selectors and properties give us the power to create designs that are tailored to browsers of all capabilities. With this variety comes new opportunities to show our creative skills and new opportunities for business. It’s time to grab those opportunities with both hands.
Case Study: Getting Hardboiled with CSS3 2D Transforms Case Study: Getting Hardboiled with CSS3 2D Transforms Reviewed by BloggerSri on 4:33 AM Rating: 5

No comments:

Powered by Blogger.