Estelle Weyl · Standardista.com · @estellevw ·Press key to advance. ·Press 2 for notes. Twitter: #sxsw #CSS3

CSS3
Making it snow
without JavaScript
(or clouds)

CSS3
Making it rain with
dark, depressing clouds
at SXSW 2012

CSS3
Making big bucks with
CSS3 Mad Skillz

CSS3 Features Displaying now?

  • CSS3 Selectors
  • linear gradients
  • opacity
  • RGBA colors
  • border-radius
  • transforms
  • transitions
  • animations

Opacity is from CSS2

Structural Selectors

:nth-child() 

:nth-last-child() 

:nth-of-type() 

:nth-last-of-type() 

:first-child 

:last-child 

:first-of-type 

:last-of-type 

:only-child 

:only-of-type 

:root

:empty

:not(:empty) 
  • Chrome
  • Safari
  • Firefox
  • Opera
  • IE 9

Structural
Selectors

tr:first-child,
tr:last-child {
  font-weight: bold;
}
tr:nth-child(even) {
  background-color: #CCC;
}
tr:nth-child(3) {
  color: #CCC;
}
tr:first-of-type,
tr:last-of-type{
  text-decoration:line-through;
}
tr:nth-of-type(odd) {
  background-color: #FFF;
}
tr:nth-of-type(4n) {
  color: #E2007A;
}
tr:nth-of-type(3n-1) {
  font-style: italic;
}

Row 1
Row 2
Row 3
Row 4
Row 5
Row 6
Row 7
Row 8
Row 9
Row 10

Play Time

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);}

Attribute Selectors

input[placeholder] { 
/* matches any input with a placeholder */}
input[type=email] {
/* exact match */}
abbr[title~=unicorn] { 
/* matches unicorn but not unicorns */}
abbr[title|=en] { 
/* matches en-us and en-uk */}
a[href^=mailto] { 
/* starts with */}
a[href$=pdf]{ 
/* ends in */}
abbr[title*=unicorn] { 
/* matches unicorn and unicorns */}
E:[att] /* have the attribute at all */

E:[att=val] /* exact */

E:[att~=val] /* val is a space separated word */

E:[att|=val] /* with a dash */

E:[att^=val] /* begins with val */

E:[att$=val]  /* ends with val */

E:[att*=val]  /* val is anywhere as a substring */
.
@media print{
  abbr[title]:after { 
    content: "(" attr(title) ")";
  }
  a[href^=http]:after { 
    content: "(" attr(href) ")";
  }
}

More CSS3 Selectors

  • E::before
  • E::after
  • E:enabled
  • E:disabled
  • E:checked
  • input:valid
  • input:invalid
  • input:optional
  • input:required
  • ::selection
  • E:target
  • E:not(s)
  • E > F Child
  • E + F Adjacent sibling
  • E ~ F sibling

Generated Content

.foo:after {
    content: '';
}
  • Chrome
  • Safari
  • Firefox
  • Opera
  • IE 8

The simplest Linear Gradient

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-

More Complex Linear 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%);

-webkit- | -moz- | -ms- || -o-

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

Gradients

