Lesson 14

Using CSS Transformations and Transitions

What You’ll Learn in This Lesson:

  • Image How to transform elements by rotating, scaling, moving, and tilting

  • Image How to work with transformations in three dimensions

  • Image How to apply multiple transformations to one element

  • Image How to do simple animations with the transition property

In this lesson you will start learning how to make your elements literally move on the screen. You will start by learning about two-dimensional transformations: making elements larger and smaller, moving them, rotating them, and even changing the tilt. The transform properties will help you make your elements look more interesting. You will also learn how to transform elements on a three-dimensional plane.

Where this lesson really gets interesting is when you start to animate those elements with the transition properties. You will learn how to make the browser convert your choppy instant changes when you mouse over an element into smooth transitions that slowly change from the starting point to the end point. This lesson requires a lot of hands-on work to really understand the material, so open your editor and get ready to try out the animations yourself.

Understanding CSS 2D Transformations

CSS lets you transform an element in several ways. The following are some of the most commonly used transformation functions:

  • Image rotate—Spins the element on the x,y plane

  • Image scale—Shrinks or enlarges the element

  • Image translate—Places the element in a new position on the screen

  • Image skew—Distorts the element along the horizontal axis or along the vertical axis

You accomplish all these transformations by using the transform property and its 11 transformation functions: rotate, scale, scalex, scaley, skew, skewx, skewy, translate, translatex, translatey, and matrix.

Rotating Elements with translate: rotate();

To rotate an element, you set the rotate() value to a degree from 0deg to 360deg (or 360deg to 0deg). The element will then rotate that many degrees clockwise for positive numbers or counterclockwise for negative numbers.

To try it out, place two <div> elements on a page:

<div class="one"></div>
<div class="two"></div>

Style both elements so that they are visible on the screen:

div {
  width: 20rem;
  height: 30rem;
  border: solid 1px black;
  background: linear-gradient(#f5ea70 0%, #ffffff 100%);
  margin: 1rem;
  float: left;
}

Finally, add a rotation of 10 degrees to the second one with the class two:

.two {
  transform: rotate(10deg);
}

Figure 14.1 shows how this looks in Firefox. The only thing that is different about the second <div> element is the transformation, and yet it displays very differently on screen.

The Firefox window shows two elements. The first element appears normally, and the second element is tilted rightward by about 10 degrees.
Figure 14.1 A simple rotation on a <div> element.

Making Elements Larger and Smaller with transform: scale();

You can transform an element by making it larger or smaller with the scale() value. The number inside scale() is the scaling factor—a number that is multiplied by the element’s current size. For example, 1 is the same as no scaling, 0.5 is half the current size, and 3 is three times as large.

The standard use is to apply one value to both the horizontal and vertical dimensions. But you can also use scalex() to resize only the horizontal dimension or scaley() to resize only the vertical direction. You can also set both values on the scale() function by separating them with a comma, like so:

transform: scale(horizontal, vertical);

Caution

When you transform an element, the browser won’t change or move the surrounding elements. A transformed element can overlap and even hide other elements on the page.

Changing the size of an element may seem pointless, but it is a good way to give elements more or less emphasis in certain situations. For example, if you want customers to click on a button, you might make that button slightly larger when they hover over it. Listing 14.1 shows how you might achieve that.

Listing 14.1 Enlarging a Button When in Hover State

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Make the Button Bigger</title>
    <style>
      button {
        font-size: 1.5rem;
        border-radius: 10px;
        border: solid 1px #940c94;
        background: linear-gradient(#cb2ff6 0%, #ffffff 100%);
        padding: 0.25rem;
        margin: 1rem;
      }
      button:hover {
        transform: scale(1.2);
      }
    </style>
  </head>
  <body>
    <button>Click Me</button>
  </body>
</html>

When you hover over the button, it gets a little bit bigger, grabbing attention and encouraging customers to click.

Note

Remember that when you transform an element, it affects everything in that element. So if you double the size of a 200 × 200 box with 15px padding with transform: scale(2);, it will display as 400 × 400 with 30px padding. The transformation applies to other styles on the element, such as font size, margins, borders, and outlines.

One thing that many designers don’t realize about the transform: scale(); property is that negative values cause an element to scale in a mirror image way. Remember that 1 as the scale() value tells the browser to keep the image the same size. So if you want your text to display as mirror writing, you just tell the browser to scale the horizontal to 1, like so:

p { transform: scalex(1); }

You can also turn it all upside down with scaley(), like so:

p { transform: scaley(1); }

This does not hide the text from search engine robots or impact the content in any other way. It just makes the text display backward, which could be fun in some situations.

Moving Elements with transform: translate();

The translate() function of the transform property moves an element from its default position on the page to the defined amount horizontally or vertically. It takes two values separated by a comma, like so:

transform: translate(horizontal, vertical);

You can move an element on just the horizontal plane with translatex() and just on the vertical plane with translatey(). Thus, you can move an element 50 pixels to the right and 20 pixels down from where it normally would display on the page like so:

transform: translate(50px,20px);

You can define an explicit value to move the element with pixels, rems, or other units. But you can also define the amount to move as a percentage of the element’s width (translatex()) and height (translatey()). This comes in handy if you want to center an element both vertically and horizontally.

Start with a simple element that you want centered:

<div class="center"><h1>Center Me</h1></div>

Give it some styles:

div {
  width: 15rem;
  border: solid 1px black;
  padding: 0.25rem 1.2rem;
  background: linear-gradient(#f5ea70 0%, #ffffff 100%);
  text-align: center;
}

Using absolute positioning, you can position the element to be halfway down the container and halfway across:

.center {
  position: absolute;
  top: 50%;
  left: 50%;
}

This places the element with the top-left corner in the center. If you want it truly centered, add a transformation to move it right 50% and up 50%:

transform: translate(50%, 50%);

The element now displays in the center both vertically and horizontally.

Caution

While using translate() to center elements vertically does work, it fails in a couple situations. First, it uses absolute positioning, which can affect the entire layout of a complex page. Second, if the content is too long to fit in the existing viewport, the content is clipped and unreadable. Figure 14.2 demonstrates how this might look.

An element that contains a lot of text is centered in a page. The top portion of the text is clipped and unreadable.
Figure 14.2 The vertically centered element is taller than the viewport, so the top is clipped and not visible.

Another way you might use translate() in your web pages is on buttons. It is common for buttons on computer operating systems to move a little down and to the left when they are clicked. This is meant to simulate a physical button being pressed. You can accomplish this effect by adding the translate() function when a button is active, like so:

button:active {
  transform: translate(2px,1px);
}

The translate() function comes into its own when you start animating your pages with CSS transitions, which are covered later in this lesson. Otherwise, it makes more sense to position elements with the position property, covered in Lesson 10, “Understanding the CSS Box Model and Positioning.”

Slanting Elements with transform: skew();

You can use transform: skew(); on an element to slant it on the horizontal and vertical axes. Much as with other transform functions, you can affect just the horizontal axis with skewx() and just the vertical with skewy(). If you give skew() one value, it defines the slant on the horizontal (skewx()) axis; otherwise, you include the horizontal and vertical values separated by a comma, like so:

transform: skew(horizontal, vertical);

You define the amount of skew as the number of degrees (between 0 and 360) the element should slant on that axis.

Note

You can define the skew and rotation of an element with radians (rad) as well as degrees. Most designers don’t use radians as they are more familiar with degree notation. You can also use negative degrees to rotate or tilt the element counterclockwise. So, for example, the value 315deg is the same as 45deg.

Keep in mind that when you transform an element, you are not just changing the container, you’re also transforming the contained elements. To understand this, create a <div> with some contents:

<div class="one">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
    sed do eiusmod tempor incididunt ut labore et dolore magna
    aliqua. Ut enim ad minim veniam, quis nostrud exercitation
    ullamco laboris nisi ut aliquip ex ea commodo consequat.
    Duis aute irure dolor in reprehenderit in voluptate velit
    esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
    occaecat cupidatat non proident, sunt in culpa qui officia
    deserunt mollit anim id est laborum.</p>
</div>

Create a second <div> that has a different class on it but has the same contents:

<div class="two">

Give both <div> elements a background color, such as a gradient, and a narrow width so they don’t take up as much space on the screen. You will want to have them stack one above the other. Here is an example:

div {
  width: 50%;
  background: linear-gradient(#4138f5 0%, #59c4e4 100%);
  padding: 1rem;
  color: white;
  margin: 0 auto;
}

Then transform one of the <div> elements to have a slight tilt of around 15 degrees:

.two {
  transform: skew(15deg);
}

In Figure 14.3, you can see that the second <div> and all its contents are tilted. The text is a little harder to read, and the linear gradient moves down the element on an angle as well.

There are two <div> elements that contain some text. The first element remains in normal landscape orientation. The second <div> element is slightly tilted leftward along with its content text.
Figure 14.3 The transform: skew(); property tilts the contents as well as the container element it’s applied to.

Notice that the element automatically tilts along exactly the center line, horizontal or vertical. You can adjust where the tilt is applied by using the transform-origin property. The default is transform-origin: 50% 50%;, but you can set it to any horizontal (the first value) and vertical (the second value) values you want, including keywords like top, bottom, left, and right. Figure 14.4 uses transform: skew(); and background gradients to create a shape that looks like a paper folded in three places.

The text "This is my Fun with Skew Playground, cool eh?" is present over four elements. Transformation (left tilt and right tilt) is applied to the second and third elements, respectively, while the top and bottom elements remain unchanged. This creates a shape that resembles a paper folded in three places.
Figure 14.4 Having fun with transform: skew() and background gradients.

The HTML for Figure 14.4 is four <div> elements, and the CSS in Listing 14.2 changes the transform origin for the two inner elements and adds skew to tilt them on the screen.

Listing 14.2 CSS for Creating a Folded Paper Effect

div {
  width: 50%;
  height: 3rem;
  background: linear-gradient(#4138f5 0%, #59c4e4 100%);
  padding: 1rem;
  color: white;
  margin: 0 auto;
  text-align: center;
}
.two {
  background: linear-gradient(#59c4e4 0%, #4138f5 100%);
  transform-origin: top right;
  transform: skew(15deg);
}
.three {
  transform-origin: bottom right;
  transform: skew(345deg);
}
.four {
  background: linear-gradient(#59c4e4 0%, #4138f5 100%);
}

Using Multiple Transformations

All the previous examples use just one transformation at a time, but you can use as many as you need, separating each pair of methods with a space. For example, to scale an image and tilt it, you could write CSS like so:

img {
  transform: scale(1.2) skew(5deg);
}

Or to apply rotation, scaling, translation, and skew to your image, you could write CSS like so:

img {
  transform: rotate(30deg) scale(1.2) translate(15px,0) skew(5deg);
}

The thing to remember is that the order in which you place the functions in your CSS is the order in which they are applied. Changing the order could change how an element looks on the page. This mostly applies to translate() but could affect other functions, depending on what you do. Test your designs a lot.

Note

There is one other transformation method you can use: transform: matrix();. This method gives you almost pixel-perfect control over exactly how your elements are transformed. Understanding it requires a lot of math, but tools—such as CSS Transform Generator (http://angrytools.com/css-generator/transform/)—are available to build matrices for you.

Transforming Elements in Three Dimensions

All the properties discussed to this point in the lesson apply to elements in two-dimensional space. But the CSS transform function can also affect elements in three dimensions. There are 3D versions of most of the transform functions, including the following:

  • Image rotatex(), rotatey(), and rotate3d(x, y, z, angle)—Allows you to define a point in 3D space around which to rotate the element.

  • Image scale3d(x, y, z) and scalez()—Resizes the element in three dimensions.

  • Image translate3d(x, y, z) and translatez()—Moves the element in three dimensions.

The trick to transforming an element in three dimensions is to define the perspective from which the third dimension is viewed. The best way to do this is to set the perspective property on the parent element. The value of this property determines the intensity of the effect; for example, further away makes the effect less intense than up close. You can use any length value as the perspective, like so:

perspective: 40cm;

Another thing to keep in mind is that without perspective, elements that have been transformed on the three-dimensional plane will look no different from elements skewed or otherwise transformed in two dimensions. In order for your 3D transformations to be apparent, you need to have some frame of reference. Figure 14.5 demonstrates this with a blank container element around each inner element that has been rotated in 3D.

There are three elements: Rotate-X, Rotate-Y, and Rotate-Z present with a respective blank container element that serves as the frame of reference. The elements are rotated vertically, horizontally, and diagonally, respectively.
Figure 14.5 The outlined squares contain the rotated inner elements.

Working with CSS Transitions

Once you know how to transform elements, you can create simple animations by using the transition properties. These properties allow the browser to control an animation, while taking direction from the CSS. The transition property is a shorthand property for several other properties:

  • Image transition-property—Indicates which CSS properties should transition.

  • Image transition-duration—Defines the amount of time the transition will take.

  • Image transition-timing-function—Specifies the function used to determine how intermediate values in the animation are computed.

  • Image transition-delay—Defines when the transition will start.

The shorthand notation for the transition property is written like so:

transition: property duration timing-function delay;

The best way to understand transitions is to create some. Still screenshots would only suggest how these animations would look, so be sure to follow along so you can see the effects in a browser.

First, create a <div> element on your page and give it some styles so that it’s visible:

div {
  width: 10rem;
  height: 10rem;
  background: linear-gradient(#6058ef 0%, #ffffff 100%);
  border: solid 5px #0096ff;
}

Then create a new version of the element that appears when the mouse hovers over it:

div:hover {
  width: 20rem;
}

If you view this in a browser now and hover over the <div> element, the <div> element will change instantly from 10rem tall to 20rem. But you can slow this down and animate the change by using a transition property (applied to the parent element rather than to the :hover state):

transition: width 2s linear;

Now when you mouse over the box, it slowly gets larger over a two-second period. When you move your mouse off the box, it transitions back at the same speed. You can add multiple properties to transition, with a comma separating each pair. Add the style to the :hover state and then add a second transition, like so:

transition: width 2s linear, height 2s ease;

Transitions get interesting when you use them with transformations. To see this, change the hover state on the <div> to transform the element to be larger and rotated:

div:hover {
  transform: translate(10rem,11rem) scale(2) rotate(45deg);
}

These styles move the element 10rem left and 11rem down, make it twice as large, and rotate it 45 degrees. If you don’t include a transition, the effect can be jarring at best, and at worst it will not even work. It won’t work when the user positions the mouse on the initial location so that it’s not hovering over the element in the final location, such as the upper-left corner. When you add a transition, as shown here, the change is less abrupt and lets the user follow along with the mouse when it stops:

transition: transform 3s ease-in-out;

Listing 14.3 shows the full HTML and CSS for this rotating cube.

Listing 14.3 A Rotating Cube

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>A Rotating Cube</title>
    <style>
      div {
        width: 10rem;
        height: 10rem;
        background: linear-gradient(#6058ef 0%, #ffffff 100%);
        border: solid 5px #0096ff;
        transition: transform 3s ease-in-out;
      }
      div:hover {
        transform: translate(10rem,11rem) scale(2) rotate(45deg);
      }
    </style>
  </head>
  <body>
    <div></div>
  </body>
</html>

You can choose nearly any CSS property you want to transition using the transition-property property. You can also use the keyword all to tell the browser to apply the transition to every property that changes. There are a couple general rules for what you can and cannot transition:

  • Image You should transition between absolute values. This means you can, for example, transition from a height of 10% to a height of 30%, but you can’t transition from 10rem to auto.

Note

The CSS3 specification says that you cannot transition using percentage lengths. But most browsers support that anyway. The specification also says you cannot transition to or from auto, but WebKit browsers (Safari and Chrome) support this as well, though sometimes with strange effects. As usual, always test your designs thoroughly.

  • Image Adding transitions on pseudo-elements (::before and ::after) doesn’t always work, but in the CSS3 specification, if an element has the quality animatable, then transitions should work on it, too.

  • Image Most browsers don’t support transitioning background gradients.

For a list of properties that can be transitioned, see http://oli.jp/2010/css-animatable-properties/. And for a really interesting example of all the ways you can change a very simple element, visit the Animatable site (http://leaverou.github.io/animatable/).

Changing the Timing of a Transition

Once you’ve set a property to transition, you need to affect the time it takes to transition, how it’s going to transition, and when it’s going to start. For these effects, you need the transition-duration, transition-timing-function, and transition-delay properties. The transition-duration and transition-delay properties should be fairly obvious: You set the amount of time—in minutes, seconds, milliseconds, and so on—for the transition to take (transition-duration) and for the time until the animation starts (transition-delay).

The transition-timing-function property is a bit more difficult to understand. This property takes a function that tells the browser how to perform the animation as it transitions the element. It takes the following values:

  • Image ease—Causes the animation to start slowly, speed up quickly, and then slow down again at the end. This is the default.

  • Image ease-in—Causes the animation to start slowly and then get up to speed.

  • Image ease-out—Causes the animation to start at speed and then slow down at the end.

  • Image ease-in-out—Causes the animation to start slowly, speed up, and then slow down at the end. It’s different from ease in that it doesn’t get up to full speed as quickly.

  • Image linear—Causes the animation to move at a steady speed the entire time.

You can also define your own custom timing function with the cubic-bezier() function. A tool you can use to help build timing functions is the CSS Easing Animation Tool (https://matthewlein.com/tools/ceaser).

NOTE:

The best way to understand the timing functions is to try them out. Try changing the ease-in-out value in Listing 14.3 to something else, such as linear, and see how the animation changes.

Using JavaScript to Trigger Transitions

Transitions make it easy to add animation to your web pages, but there are some situations where you might want an animation, but there isn’t an appropriate CSS selector. For example, CSS has a :hover class but doesn’t have a :click pseudo-class, so if you want to trigger a transition when someone clicks on an element, you need to do it with JavaScript.

One way to do this is to define classes that you can assign when an element is clicked. You would have a class for the element itself and a class for when it’s clicked, like so:

div {
  width: 10rem;
  height: 10rem;
  background: #ff0000;
  transition: transform 3s linear;
}
div.clicked {
  transform: rotate(230deg);
}

Then, using jQuery, which you’ll learn more about in Lesson 26, “Using Third-Party JavaScript Libraries and Frameworks,” you add and remove the clicked class, like so:

$(function() {
  $("div").click(function(){
    $(this).toggleClass('clicked');
  });
});

You can also do this without a library by using plain JavaScript. Listing 14.4 shows a fully functional version of the script and CSS for this example. (You will learn more about this in Lesson 20, “Getting Started with JavaScript Programming.”)

Listing 14.4 Spinning a Box When You Click It

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Spin Box on Click</title>
    <style>
      div {
        width: 10rem;
        height: 10rem;
        background: #ff0000;
        transition: transform 3s linear;
      }
      div.clicked {
        transform: rotate(230deg);
      }
    </style>
    <script src="https://ajax.googleapis.com/ajax/
libs/jquery/3.3.1/jquery.min.js"></script>
  </head>
  <body>
    <div></div>
    <script>
    $(function() {
    $("div").click(function(){
        $(this).toggleClass('clicked');
      });
    });
    </script>
  </body>
</html>

Summary

This lesson taught you how to add basic animation to web pages by transforming elements and then having the browser transition those transformations slowly and smoothly. In the first section you learned how to use the transform property. You learned how to rotate an element around an axis with rotate(). Then you learned how to make an element larger or smaller with the scale() function. With the translate() function, you learned that you could move elements from where they would normally be placed. And the skew() function showed you how to tilt elements on the horizontal and vertical axes. But there are also three-dimensional transformations. And in this lesson, you learned how to use the rotatex(), rotatey(), and rotate3d(x, y, z, angle) functions to spin an element around a point in space. You learned that the scale3d(x, y, z) and scalez() functions resize the element in the three dimensions, and translate3d(x, y, z) and translatez()move an element in three dimensions. You can’t work in 3D without perspective, so this lesson covered the perspective() property as well.

This lesson really got interesting when you learned how to animate transformations with the transition properties. You learned how to define the properties to transition, how to define the time a transition takes, and how to set a delay for a transition so that it does not start immediately. You also learned about the different timing functions you can use to affect how a transition looks on the screen. This lesson also covered, very briefly, how to kick off a transition with JavaScript; you will learn a lot more about this in future lessons.

Q&A

Q. If I want to transform just a section of a paragraph, such as a code block, is this possible with the transform property?

A. The transform properties apply only to block-level elements and a few table elements. If you need to transform an inline element such as a <code> block, you should first add the display: block; or display: inline-block; style to it so that the browser knows that it needs to treat this like a block-level element. Then you can transform it.

Q. If I want to have different transition values for multiple properties, how do I do that?

A. You can separate multiple transitions with commas, like so: transition: transform 3s linear, background 1s ease;

This transitions the transform property over three seconds in a  linear  fashion, while transitioning the  background  property over one second with the  ease  function.

Workshop

The workshop contains quiz questions and exercises to help you solidify your understanding of the material covered.

Quiz

1. How can you spin an element so that it displays upside down?

2. What would transform: scale(3); do to an element?

3. How is using translate() different from using CSS positioning?

4. What are two ways to slant an element 5 degrees?

5. What is a style rule you could use to make a paragraph with the class special so that it is transformed half as big as normal and slanted 45 degrees counterclockwise?

6. Which value would make a 3D transformation more intense: perspective: 1m; or perspective: 1in;?

7. How do you move an element 15 pixels on the z-axis?

8. How do you define what feature will change in a transition?

9. What is the correct order for properties in the shorthand transition property?

10. Which timing function makes a transition evenly across the entire time period?

Note

Just a reminder for those of you reading these words in the print or e-book edition of this book: If you go to www.informit.com/register and register this book (using ISBN 9780672338083), you can receive free access to an online Web Edition that not only contains the complete text of this book but also features an interactive version of this quiz.

Answers

1. You can use the transform: rotate(180deg); property to turn an element upside down.

2. It would enlarge the element three times the original size while leaving it overlapping the surrounding content.

3. It moves the element from its default position but leaves all the surrounding elements in place.

4. You can use transform: slant(5deg); or transform: slantx(5deg);.

5. Use this style rule:

p.special {
  transform: scale(0.5) skew(45deg);
  }

or use this:

p.special {
  transform: scale(0.5) skew(320deg);
  }

6. The closer value looks more intense, so perspective: 1in;, at 1 inch away rather than 1 meter, would appear more intense.

7. Use transform: translatez(15px); with perspective: 50px;. The value of the perspective doesn’t matter as much as the fact that it’s set.

8. Use transition-property to define the CSS properties to transition.

9. They should be written in this order: transition-property, transition-duration, transition-timing-function, and transition-delay.

10. The linear timing function animates the transition evenly across the time period.

Exercises

  • Image Create a simple photo gallery where the images are thrown down on the page haphazardly. Use the CSS transform property to change how the images display on the screen. The HTML should be a list of images. The design should be created with CSS.

  • Image In Lesson 11, “Using CSS to Do More with Lists, Text, and Navigation,” you created a menu where the background and text colors changed when the mouse rolled over them. Go back to that menu and add a transition to the changes.

..................Content has been hidden....................

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