Basics of CSS3 transformations

All modern browsers already support CSS transforms, including mobile browsers. For the first two apps, we'll use four new statements from CSS3 heavily:

  • transform: Move, rotate, scale, or skew the HTML element using translate[X,Y,Z](v), rotate[X,Y,Z](v), scale[X,Y,Z](v), and skew[X,Y](v), respectively. All these basic transformations have their 3D alternative, such as rotate3d(x, y, z, angle), that you can use to set transformations in all three dimensions with one statement.

    If you want to perform more transformations on an element, you have to set all of them in a single CSS statement, for example, transform: rotateY(90deg) translateX(100px);.

  • transform-style: Using flat or preserve-3d options, you can tell the browser whether you want to apply 3D transformations from parent elements to their child. By default, the browser takes all transformations on a per-element basis, which means that if you, for example, rotate the parent element and then rotate its child elements, the browser will perform rotations independently.
  • perspective: Set the perspective depth for this element and all its children as a distance from the element to the viewer. Changing this value doesn't change the size of elements, as we'll see in the second app.
  • transform-origin: This statement is mostly useful for rotation. It lets you set a point around which rotation will be performed. By default, the origin is set to the element's center.

    Note

    All these CSS3 statements are currently available on mobile browsers only with the prefix -webkit-.

Axes

The coordinate system for transformations is very obvious: the x and y axes are like those you're probably used to. The z axis goes in the direction to/from you. The center of coordinates for each element is in its center by default.

Hello world in 3D

It's time to see CSS3 transformations in action. We're going to rotate this HTML snippet:

<body>
  <div id="container">
    <div id="first">Hello</div>
    <div id="second">World!</div>
  </div>
</body>

Apply CSS3 with a few 3D transformations:

/* Center of perspective for this div will be in [250,50]. */
#container { height: 100px; width: 500px;
             perspective: 300px; position: relative; }
#container div { position: absolute; width: 150px; }
#first { transform: rotateY(30deg) translateX(-85px); }
#second { transform: rotateY(-40deg) translateX(85px); }

Note

We're omitting some nonimportant CSS such as font size or colors here in order to make the examples more readable.

In the browser, we'll see rotated div elements with text like this. Note that the white text is just like any other text on the page. Also, transformed elements are just normal div elements that can be adjusted with CSS to what you desire.

This is an important distinction from WebGL, where everything is drawn right into the canvas using shaders and has absolutely nothing to do with HTML.

Hello world in 3D

Both div elements, #first and #second, are positioned absolutely. If we didn't translate their position, they would overlay each other, but at the same time, we can't use just inline-block because the rotated div element takes the same space as when it wasn't rotated. Therefore, it would be even harder to make them look like they're joined together.

Nesting 3D transformed elements

Let's add one more div element to the #first element:

<div id="container">
  <div id="first"><div id="third">Nested</div>Hello</div>
  <div id="second">World!</div>
</div>

Then, add styles that transform this div element as well:

#third { transform-origin: 0 0;
         transform: rotateY(110deg); }

We want to rotate it around the y axis by 110 degrees, centered to the left edge of its parent (that's the effect of the transform-origin). This should make the mirrored image of the element look like it's joined to the left edge of #first while going slightly to the left and fading away from us. The #third element is aligned to the top-left corner of its parent because it's positioned absolutely.

Nesting 3D transformed elements

But wait; that's not what we wanted. We can see the back of the #third element, which makes the output look like it's mirrored. That's fine but it seems like it's following the same transformation as #first.

The reason for this behavior is that the browser flattens transformations for child elements. To avoid this, we'll use transform-style: preserve-3d, which we mentioned earlier. Note that preserve-3d applies the parent's transformations only to direct children elements. If children elements have other children elements, then they have to use preserve-3d as well.

So, we can fix this by adding transform-style: preserve-3d to #first:

#first { /* … */ transform-style: preserve-3d; }

Now the result looks like we expected:

Nesting 3D transformed elements

Note

In some situations, you don't want to see the back of rotated elements. In that case, set backface-visibility: hidden;.

If you're confused with all these rotations and translations, don't worry. It's hard to imagine rotating objects in 3D, moreover, combining multiple nested objects and rotating each of them relatively.

Your best friend is Developer Tools. Try changing rotations or translations on the fly, change perspective, and see what effect it has. Also, change transform-origin on #third and see what happens.

We'll later set transformations in Dart for both -webkit- prefixed and nonprefixed versions, such as:

element.style.setProperty('transform', 'rotateX...'),
// Mobile browsers supporting only prefixed versions.
element.style.setProperty('-webkit-transform', 'rotateX...'),
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.28.179