# Transitions

  • Transitions allow you to gradually or smoothly change some properties from one style to another
  • The transition is on a different state (like :hover, :active, :focus, :checked, ...) of the element itself or on a different state of the parent element
  • Most of the properties can be changed smoothly but, the font-family and the background-image for example can not
  • Transitions are often (not always) used in combination with transformations
  • The transition properties are:
EMMET instruction result default description
trsp + TAB transition-property: ; all property to change
trsdu + TAB transition-duration: ; 0 duration of the transition in seconds (s) or milliseconds (ms)
trsde + TAB transition-delay: ; 0 delay (s orms ) before the transition starts
trstf + TAB transition-timing-function: ; ease speed curve of the transition effect
trs + TAB transition: ; shorthand for all the above properties

# One property

  • Span 1: Change the background-color over a period of 1000ms (or 1s)

 


 


span:first-child {
    transition: background-color 1000ms;
}
span:first-child:hover {
    background-color: coral;
}
1
2
3
4
5
6
  • Span 2: Change the border-radius over a period of 2000ms (or 2s)
    • Notice that the background-color changes immediately!

 



 


span:nth-child(2) {
    transition: border-radius 2000ms;
}
span:nth-child(2):hover {
    background-color: skyblue;
    border-radius: 50%;
}
1
2
3
4
5
6
7
  • Span 3: Transform (rotate and scale) the span tag over a period of 500ms (or .5s)

 


 


span:last-child {
    transition: transform 500ms;
}
span:last-child:hover {
    transform: rotate(30deg) scale(1.2);
}
1
2
3
4
5
6
    
<div>
    <span>1</span>
    <span>2</span>
    <span>3</span>