background: -webkit-linear-gradient(
90deg,
#E468E8 0%,
#E169FF 33%,
#4FBFF7 66%,
#2C4299 100%);
             
 Angle
             
 First stop
 Second stop
background: radial-gradient(4% 12%,
circle
farthest-side,
#4697AB,
#F7F9FA,
#C344C7 40%);
 Circle  Ellipse
 L/R
 T/B
 colorstop 

Gradients

Tips on Gradient

  • Chrome 3*
    Chrome 10
  • Safari 4*
    Safari 5.1
  • Firefox 3.6
     
  • Opera 11.1
     
  • Internet Explorer 10

Prefixed -webkit-, -moz-, -ms-, -o-

* legacy syntax

Opacity

  • Chrome 1
  • Safari 1.2
  • Firefox 0.9
  • Opera 9
  • IE 4* / IE 9
opacity: 1;
opacity: 0.75;
opacity: 0.5;
opacity: 0.25;
opacity: 0;

AlphaTransparency

color: rgba(0, 0, 0, 1);
background-color: rgba(58, 103, 171, 1);
color: rgba(0, 0, 0, 0.75);
background-color: rgba(58, 103, 171, 0.75);
color: rgba(0, 0, 0, 0.5;
background-color: rgba(58, 103, 171, 0.5);
color: rgba(0, 0, 0, 0.25);
background-color: rgba(58, 103, 171, 0.25);
color: rgba(0, 0, 0, 0)
background-color: rgba(58, 103, 171, 0);
  • Chrome 1
  • Safari 1.2
  • Firefox 0.9
  • Opera 9
  • IE 9

HSLA

color:hsla(
   328, 	 H 
blah
100%, S
44%, L
1.00 A
);
HSLA Colors

AlphaTransparency Tips

  • Used in RGBA & HSLA colors
    rgba(58, 103, 171, 0.5);
    hsla(216, 49%, 45%, 0.5);
    
  • Transparent Shadows
    .trans { box-shadow: -10px 10px rgba(0,0,0,0.3);
             text-shadow: 0 21px 1px rgba(0,0,0,0.3);}
  • Solid Shadows
    .solid { box-shadow: -10px 10px #999;
             text-shadow: 0 21px 1px #999;}

border-radius

Border on slides, code & showflakes

border-radius: 0;
border-radius: 20px;
border-radius: 50%;
  • Chrome / Chrome 4
  • Safari 3 / Safari 5
  • Firefox 1 / Firefox 4

  • Opera 10.5

  • IE 9

% works correctly since Safari 5.1 and FF 4.0

border-radius

.circle {border-radius: 50%;}
.oval { border-radius: 50%;}
.different { border-radius: 10px 30px;}
.elliptical { border-radius: 10px / 30px;}

Transforms used

  • transform: translate(200px, 0)
  • transform: rotate(360deg)
  • transform: scale(1.5)
  • transform-origin: -20px -20px
  • Chrome
  • Safari
  • Firefox 3.5
  • Opera 10.5
  • IE 9
  •   all with vendor prefix

transforms

transitions

Enables the transition of properties from one state to the next over a defined length of time

  • transition-property: properties (or 'all') that transition
  • transition-duration: s or ms it takes to transition
  • transition-timing-function: bezier curve of transition
  • transition-delay: s or ms before transition starts
  • transition: shorthand for 4 transition properties
  • Chrome
  • Safari
  • Firefox 4
  • Opera 10.5
  • IE 10
  •   all with vendor prefix

transitions

code {
   transition: color, font-size, background-color 0.5s ease-in 50ms;
}

animations

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);
    }
}
@-ms-keyframes falling {
    0%{
      -ms-transform: translateY(0);
    }
    100% {
      -ms-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- | -ms-

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);}
}

@-ms-keyframes falling {
  0%{ -ms-transform: 
      translateY(0) rotate(0deg) scale(0.9, 0.9);}  
  100%{ -ms-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;
    -ms-transform-origin: left -20px;
    }

-webkit- | -moz- | -ms-

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- | -ms-

But nothing is animated yet!

We've only declared the keyframes

base CSS

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

-webkit- | -moz- | -ms-

‘animation-name’

.snowflake {
   ...
   -webkit-transform-origin: left -20px;
   -webkit-animation-name: falling; 
   
   -moz-transform-origin: left -20px;
   -moz-animation-name: falling; 
   
   -ms-transform-origin: left -20px;
   -ms-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;
  
  -ms-transform-origin: left -20px;
  -ms-animation-name: falling; 
  -ms-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;
  -ms-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- | -ms-

‘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- | -ms-

‘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;
  -ms-animation-delay: 2s;
}

-webkit- | -moz- | -ms-

‘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;
  -ms-animation-direction: normal;
}

Two possible values: normal | alternate;

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

-webkit- | -moz- | -ms-

‘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;
  -ms-animation: falling 3s ease-in-out 2s infinite;
}

-webkit- | -moz- > | -ms-

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;
  -ms-animation-fill-mode: forwards;
}

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

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

‘animation-fill-mode: backwards’

.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;
  -ms-animation-fill-mode: backwards;
}

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

.snowflake {
 -webkit-animation: falling 3s ease-in-out 2s 3  backwards;
 -moz-animation: falling 3s ease-in-out 2s 3  backwards;
 -ms-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;
  -ms-animation-fill-mode: both;
}

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

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

Animation Fill Mode (again)

animation-fill-mode: none;
animation-fill-mode: forwards;
animation-fill-mode: backwards;
animation-fill-mode: both;
.box { animation: showme 5s linear 5s 1;}
@keyframes showme {
	0% {left: 200px; background-color:blue;}
	50% {background-color:green;}
	100% {left: 600px; background-color: yellow;}
}

Can you stop an animation?

‘animation-play-state’

-webkit-animation-play-state: paused | running
-moz-animation-play-state: paused | running
-ms-animation-play-state: paused | running
.snowflake:hover {
  -webkit-animation-play-state: paused;
  -moz-animation-play-state: paused;
  -ms-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

HTML5 & CSS3 for the Real World

Estelle Weyl
www.standardista.com
@estellevw

Stephanie (Sullivan) Rewis
w3conversions.com
@stefsull