The transition property
The first step in CSS animation is understanding the transition property and its values. A transition is a property that enables CSS elements to change from one state to another in a smooth, animated manner.
Consider the following example:
.target { Â Â font-size: 14px; Â Â transition: font-size 4s 1s; } .target:hover { Â Â font-size: 36px; }
In this example, the transition property is applied to the target
class to change the font-size
attribute from 14 px to 36 px on hover. Within this example, we can observe the following:
- The transition property is described within the element’s original value, not in the changed one
- It’s possible to specify the element that will change within the transition property
- We can set the transition duration immediately after describing which property will be the transition target or as the first attribute (4s)
Consider another example:
.target { Â Â font-size: 14px; Â Â color: red; Â Â transition: 4s ease-in-out 1s; } .target:hover { Â Â font-size: 36px; Â Â color: blue; }
In the preceding example, we’ve added the color
property to the target
class. If we apply this CSS, we’ll notice that both properties (color
and font-size
) are influenced by the transition:
- When the transition property is not specified, it applies to all other properties of the element.
- We can define
transition-timing-function
to specify the transition speed curve. In the preceding example,ease-in-out
specifies a transition effect with a slow start and end. - We can introduce a delay to the transition using
transition-delay
or its shorthand after the transition duration (1s
).
Transition properties
The following table outlines the key transition properties, providing a brief description and the type of value each property accepts. These properties allow developers to control various aspects of the transition effect, such as the duration, timing, and specific CSS properties that should transition:
Property |
Type of value |
Description |
transition (shorthand) |
Set of values |
A shorthand for combining the transition properties into a single property. |
transition-property |
CSS property |
Determines the CSS property name for which the transition effect is applied. |
transition-duration |
Seconds or milliseconds |
Specifies the duration, in seconds or milliseconds, for the transition effect to complete. |
transition-timing-function |
cubic-bezier(n,n,n,n) or ease | ease-in | ease-out | ease-in-out | linear | step-start | step-end |
Defines the speed curve of the transition effect. |
transition-delay |
Seconds or milliseconds |
Sets a delay, in seconds, before the transition effect begins. |
[NEW!] transition-behavior |
normal | allow-discrete |
Specifies whether transitions will be started for properties whose animation behavior is discrete. |
Table 5.1 – The transition properties and its accepted values
Important note
transition-behavior
is a new property that doesn’t work in older browsers by default. When using {transition-behavior: allow-discrete}
to set discrete animations, make sure this is at the end of the CSS block to avoid specificity conflicts with the transition shorthand.
The transition shorthand follows a specific order of properties: first, the property name; second, the duration; third, the timing function; fourth, the transition delay; and finally, the transition behavior.
For instance, in the following shorthand, opacity
is the property name, 2s
is the duration, ease-in
is the timing function, 0.5s
is the delay, and normal
is the transition behavior. If any of these properties are not specified, their default values will be used:
transition: opacity 2s ease-in 0.5s normal
Exercises with transitions
After understanding the theory behind CSS transitions, it’s time to put that knowledge into practice. Let’s create CSS animations that will provide a solid foundation for further improvement and can be applied to various projects. By working through these exercises, you’ll gain hands-on experience that will enhance your ability to craft dynamic and engaging web animations.
Exercise #1 – simple menu animation
Our first exercise will be a simple, elegant animated menu. Begin by creating a project folder titled CSS-animations-exercise-transitions
. Open this folder in VS Code and create two essential files: index.html
and style.css
.
Note
While it’s possible to embed CSS styles directly within the HTML file using the <style>
tag within <head>
, it’s advisable to separate responsibilities for a cleaner HTML file and to avoid unnecessary clutter.
Here’s the initial HTML file:
<!DOCTYPE html> <html lang="en"> <head> Â Â <meta charset="UTF-8"> Â Â <meta name="viewport" content="width=device-width, Â Â Â Â Â Â Â Â initial-scale=1.0"> Â Â <title>CSS Animated Menu</title> Â Â <link rel="stylesheet" href="style.css"> </head> <body> Â Â <aside> Â Â Â Â <ul> Â Â Â Â Â Â <li> Â Â Â Â Â Â Â Â <a href="#"> Â Â Â Â Â Â Â Â Â Â <img src="./svg/new.svg" Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â alt="New Document" Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â class="menu-icon"> Â Â Â Â Â Â Â Â Â Â <span>New Document</span> Â Â Â Â Â Â Â Â </a> Â Â Â Â Â Â </li> Â Â Â Â Â Â <li> Â Â Â Â Â Â Â Â <a href="#"> Â Â Â Â Â Â Â Â Â Â <img src="./svg/recent.svg" Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â alt="Open recent" Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â class="menu-icon"> Â Â Â Â Â Â Â Â Â Â <span>Recent</span> Â Â Â Â Â Â Â Â </a> Â Â Â Â Â Â </li> Â Â Â Â Â Â <li> Â Â Â Â Â Â Â Â <a href="#"> Â Â Â Â Â Â Â Â Â Â <img src="./svg/search.svg" Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â alt="Search documents" Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â class="menu-icon"> Â Â Â Â Â Â Â Â Â Â <span>Search</span> Â Â Â Â Â Â Â Â </a> Â Â Â Â Â Â </li> Â Â Â Â </ul> Â Â </aside> </body> </html>
In this file, we’ve crafted a straightforward menu list enclosed within the <
aside>
tag.
A single menu list is constructed using an unordered list (ul
) comprising three list items (li
). Each item incorporates an image element (img
) and a text element (span
), enveloped within an anchor (a
) tag to denote links to other pages.
Image download instructions
To streamline the process, we've organized the images into a folder, ready for you to download. Please procure them from the provided link (https://packt.link/shFG2) and save them within a newly created folder named svg
. Ensure this folder is nested within the project directory to maintain proper file paths.
Linking HTML and CSS files with <link>
Inspect the preceding HTML snippet. Within the <head>
tag, we’ll find the following element:
<link rel="stylesheet" href="style.css">
This tag establishes a connection between our HTML file and our CSS file. It’s customary to name the primary CSS file style.css
or styles.css
and position it within the same folder as our HTML. With this link established, let’s proceed to create the CSS file and commence styling!
Initial styling
Access the base CSS file and input the following code snippet. We’ll dissect it line by line in sequential order:
/* CSS RESET */ * { Â Â margin: 0; Â Â padding: 0; Â Â box-sizing: border-box; } /* INITIAL STYLES */ aside { Â Â width: 280px; Â Â background-color: #093c9b; Â Â padding: 10px; Â Â height: 100vh; } ul li { Â Â list-style: none; Â Â padding: 10px 15px; Â Â background-color: #053081; Â Â border-radius: 10px; Â Â margin: 10px; } ul li a { Â Â display: flex; Â Â gap: 20px; Â Â align-items: center; Â Â color: #fff; Â Â text-decoration: none; Â Â font-family: 'Verdana', sans-serif; Â Â font-size: 16px; Â Â line-height: 1.6; } ul li a img { Â Â width: 20px; Â Â height: 20px; }
Understanding the file
The code starts with a CSS reset. This technique is frequently employed to eliminate any default CSS applied by the browser to HTML files. It standardizes the margin and padding of all elements to 0
and ensures that the box-sizing
property is set to border-box
for all elements, thereby computing the width inclusive of padding and border sizes. This approach establishes a uniform foundation for styling across various browsers:
* { Â Â margin: 0; Â Â padding: 0; Â Â box-sizing: border-box; }
Styling the aside element
The <aside>
element serves as the container for our menu list. The provided code configures its width, background color, padding, and height:
aside { Â Â width: 280px; Â Â background-color: #093c9b; Â Â padding: 10px; Â Â height: 100vh; }
Note that the background color is specified using hexadecimal encoding, allowing for easy experimentation with different color values.
Styling the list items (ul li)
These styles target the <li>
elements nested within <ul>
. They eliminate the default list style and specify the padding, background color, border radius, and margin for each list item, enhancing their visual presentation:
ul li { Â Â list-style: none; Â Â padding: 10px 15px; Â Â background-color: #053081; Â Â border-radius: 10px; Â Â margin: 10px; }
Styling anchor elements within list items (ul li a)
These styles are targeted at the anchor <a>
elements nested within <li>
elements. They employ display: flex
for layout, introduce spacing between elements, vertically align items, define the text color, remove text decoration, and specify the font family, size, and line height, enhancing the appearance and readability of the links:
ul li a {   display: flex   gap: 20px;   align-items: center;   color: #fff;   text-decoration: none;   font-family: 'Verdana', sans-serif;   font-size: 16px;   line-height: 1.6; }
Styling images within anchor elements of list items (ul li a img)
These styles target <img>
elements, which are descendants of <a>
elements within <li>
elements. They establish the width and height of the images to be 20 px each, ensuring uniformity and appropriate sizing within the list items:
ul li a img { Â Â width: 20px; Â Â height: 20px; }
Enhancing CSS cohesion
To uphold the cascading nature of CSS, we adopt a structured approach to writing our styles, aligning them with the HTML structure. We begin by styling the container, then progress to the list items, and finally, address the inline elements, such as <img>
and <a>
. This is the cascading rule of CSS:
- Specificity: CSS selectors are prioritized based on specificity. More specific selectors override less specific ones. For instance,
#id
selectors hold more weight than.class
selectors, which, in turn, supersede element selectors. - Source order: In cases of conflicting styles with identical specificity, the style declaration that appears last in the CSS file, or is closest to the targeted element in an external stylesheet, takes precedence.
This hierarchical structure ensures the systematic application of styles and empowers developers to manage the visual presentation of HTML elements efficiently.
The initial result of our exercise will be as follows:
Figure 5.1 – Initial styling for the menu
Introducing our initial animation
Let’s animate the menu list items by adjusting their background color when the mouse hovers over them. Initially, we define the style we want to apply when the element is in the :
hover
state:
ul li:hover { Â Â background-color: #0a4fbd; }
This CSS declaration targets <li>
elements within <ul>
elements and alters their background color when they’re hovered over by the cursor.
Upon hovering over the <li>
element, we’ll notice an immediate color change. However, this change lacks smoothness and natural transition, as it’s not yet animated.
Figure 5.2 – Applying the :hover styling to the menu
Now, we’re integrating the transition element into the primary ul li
selector to dictate the animation characteristics. Add the following line within the ul li
CSS properties:
transition: background-color 0.5s ease-in-out;
This line utilizes the shorthand transition property to encompass all the necessary transition properties for our animation. It’s a concise alternative to individually specifying the transition properties, as demonstrated here:
  transition-property: background-color;   transition-duration: 0.5s;   transition-timing-function: ease-in-out;
Here’s a breakdown of the components:
transition-property: background-color
determines the CSS property that will smoothly transition. In this scenario, it indicates the transition of the background color of an element.transition-duration: 0.5s
denotes the length of the transition effect. It’s set to 0.5 seconds, indicating that any changes to thebackground-color
property will transition over half a second:- Note: In JavaScript, it’s advisable to use milliseconds (ms) for time measurements to maintain consistency
transition-timing-function: ease-in-out
specifies the timing function employed for the transition. This function governs the rate of change of the transition effect over time.ease-in-out
initiates slowly, accelerates midway, and then decelerates toward the end, resulting in a smooth and natural transition effect.
Overall, this property declaration ensures that when the background color of an element changes, it does so smoothly over a duration of 0.5 seconds with a gradual acceleration and deceleration effect.
Congratulations! Our first animation is now complete. Take a moment to review the HTML file and observe the animation in action. Feel free to experiment with the transition further by adjusting parameters such as duration, delay, and other values to customize the effect.
Here’s the final CSS file for this exercise:
/* CSS RESET */ * { Â Â margin: 0; Â Â padding: 0; Â Â box-sizing: border-box; } /* INITIAL STYLES */ aside { Â Â width: 280px; Â Â background-color: #093c9b; Â Â padding: 10px; Â Â height: 100vh; } ul li { Â Â list-style: none; Â Â padding: 10px 15px; Â Â background-color: #053081; Â Â border-radius: 10px; Â Â margin: 10px; Â Â transition: background-color 0.5s ease-in-out; } ul li:hover { Â Â background-color: #0a4fbd; } ul li a { Â Â display: flex; Â Â gap: 20px; Â Â align-items: center; Â Â color: #fff; Â Â text-decoration: none; Â Â font-family: 'Verdana', sans-serif; Â Â font-size: 16px; Â Â line-height: 1.6; } ul li a img { Â Â width: 20px; Â Â height: 20px; }
This code will produce this result:
Figure 5.3 – Visual representation of the exercise coding
The following are common issues that might be encountered in this exercise:
- Is the CSS not being applied?
- Ensure that the CSS file resides in the same directory as the HTML file
- Double-check the placement and spelling of the
(<link rel="stylesheet" href="style.css">)
link tag within the HTMLhead
tag
- Is the CSS functioning but some elements remain unstyled?
- Verify the accuracy of class names and properties. Remember, CSS is case-sensitive.
- Remember to save changes (Ctrl + S) and refresh the HTML file in
browser.qwq
.
If the code has been reviewed and appears identical to the instructions, consider downloading the provided source code to facilitate learning.
For detailed resolution, refer to the resolution code available at this link: https://packt.link/g24bq
Exercise #2 – adding more animations to the menu
The menu already boasts a polished style, but let’s elevate it further. We’ll enhance it by making the font weight bolder when hovering over the <
li>
element.
For this second exercise, duplicate the HTML file in the same folder and rename it to sidebar-menu-with-animations.html
.
Inspect the <
li>
elements:
<li> Â Â Â Â Â Â Â Â <a href="#"> Â Â Â Â Â Â Â Â Â Â <img src="./svg/search.svg" Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â alt="Search documents" Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â class="menu-icon"> Â Â Â Â Â Â Â Â Â Â <span>Search</span> Â Â Â Â Â Â Â Â </a> Â Â Â Â Â Â </li>
Each <li>
contains an <img>
element with the menu-icon
class assigned and a <span>
tag containing the link label. We’ll animate the <img>
tag to enlargen when hovered over and make the text bolder simultaneously:
ul li:hover a { Â Â font-weight: bold; } ul li:hover a img { Â Â width: 24px; Â Â height: 24px; }
Interpreting this CSS code, the browser is instructed that when hovering over the <li>
element, the child <a>
element will have a bolder font weight, and the child <img>
element will increase in size. Even when altering the behavior of a child element, the trigger (hover
) can be set on the parent element to execute the specified behavior.
Upon reviewing the application, it becomes apparent that while the transition of the background persists, the newly defined properties aren’t transitioning. This occurs because although we can set the :hover
trigger to a parent in CSS, we must still specify the transition values into the element itself. Let’s rectify this:
ul li a { Â Â display: flex; Â Â gap: 20px; Â Â align-items: center; Â Â color: #fff; Â Â text-decoration: none; Â Â font-family: 'Verdana', sans-serif; Â Â font-size: 16px; Â Â line-height: 1.6; Â Â transition: font-weight 0.5s; } ul li a img { Â Â width: 20px; Â Â height: 20px; Â Â transition: all 0.5s; }
Enhancing animation performance – key points
In the menu’s <a>
tag, there are several CSS properties defined, whereas only two properties are specified for the image in the <
img>
tag.
To enhance animation efficiency, we specify which property will be animated within the <a>
element. This optimization is crucial because the transition property defaults to animating all properties, which can potentially slow down the application.
However, in the <img>
tag, where only the desired properties are targeted for animation, we can either use the all
value or omit it altogether, as it defaults to transitioning all properties. This selective approach streamlines the animation process and improves overall performance.
Congratulations! Our animated sidebar menu is now complete!
Figure 5.4 – Animation effect applied in the menu
The CSS file should be looking like this:
/* previous CSS */ ul li a { Â Â display: flex; Â Â gap: 20px; Â Â align-items: center; Â Â color: #fff; Â Â text-decoration: none; Â Â font-family: 'Verdana', sans-serif; Â Â font-size: 16px; Â Â line-height: 1.6; Â Â transition: font-weight 0.5s; } ul li:hover a { Â Â font-weight: bold; } ul li a img { Â Â width: 20px; Â Â height: 20px; Â Â transition: 0.5s; } ul li:hover a img { Â Â width: 24px; Â Â height: 24px; }
The @starting-style rule
To prevent unexpected outcomes, CSS transitions do not activate by default when an element undergoes its initial style update or when its display type changes from none
to another value.
For these transitions to occur on the first style update, it’s possible to use the new @starting-style
rules. These rules define the starting styles for elements that lack a prior state, specifying the property values from which the transition should begin.
You can utilize @starting-style
in two ways: either as a standalone rule or nested within a ruleset.
The standalone rule looks as follows:
@starting-style {   selector {     properties   } }
The nested rule looks as follows:
selector {   properties   @starting-style {     properties   } }
@starting-style
proves particularly beneficial for creating entry and exit transitions for elements that appear in the forefront (such as popovers and modal dialogs), elements transitioning to and from display: none
, and elements newly added to or removed from the DOM. Let’s see how it works in the next exercise.
Exercise #3 – multiple transitions with the @starting-style rule
In this project, we aim to implement an entry animation for each <li>
item in the menu of Exercise #2. The items will smoothly slide in from the left upon appearance. To achieve the desired behavior, we will utilize a combination of named transitions and the @
starting-style
rule.
Let’s create a multiple-transition effect in the Exercise #2 menu:
- Open the folder for Exercise #2. No changes are required in the HTML file; our focus will be on the CSS.
- Begin by defining the initial style for the
<li>
elements. They should be invisible and positioned outside the viewbox to allow for a sliding effect. Add the following code to the end of the CSS file:@starting-style { Â Â ul li { Â Â Â Â opacity: 0; Â Â Â Â transform: translateX(-280px); Â Â } }
- Define the final (default) state for the
<li>
elements, incorporating the properties specified in the starting style to enable transitions:ul li { Â Â list-style: none; Â Â padding: 10px 15px; Â Â background-color: #053081; Â Â border-radius: 10px; Â Â margin: 10px; Â Â transition: Â Â Â Â background-color 0.5s ease-in-out; Â Â opacity: 1; Â Â transform: translateX(0px); }
Note
Setting translateX
to 0
restores the element to its default position.
- Introduce the animation by adding the
opacity
andtransform
properties to the transition:Â Â ul li { Â Â list-style: none; Â Â padding: 10px 15px; Â Â background-color: #053081; Â Â border-radius: 10px; Â Â margin: 10px; Â Â transition: Â Â background-color 0.5s ease-in-out, Â Â opacity 0.5s ease-in-out, Â Â transform .7s ease-in-out; Â Â opacity: 1; Â Â transform: translateX(0px); }
Note
Specifying the properties we want to animate enhances performance by targeting only those properties that change.
The result of our code is as follows:
Figure 5.5 – Animated transition effect
While the animation result is satisfactory, all <li>
elements animate simultaneously, and we desire a cascading effect. To achieve this, introduce a transition delay for each element:
ul li:nth-child(1) { Â Â transition-delay: 0.1s; } ul li:nth-child(2) { Â Â transition-delay: 0.2s; } ul li:nth-child(3) { Â Â transition-delay: 0.3s; }
Congratulations! Our entry animation is now complete. Enjoy the stunning result!
Figure 5.6 – Representation of the developed animation flow
The code containing the result of this exercise is accessible from the link provided here: https://packt.link/j12MO
Note
@starting-style
is only relevant to CSS transitions and doesn’t affect animations with keyframes. The @starting-style rule is a new feature for CSS. At the time of writing this book, it’s only available to the browsers in this list: https://caniuse.com/mdn-css_at-rules_starting-style.
After mastering the basics of CSS transitions, it’s time to explore more complex techniques essential for creating dynamic effects. In the following section, we’ll learn about advanced concepts such as positioning, z-index, blur, and opacity. These skills will enhance your ability to craft sophisticated and engaging animations for your web projects.