</div>

    
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
html { font-size: 16px; }
body { font-family: Verdana, Geneva, sans-serif; line-height: 1.5; padding: 1rem; text-align: center; }
div { border: 1px solid darkgray; background-color: rgba(169, 169, 169, 0.3); display: inline-block; margin: 1rem; }
span { display: inline-block; width: 5rem; line-height: 5rem; margin: 1rem; border: 1px solid #000; background-color: lightgreen; }
span:first-child { transition: background-color 1000ms; }
span:first-child:hover { background-color: coral; }
span:nth-child(2) { transition: border-radius 2000ms; }
span:nth-child(2):hover { background-color: skyblue; border-radius: 50%; }
span:last-child { transition: transform 500ms; }
span:last-child:hover { transform: rotate(30deg) scale(1.2); }
    

REMARK

  • Move the transition from the normal state to the hover state and look how the transition reacts this time
    • The transition ONLY takes place when entering the span tag and NOT when you leave the span tag!

 


 



span:last-child {
    /* transition: transform 500ms; */
}
span:last-child:hover {
    transition: transform 500ms;
    transform: rotate(30deg) scale(1.2);
}
1
2
3
4
5
6
7

# Two or more properties

  • You can transition two or more CSS properties by separating them with a comma
  • Span 1: Change three properties over the same period
  • Span 2: Change the same three properties but with different timing

 


 







span:first-child {
    transition: background-color 1s, border-radius 1s, transform 1s;
}
span:last-child {
    transition: background-color 1s, border-radius 2s, transform 6s;
}
span:hover {
    background-color: skyblue;
    border-radius: 50%;
    transform: rotate(30deg) scale(1.5);
}
1
2
3
4
5
6
7
8
9
10
11
    
<div>
    <span>1</span>
    <span>2</span>
</div>

    
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
html { font-size: 16px; }
body { font-family: Verdana, Geneva, sans-serif; line-height: 1.5; padding: 1rem; text-align: center; }
div { border: 1px solid darkgray; background-color: rgba(169, 169, 169, 0.3); display: inline-block; margin: 1rem; }
span { display: inline-block; width: 5rem; line-height: 5rem; margin: 1rem; border: 1px solid #000; background-color: lightgreen; }
span:first-child { transition: background-color 1s, border-radius 1s, transform 1s; }
span:last-child { transition: background-color 1s, border-radius 2s, transform 6s; }
span:hover { background-color: skyblue; border-radius: 50%; transform: rotate(30deg) scale(1.5); }
    

# All properties

  • When targeting all properties at once, you can use the keyword all or just leave the keyword out because all is the default value



 









img {
    margin: 1rem;
    border: 1px solid #000;
    transition: 2s;
}
img:hover {
    filter: sepia(100%);
    opacity: .5;
    border-radius: 2rem;
    transform: rotate(180deg);
    box-shadow: 0 0 20px rgba(0, 0, 0, 1);
}
1
2
3
4
5
6
7
8
9
10
11
12
    
<figure>
  <img src="https://picsum.photos/id/102/200/200" alt="Raspberries">
</figure>

    
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
html { font-size: 16px; }
body { font-family: Verdana, Geneva, sans-serif; line-height: 1.5; padding: 1rem; text-align: center; }
figure { border: 1px solid darkgray; background-color: rgba(169, 169, 169, 0.3); display: inline-block; padding: 1rem; }
img { margin: 1rem; border: 1px solid #000; transition: 2s; }
img:hover { filter: sepia(100%); opacity: .5; border-radius: 2rem; transform: rotate(180deg); box-shadow: 0 0 20px rgba(0, 0, 0, 1); }
    

DESIGN TIP

For a minimalistic approach to CSS transitions:

  • Use transitions purposefully, enhancing only key elements like buttons or navigation menus.
  • Keep transition durations between 200ms to 500ms for quick, smooth feedback.
  • Ensure consistency in transition effects across the website to maintain a cohesive user experience.

REMARK

When speed is important (e.g. on older smartphones), it's best to target all properties individually like we did in the previous example (as the all keyword loops over ALL changeable properties of the element, not only the properties you write in the hover state)

# Sequential transitions

  • The transition-delay property specifies the duration to wait before starting a property's transition effect

WARNING

When using the transition-duration AND the transition-delay with the shorthand property, the transition-duration ALWAYS comes first!

  • In the example below, we use some of the transitions of the previous example but now in sequential order
    • The transition on the border-radius starts immediately and takes 300ms
    • The transition on the box-shadow starts after 300ms and takes 800ms
    • Then there is a pauze of 400ms because the transform starts at 1.5s



 
 
 


img {
    margin: 1rem;
    border: 1px solid #000;
    transition: border-radius 300ms,
        box-shadow 800ms 300ms,
        transform 1s 1.5s;
}
1
2
3
4
5
6
7
    
<figure>
  <img src="https://picsum.photos/id/102/200/200" alt="Raspberries">
</figure>

    
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
html { font-size: 16px; }
body { font-family: Verdana, Geneva, sans-serif; line-height: 1.5; padding: 1rem; text-align: center; }
figure { border: 1px solid darkgray; background-color: rgba(169, 169, 169, 0.3); display: inline-block; padding: 1rem; }
img { margin: 1rem; border: 1px solid #000; transition: border-radius 300ms, box-shadow 800ms 300ms, transform 1s 1.5s; }
img:hover { filter: sepia(100%); opacity: .5; border-radius: 2rem; transform: rotate(180deg); box-shadow: 0 0 20px rgba(0, 0, 0, 1); }
    

# Timing function

  • You can use several keywords for the transition-timing-function function
  • A few examples:
    • All span tags behave as a block element with a default width of 130px
      (IMPORTANT: the transitions only work if you specify a width other than auto!)
    • On the hover state, the span tag grows to his full width of 100% but every span tag has his own timing function



 


 


 


 


 


 


span {
    ...
    display: block;
    width: 130px;
}
span:hover {
    width: 100%;
}
span:first-child {
    transition: width 2s linear;
}
span:nth-child(2) {
    transition: width 2s ease;
}
span:nth-child(3) {
    transition: width 2s steps(4);
}
span:nth-child(4) {
    transition: width 2s cubic-bezier(0.1, 0.7, 1.0, 0.1);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    
<div>
    <span>linear</span>
    <span>ease-in-out</span>
    <span>steps(4)</span>
    <span>cubic-bezier()</span>
</div>

    
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
html { font-size: 16px; }
body { font-family: Verdana, Geneva, sans-serif; line-height: 1.5; padding: 1rem; }
div { border: 1px solid darkgray; background-color: rgba(169, 169, 169, 0.3); margin: 1rem; padding: .5rem; }
span { margin-bottom: .5rem; padding: .5rem; border: 1px solid #000; background-color: skyblue; display: block; width: 130px; }
span:hover { width: 100%; }
span:first-child { transition: width 2s linear; }
span:nth-child(2) { transition: width 2s ease-in-out; }
span:nth-child(3) { transition: width 2s steps(4); }
span:nth-child(4) { transition: width 2s cubic-bezier(0.1, 0.7, 1.0, 0.1); }
    

TIP: Custom cubic_bezier() timing function (optional)

  • To create your own custom timing function, you can use cubic-bezier.com but it can also be done inside the browser's DevTools (Firefox: left image, Chrome: right image)
    • Select one of the span tags
    • Click on the icon near the timing function
    • Play with the start and end handles to create your custom function
    • Copy the cubic_bezier() code and paste it in to your transition function

cubic-bezier

# Targeting a child element

  • Sometimes you need to move the hover state to the parent element to create an attractive effect
  • When you hover the span element in the bottom left corner, the transformation sometimes "shakes" a bit
  • Let's make the effect on the following example a bit nicer:
    • Replace span:hover {...} with div:hover span {...}
 



div:hover span {
    transform: rotate(-45deg);
}
1
2
3
    
<div>
    <span>rotate(45deg)</span>
</div>

    
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body { font-family: Verdana, Geneva, sans-serif; line-height: 1.5; padding: 1rem; text-align: center; }
section { display: flex; flex-wrap: wrap; }
div { border: 1px solid darkgray; background-color: rgba(169, 169, 169, 0.42); display: inline-block; margin: 2rem; }
span { display: inline-block; width: 150px; line-height: 150px; font-size: .9rem; text-align: center; border: 1px solid #000; background-color: rgba(248, 204, 52, 0.66); transform-origin: top right; transition: 1s; }
span:hover { /* replace with: div:hover span */ transform: rotate(-45deg); }
    

# Example

# Rising buttons

  • This page contains a basic navbar as we saw at the Flexbox course page
  • When you hover an a tag, it is scaled along the X axis, moved up by .2rem and it gets some new colors and a little drop shadow




 

 







nav a {
    ...
    color: floralwhite;
    border: 1px solid coral;
    transition: 300ms;
}
a:hover {
    transform: scaleX(1.05) translateY(-.2rem);
    background-color: floralwhite;
    border-color: dimgray;
    color: dimgray;
    box-shadow: 0 5px 5px rgba(0, 0, 0, .2);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
    
<nav>
  <ul>
      <li>
          <a href="#!">HOME</a>
      </li>
      <li>
          <a href="#!">TWITTER</a>
      </li>
      <li>
          <a href="#!">SLACK</a>
      </li>
  </ul>
</nav>

    
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
html { font-size: 16px; }
body { font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; line-height: 1.5; padding: 2rem; background-color: coral; }
nav { font-weight: bold; }
nav ul { display: flex; list-style-type: none; text-align: center; }
nav li { flex: 1 1 auto; display: flex; }
nav a { flex: 1 1 auto; line-height: 2; color: floralwhite; border: 1px solid coral; transition: 300ms; }
a:hover { transform: scaleX(1.05) translateY(-.2rem); background-color: floralwhite; border-color: dimgray; color: dimgray; box-shadow: 0 5px 5px rgba(0, 0, 0, .2); }
    

# Overline menu item

  • When you hover an a tag, it changes colors and gets an overline.
    
<nav>
  <ul>
      <li>
          <a href="#!">Home</a>
      </li>
      <li>
          <a href="#!">Twitter</a>
      </li>
      <li>
          <a href="#!">Slack</a>
      </li>
  </ul>
</nav>

    
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
html { font-size: 16px; }
body { font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; line-height: 1.5; padding: 2rem; }
nav ul { list-style: none; display: flex; }
nav ul li { margin-right: 20px; }
nav ul li a { color: #333333; border-top: 2px solid white; padding-top: 7px; text-decoration: none; transition: .5s; }
nav ul li a:hover { color: black; border-top-color: black; }
    
Last Updated: 9/10/2023, 2:54:38 PM