Estelle Weyl · Standardista.com · @estellevw ·Press key to advance.

Making it snow
(in the summer)
without JavaScript
(or clouds)

CSS3: Making things beautiful
Making things move.

  • Gradients
  • Opacity
  • Rounded corners
  • CSS3 Selectors
  • Transforms
  • Animations

All of the above are included in this slide. Opacity is from CSS2

Our Background

background-image: 
    linear-gradient( 
    #3A67AB, 
    #E8F6FF);
background-image: 
    linear-gradient(top, 
    #3A67AB 0%, 
    #E8F6FF 100%);
background-image: 
    linear-gradient(270deg, 
    #3A67AB 0%, 
    #E8F6FF 100%);

prefix with -webkit-, -moz-, -ms- & -o-

Snow Flake Gradient

background-image:
  linear-gradient(180deg, 
     rgba(255,255,255,0) 40%, 
     #ffffff 40%, 
     #ffffff 60%, 
     rgba(255,255,255,0) 60%),
  linear-gradient(90deg,  
     rgba(255,255,255,0) 40%, 
     #ffffff 40%, 
     #ffffff 60%, 
     rgba(255,255,255,0) 60%),
  linear-gradient(45deg,  
     rgba(255,255,255,0) 43%, 
     #ffffff 43%, 
     #ffffff 57%, 
     rgba(255,255,255,0) 57%),
  linear-gradient(135deg,  
     rgba(255,255,255,0) 43%, 
     #ffffff 43%, 
     #ffffff 57%, 
     rgba(255,255,255,0) 57%);
		

transparent = rgba(0,0,0,0) not rgba(255,255,255,0)

Opacity

opacity: 1;
opacity: 0.75;
opacity: 0.5;
opacity: 0.25;
opacity: 0;

Rounded Corners

.none { border-radius: 0;}
.fixed { border-radius: 20px; } 
.round { border-radius: 50%;}
.different { border-radius: 10px 30px;}
.ellipse { border-radius: 10px / 30px;}

Snowflake pseudo-Randomness

<div id="flakes"><i></i><i></i><i></i><i></i><i></i><i></i><i></i>...
i:nth-of-type(5n)    { height:30px; width:30px;}
i:nth-of-type(5n+1)  { height:24px; width:24px;}
i:nth-of-type(5n+2)  { height:10px; width:10px;}...

i:nth-of-type(3n)    { animation-delay: 2.3s;}
i:nth-of-type(3n+1)  { animation-delay: 1.5s;}
i:nth-of-type(3n+2)  { animation-delay: 3.4s;}

i:nth-of-type(7n)    { opacity: 0.5;}
i:nth-of-type(7n+1)  { opacity: 0.8;}
i:nth-of-type(7n+2)  { opacity: 0.3;} ...

i:nth-of-type(11n)   { animation-timing-function: ease-in-out;}
i:nth-of-type(11n+1) { animation-timing-function:ease-out;}
i:nth-of-type(11n+2) { animation-timing-function:ease;} ...
i:nth-of-type(11n+5) { animation-timing-function:cubic-bezier(0.2, 0.3, 0.8, 0.9);}

Transforms used

  • transform: translate(200px, 0)
  • transform: rotate(360deg)
  • transform: scale(1.5)
  • transform-origin: -20px -20px

Animations

Browser Support

Prefixed -webkit- and -moz-

  • Chrome
  • Safari 4+
  • Firefox 5+
  • Android
  • iOS

Animation Essentials

  • @keyframes
  • animation-name
  • animation-duration
  • animation-timing-function
  • animation-iteration-count
  • animation-direction
  • animation-play-state
  • animation-delay
  • animation-fill-mode
  • animation (shorthand)

Keyframes

@keyframes falling {

    from {
      top: -40px;
    }

    to {
      top: 1000px;
    }
}

Keyframes

@keyframes falling {

    0% {
      top: -40px;
    }

    100% {
      top: 1000px;
    }

}

Don't forget the %

Don't forget the 100%

Don't quote the animation name

Granular animation control

@keyframes falling {

    0% {
      top: -40px;
    }
    
    10% {
      top: 400px;
    }
    
    90% {
      top: 560px;
    }

    100% {
      top: 1000px;
    }

}

Animating multiple properties

@keyframes fallingAndDimming {

   0% {
      top: -40px;
      opacity: 1;
    }
    
    50% {
      opacity: 0.5;
    }

    100% {
      top: 800px;
      opacity: 1
    }

}
	

Duplicate Keyframes

@keyframes LeftRightWithPause {

    0%, 30%, 100% {
      transform: translateX(-80px);
    }
    
    50%, 80% {
      transform: translateX(40px);
    }
}

Keyframe vendor prefixing

@-webkit-keyframes falling {

    0%{
      -webkit-transform: translateY(0);	
    }

    100% {
      -webkit-transform: translateY(1000px);
    }
}

@-moz-keyframes falling {

    0%{
      -moz-transform: translateY(0);
    }

    100% {
      -moz-transform: translateY(1000px);
    }
}

Animating CSS Transforms

@keyframes falling {

  0%{
    transform: 
         translateY(0)
rotate(0deg)
scale(0.9, 0.9);	
  }

  100% {
    transform:
         translateY(1000px)
rotate(360deg)
scale(1.1, 1.1);
  }

}

-webkit- | -moz-

Vendor Prefixing

@-webkit-keyframes falling {
  0%{
    -webkit-transform: 
      translateY(0) rotate(0deg) scale(0.9, 0.9);	
  }
    
  100%{
    -webkit-transform: 
      translateY(1000px) rotate(360deg) scale(1.1, 1.1);
  }
}
@-moz-keyframes falling {
  0%{
    -moz-transform: 
      translateY(0) rotate(0deg) scale(0.9, 0.9);	
  }
    
  100%{
    -moz-transform: 
      translateY(1000px) rotate(360deg) scale(1.1, 1.1);
  }
}

with ‘transform-origin’

@keyframes falling {
    
  0%{
    transform: 
      translateY(0) rotate(0deg) scale(0.9, 0.9);	
  }
    
  100%{
    transform: 
      translateY(1000px) rotate(360deg) scale(1.1, 1.1);
  }
}
.snowflake {
    -webkit-transform-origin: left -20px;
    -moz-transform-origin: left -20px;
    }

-webkit- | -moz-

Hardware Acceleration

@keyframes falling {

    0%{
      transform: translate3d(0, 0, 0) 
            rotate(0deg) 
            scale(0.9, 0.9);	
    }

    100% {
       transform: translate3d(0, 1000px, 0) 
             rotate(360deg) 
             scale(1.1, 1.1);
    }

}

-webkit- | -moz-

But nothing is animated yet!

We've only declared the keyframes

base CSS

.snowflake {
  display: inline-block;
  height: 20px;
  width: 20px;
 background-image:
   -webkit-linear-gradient(180deg, rgba(255,255,255,0) 40%, #fff 40%, #fff 60%, rgba(255,255,255,0) 60%),
   -webkit-linear-gradient(90deg,  rgba(255,255,255,0) 40%, #fff 40%, #fff 60%, rgba(255,255,255,0) 60%),
   -webkit-linear-gradient(45deg,  rgba(255,255,255,0) 43%, #fff 43%, #fff 57%, rgba(255,255,255,0) 57%),
   -webkit-linear-gradient(135deg,  rgba(255,255,255,0) 43%, #fff 43%, #fff 57%, rgba(255,255,255,0) 57%);

 background-image:
   -moz-linear-gradient(180deg,rgba(255,255,255,0) 0%, rgba(255,255,255,0) 40%, #fff 40%, #fff 60%, rgba(255,255,255,0) 60%, rgba(255,255,255,0) 100%),
   -moz-linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 40%, #fff 40%, #fff 60%, rgba(255,255,255,0) 60%, rgba(255,255,255,0) 100%),
   -moz-linear-gradient(45deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 43%, #fff 43%, #fff 57%, rgba(255,255,255,0) 57%, rgba(255,255,255,0) 100%),
   -moz-linear-gradient(135deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 43%, #fff 43%, #fff 57%, rgba(255,255,255,0) 57%, rgba(255,255,255,0) 100%);
  border-radius: 50%;
  -webkit-transform-origin: left -20px;
  -moz-transform-origin: left -20px;
}

‘animation-name’

.snowflake {
   ...
   -webkit-transform-origin: left -20px;
   -webkit-animation-name: falling; 
   
   -moz-transform-origin: left -20px;
   -moz-animation-name: falling; 
}

‘animation-duration’

.snowflake { 
  ...
  -webkit-transform-origin: left -20px;
  -webkit-animation-name: falling; 
  -webkit-animation-duration: 3s;
  
  -moz-transform-origin: left -20px;
  -moz-animation-name: falling; 
  -moz-animation-duration: 3s;
}

‘animation-timing-function’

.snowflake { transform-origin: left -20px;
  animation-name: falling; 
  animation-duration: 3s;
  -webkit-animation-timing-function: ease-in-out;
  -moz-animation-timing-function: ease-in-out;
}
ease
linear
ease-in 
ease-out 
ease-in-out  
step-start /* same as steps(1, start) */
step-end /* same as steps(1, end) */
steps( X, start|end) /* X = # of steps + when change of value occurs */
cubic-bezier(x1, y1, x2, y2)

-webkit- | -moz-

‘animation-iteration-count’

.snowflake {
   …
  transform-origin: left -20px;
  animation-name: falling; 
  animation-duration: 3s;
  animation-timing-function: ease-in-out;
  -webkit-animation-iteration-count: infinite;
  -moz-animation-iteration-count: infinite;
}

‘infinte’ or number. Default is ‘1’.

-webkit-animation-iteration-count: 3;
-moz-animation-iteration-count: 3;

-webkit- | -moz-

‘animation-delay’

.snowflake { transform-origin: left -20px;
  animation-name: falling; 
  animation-duration: 3s;
  animation-timing-function: ease-in-out;
  animation-iteration-count:infinite;
  -webkit-animation-delay: 2s;
  -moz-animation-delay: 2s;
}

-webkit- | -moz-

‘animation-direction’

.snowflake {
  …
  transform-origin: left -20px;
  animation-name: falling; 
  animation-duration: 3s;
  animation-timing-function: ease-in-out;
  animation-iteration-count:infinite;
  animation-delay: 2s;
  -webkit-animation-direction: normal;
  -moz-animation-direction: normal;
}

Two possible values: normal | alternate;

-webkit-animation-direction: alternate;
-moz-animation-direction: alternate;

-webkit- | -moz-

‘animation’ (shorthand)

.snowflake {
  …
  animation-name: falling; 
  animation-duration: 3s;
  animation-timing-function: ease-in-out;
  animation-iteration-count:infinite;
  animation-delay: 2s;
  animation-direction: normal;
}

. . . can also be written as . . .

.snowflake {
  ...
  -webkit-animation: falling 3s ease-in-out 2s infinite;
  -moz-animation: falling 3s ease-in-out 2s infinite;
}

-webkit- | -moz-

What happens at animation end?

‘animation-fill-mode’

values: none | forwards | backwards | both
.snowflake {
  animation-name: falling; 
  animation-duration: 3s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: 3;
  animation-delay: 5s;
  -webkit-animation-fill-mode: forwards;
  -moz-animation-fill-mode: forwards;
}

. . . or . . .-webkit- | -moz-

.snowflake {
 -webkit-animation: falling 3s ease-in-out 2s 3  forwards;
 -moz-animation: falling 3s ease-in-out 2s 3  forwards;
}

‘animation-fill-mode: bakcwards’

.snowflake {
  animation-name: falling; 
  animation-duration: 3s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: 3;
  animation-delay: 5s;
  -webkit-animation-fill-mode: backwards;
  -moz-animation-fill-mode: backwards;
}

. . . or . . .-webkit- | -moz-

.snowflake {
 -webkit-animation: falling 3s ease-in-out 2s 3  backwards;
 -moz-animation: falling 3s ease-in-out 2s 3  backwards;
}

‘animation-fill-mode: both’

.snowflake {
  animation-name: falling; 
  animation-duration: 3s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: 3;
  animation-delay: 5s;
  -webkit-animation-fill-mode: both;
  -moz-animation-fill-mode: both;
}

. . . or . . .-webkit- | -moz-

.snowflake {
 -webkit-animation: falling 3s ease-in-out 2s 3  both;
 -moz-animation: falling 3s ease-in-out 2s 3  both;
}

Can you stop an animation?

‘animation-play-state’

-webkit-animation-play-state: paused | running
-moz-animation-play-state: paused | running
.snowflake:hover {
  -webkit-animation-play-state: paused;
  -moz-animation-play-state: paused;
  }

What happens at animation end?

  • animationstart
  • animationend
  • animationiteration
el.addEventListener( 'webkitAnimationEnd', 
    function( event ) {
        console.log('Animation Ended'); 
    }, false );
  • webkitAnimationStart
  • webkitAnimationEnd
  • webkitAnimationIteration

Starting next animation at end of previous

el.addEventListener( 'webkitAnimationEnd', 
    function( event ) {
        el.removeClassName('newClass'); 
        setTimeout("el.addClassName('newClass')", 100ms) 
    }, 
    false );

Thank you

Estelle WeylHTML5 & CSS3 for the Real World

www.standardista.com

@estellevw