7. Transformations
The last group of WebKit CSS extensions we’ll look at are
the transformation functions. We can apply these functions to any
element to generate visual effects without using images, canvas, or SVG. The transformation functions
work in the Safari, Android, and webOS browsers as of this
writing.
The usage is very simple: we use the CSS property -webkit-transform, applying as a value any of
the CSS functions that we saw earlier in this section—for example,
rotate, scale, or translate3d (only for Safari).
We can change the origin point of the transformation with the
-webkit-transform-origin property.
The default value is the middle of the element (a value of 50% 50%).
7.1. Perspective
Setting a 3D perspective can be done using the perspective transformation function or the
special CSS property -webkit-perspective, which takes a value in
pixels defining the distance from the viewer’s perspective. If we use
the latter option the perspective will be applied to the children of
the element, and if we use the transformation function it will be
applied to the element itself.
7.2. Transform style
The transformation can act differently with regard to its nested
elements. We can control this behavior with the -webkit-transform-style attribute, which has
two possible values: float and
preserve-3d. If float is used, the nested elements are
flattened as if they were an image and the perspective is applied to
that image. With preserve-3d every
nested element will have its own 3D perspective, as seen in Figure 2.
7.3. Backface visibility
Backface? What? An element in HTML has a backface? It
can in mobile Safari, for 3D transformations defining the -webkit-backface-visibility CSS property. It
is not what you might think (two faces in the same element), but the
effect can easily be implemented.
Warning:
3D transformations do not work on Android- and webOS-based
devices; we should use them only when designing for the iPhone, iPod
Touch, or iPad.
The backface visibility property can be defined as hidden or visible. If hidden, when we define a rotation of the
y-axis of more than 180 degrees the element will disappear, and we can
make another element showing a backface appear in its place.
Note:
All transformations can also be applied using JavaScript, by
changing CSS styles or by using the WebKitCSSMatrix JavaScript class and
defining a couple of objects. The most simple and quick way is to
define the transformation as a string and apply it to element.style.webkitTransform.
7.4. The CardFlip pattern
This is one of the most “wow” visual features of Safari
on iOS. The CardFlip pattern allows us to show an element in a
rectangular area and, when some event occurs, perform a transformation that flips the
element as if it were a poker card and shows another element of the
same size and in the same position as the backface.
Apple provides a full sample that can be used as the base
template for designing this kind of animation. You can download it
from http://www.mobilexweb.com/go/cardflip.
A simplified version of the CardFlip sample looks like
this:
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN"
"http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Card Flip</title>
<style>
body {
margin: 0px;
-webkit-user-select: none;
}
#container {
height: 356px;
width: 320px;
background-color: rgba(56,108,179, 0.5);
/* Disable tap highlighting */
-webkit-tap-highlight-color: rgba(0,0,0,0);
/* Give some depth to the card */
-webkit-perspective: 600;
}
.card {
position: absolute;
height: 300px;
width: 200px;
left: 60px;
top: 28px;
-webkit-transform-style: preserve-3d;
-webkit-transition-property: -webkit-transform;
-webkit-transition-duration: 1.5s;
}
.card.flipped{
-webkit-transform: rotateY(180deg);
}
/* Styles the card and hides its "back side" when the card is flipped */
.face {
position: absolute;
height: 300px;
width: 200px;
-webkit-border-radius: 10px;
-webkit-box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.5);
-webkit-backface-visibility: hidden;
}
.face > p {
margin-top: 36px;
margin-bottom: 0;
text-align: center;
font-size: 92px;
}
.front {
color: rgb(78,150,249);
background-color: rgb(34,65,108);
}
.back {
color: rgb(34,65,108);
background-color: rgba(78,150,249,0.5);
/* Ensure the "back side" is flipped already */
-webkit-transform: rotateY(180deg);
}
</style>
<script type="text/javascript">
function flip(event) {
var element = event.currentTarget;
/* Toggle the setting of the classname attribute */
element.className = (element.className == 'card') ? 'card flipped' : 'card';
}
</script>
</head>
<body>
<div id="container">
<div id="card" class="card" onclick="flip(event)">
<div id="front" class="front face">
<p>♠ ♦<br> ♣ ♥</p>
</div>
<div id="back" class="back face">
<p>♦ ♠<br> ♥ ♣</p>
</div>
</div>
</div>
</body>
</html>
Analyzing the code, we see two div elements inside a container called
card. One div is the “front” face and the other the
“back” face. Both faces are positioned in the exact same position (as
absolute elements), and the back side starts with a y-axis rotation of
180 degrees. Both faces also define themselves as hidden when
backfaced.
When the user clicks the card
container (with either the front or back face displayed on the
screen), via JavaScript we apply (or not) the flipped CSS class, which rotates both
elements 180 degrees around the y-axis. And
voilà! Only one face will be at the front at any
given time; the other will be automatically hidden. This process is
done with a beautiful, smooth animation, which you can’t quite see in
Figure 3.