• Transformations CSS3

    La propriété CSS transform permet de manipuler un élément HTML sur les axes X et Y (horizontal et vertical) grâce à des fonctions diverses de transformation :
    Translation (translate),
    Mise à l'échelle (scale),
    Rotation (rotate)
    Inclinaison (skew)
    Matrice de transformation (matrix)

    Exemple :

    transform: translate(x,y);
    
    transform: translate(60px, 10px);
    
    translate

    Transform-origin

    La propriété transform-origin définit le point d'origine des transformations
    La valeur initiale de cette propriété est le centre de l'élément, ce qui équivaut à la notation :
    transform-origin: 50% 50%;

    Rotate 45deg
    Rotate -45deg
    transform-origin: 0 0;
    Rotate 120deg
    transform-origin: 100% 0;
    Rotate 120deg
    transform-origin: 100% 100%;
    Mot-clé Valeur
    left 0%
    center 50%
    right 100%
    top 0%
    bottom 100%
  • CSS3 Transform

    La fonction translate

    Elle permet d'effectuer une translation(un déplacement) de l'élément sur les axes X et Y. L'élément garde sa position dans le flux flux, il translate de son emplacement initial, comme pour une position relative.

    transform: translate(x,y);
    

    "y" est une valeur optionnelle équivalente à 0 si elle n'est pas renseignée.
    Les deux valeurs peuvent être négatives.

    Exemple translate(-10px,-50px) avec transition :

    Les fonctions translateX et translateY

    Ces fonctions permettent de réaliser indépendamment une translation sur l'axe X ou Y. transform: translateX(value) translateY(value);

    La fonction scale

    Cette fonction permet d'agir sur l'échelle(les dimensions) de l'élément.
    La valeur initiale est 1, tandis que les valeurs supérieures à 1 créent un effet d'agrandissement, les valeurs inférieures créent un effet de réduction.

    transform: scale(x,y);
    

    La valeur y est optionnelle et sera égale à la valeur de x si elle est non renseignée.
    Les valeurs de x et y peuvent être aussi négatives.

    transform: scale(2);
    

    test scale

    Les fonctions scaleX et scaleY

    Comme pour translate, ces deux fonctions permettent de définir indépendamment les valeurs x et y.
    Si scaleX est uniquement renseigné, scaleY vaudra implicitement 1, et inversement.
    Cette transformation va élargir l'élément ainsi que son contenu pour obtenir un carré :

    transform:scaleY(2);
    width:100px;
    height:50px;
    /* transition du scale: 2 au survol */
    
    test scale
    div.blocScale:hover {
    	transform:scaleX(-1);
    }
    

    La fonction rotate

    Elle permet d'effectuer une rotation de l'élément ciblé.
    Cette rotation s'exprime en degrés, elle peut être négative et supérieure de manière absolue à 360.
    Ce dernier point n'a de réel intérêt que lors d'une animation d'un état à un autre afin de lancer, par exemple, une rotation de plusieurs tours d'un élément.
    Autrement, sans animation de la rotation, la valeur 380° équivaut visuellement à une rotation de 20°.

    transform: rotate(45deg);
    /* animation du rotate 45deg - 380deg  et scale: 2 */
    
    test rotate

    Attention au point d'origine de la transformation.

    Les fonctions skewX et skewY

    Elles permettent d'obliquer la forme d'un élément. Voici deux exemples de transformation

    transform:skewX(15deg);
    
    transform:skewX(15deg) skewY(15deg);
    
    test skewX
    test skewX et skewY

    skewY / skewX

    La fonction "absolue" matrix. Cette fonction permet de réunir en une seule déclaration toutes les fonctions précédentes que nous avons vu sous la forme d'une matrice.

    Exemple d'une transformation avec beaucoup de fonctions :
    
    div {
        transform-origin: 0 0;
        transform: rotate(15deg) translateX(230px)  scale(1.5, 2.6) skew(220deg, -150deg) translateX(230px);
    }
    
    Équivaut à la matrice suivante :
    
    div {
        transform-origin: 0 0;
        transform: matrix(1.06, 1.84, 0.54, 2.8, 466px, 482px);
    }
    

    Il existe un éditeur en ligne qui vous permet de manipuler une boîte dans le but d'obtenir des coordonnées matricielles : useragentman

  • Transform 3D

    Perspective

    Pour activer l'espace 3D, un élément a besoin de perspective. Cela peut être appliqué de deux façons :
    soit avec la propriété transform, soit avec la propriété perspective.

    transform : perspective(600px); 
    
    ou en utilisant la propriété perspective :
    
    perspective : 600px; 
    

    En utilisation réelle, penser à utiliser les versions préfixées : -webkit-perspective , -moz-perspective...

    .red {
    	transform : perspective(600px) rotateY(45deg); 
    }
    .blue {
    	perspective: 600px;
    }
    .blue .box {
    	transform: rotateY( 45deg );
    }
    

    Ces deux possibilités renvoient un espace 3D, mais il y a une différence.
    La fonction perspective de transform n'est à utiliser que pour appliquer une transformation 3D sur un seul élément.
    Lorsqu'elle est utilisé sur plusieurs éléments, les éléments transformés n'utilisent pas le même point de fuite.
    Il vaut mieux dans le cas d'une transformation appliquée à plusieurs éléments, utiliser la propriété perspective sur un élément parent.
    Chacun des enfants partagera ainsi le même espace 3D.

    La valeur de perspective crée une distance entre le spectateur et l'objet.
    Plus la valeur est grande, plus la distance est grande, et l'effet visuel est moins prononcé.
    La valeur est généralement comprise entre 600 et 1000px.
    Par défaut, le point de fuite d'un espace 3D est positionné au centre.

    	perspective-origin : 50% 50%; 
    

    Vous pouvez modifier la position du point de fuite avec la propriété perspective-origin.

    Fonctions de transformation 3D

    translateZ()
    rotateX()
    rotateY()
    rotateZ()

    translateZ() positionne le long de l'axe Z, qui va d'avant en arrière dans l'espace 3D.
    Les valeurs positives positionnent l'élément plus près de l'observateur et les valeurs négatives plus loin.

    rotateX() fait tourner l'élément autour de l'axe horizontal et pas de gauche à droite.
    rotateY() fait tourner l'élément autour de l'axe vertical.

    .container {
      width: 200px;
      height: 200px;
      border: 1px solid #CCC;
      perspective: 600px;
    }				
    .panel {
      width: 100%;
      height: 100%;
      position: absolute;
      opacity: 0.7;
      color: white;
      background: red;
    }				
    #translate-z-negative .panel {
      transform: translateZ( -200px );
    }
    #translate-z-positive .panel {
      transform: translateZ( 200px );
    }				
    #rotate-x .panel {
      transform: rotateX( 45deg );
    }				
    #rotate-y .panel {
      transform: rotateY( 45deg );
    }				
    #rotate-z .panel {
      transform: rotateZ( 45deg );
    }				
    
    translateZ( -200px )
    translateZ( 200px )
    rotateX( 45deg )
    rotateY( 45deg )
    rotateZ( 45deg )
  • Transform 3D : Flip Card

    Nous allons utiliser les propriétés transform et perspective afin de retourner un élément au survol.

    <div class="container3D">
    	<div id="carte">
        	<figure class="front">1</figure>
            <figure class="back">2</figure> 
        </div>
    </div> 
    CSS :
    .container3D { 
    	width: 200px;
        height: 260px;
        position: relative;
        perspective: 800px;
    } 
    

    Le .container3D définit l'espace 3D.
    Le #carte agit comme un wrapper pour l'objet 3D.
    Deux éléments distincts pour les deux faces de la carte : .front et .back

    #carte { 
    	width: 100%;
        height: 100%;
        position: absolute;
        transform-style: preserve-3d;
        transition: transform 1s;
    }
    

    Un positionnement en absolute pour la carte qui prend les dimensions exactes du conteneur 3D.
    Une transition pour profiter de l'effet de transformation.
    La perspective ne s'applique qu'aux enfants directs, ici l'élément #carte.
    Mais le parent peut transmettre sa perspective avec transform-style: preserve-3d

    #carte figure {
    	margin: 0;
        display: block;
        position: absolute;
        width: 100%;
        height: 100%;
        backface-visibility: hidden;
    }
    #carte .front {
    	background: red;
    }
    #carte .back { 
    	background: blue;
        transform: rotateY(180deg);
    }
    .container-3D:hover #carte {
    	transform: rotateY(-180deg);
    }
    

    On positionne les faces de la carte en absolute pour les superposer et on ajoute backface-visibility: hidden,
    pour cacher la face retournée de la carte.
    Pour retourner la face .back, on ajoute une transformation avec rotateY(180deg).
    Au survol du container3D, on retourne la #carte avec rotateY(180deg).

    1
    2
    .container-3D-bis .carte {
        transform-origin: right center;
    }
    .container-3D-bis:hover .carte {
        transform: translateX(-100%) rotateY(-180deg);
    }
    
    1
    2

    Ici on déplace le point d'origine pour l'axe de rotation de la carte avec transform-origin.
    On replace au survol la carte à sa position avec le translate négatif.

    .container-3D-third {
    	transition:1s all ease-in;
    }
    .container-3D-third .carte {
    	transition: .2s all ease-out;
    }
    .container-3D-third:hover .carte {
        transform: rotateY(-180deg);
    }
    .container-3D-third:hover {
        transform: translateX(-100%);
    }
    
    1
    2

    On définit des transitions différentes pour varier la vitesse des 2 transformations.

    Le cube

    Il est possible de créer un cube en créant 6 faces.
    Inspecter le cube
    Un cube animé

  • Animations CSS3

    Une animation peut être lancée lors d'un changement de pseudo-classe (:hover, :focus, :target, :checked), lors d'un changement de "class" via Javascript, ou simplement lors du chargement de la page.
    Les animations consistent en deux composants : un style décrivant l'animation et un ensemble de keyframes qui indique les états de début et de fin du style CSS de l'animation, ainsi que des points de passage intermédiaires.

    Les avantages des animations CSS par rapport aux techniques d'animation utilisant des scripts habituelles :

    - Elles sont faciles à utiliser pour les animations simples ; leur création est possible sans aucune connaissance en JavaScript.
    - Les animations sont fluides,
    - le navigateur contrôle la séquence d'animation ce qui lui permet d'optimiser sa performance et son efficacité.

    div.spriteContainer {
    height: 120px;
    margin: 1rem;
    width: 118px;
    animation:sprite .8s steps(6) infinite alternate;
    -webkit-animation:sprite .8s steps(6) infinite alternate; /* Prefix for Safari and Chrome */
    background-image:url(11/img/sprite.jpg);
    }
    
    @keyframes sprite {
    0% {background-position:0;}
    100% {background-position:-710px;}
    }
    
    @-webkit-keyframes sprite /* Prefix for Safari and Chrome */
    {
    0% {background-position:0;}
    100% {background-position:-710px;}
    }
    
    

    Configuration de l'animation

    L'élément que vous souhaitez animer, doit avoir la propriété animation et des sous-propriétés.
    Cela vous permettra de configurer la temporisation et la durée de l'animation, ainsi que d'autres détails concernant la manière dont l'animation se déroule.
    L'apparence réelle de l'animation sera définie par les règles @keyframes.


    Mais d'abord voyons les sous-propriétés de la propriété animation :

    animation-delay:
    Configure le délai entre l'instant auquel l'élément est chargé et le début de l'animation.


    animation-direction:
    Configure si l'animation doit se jouer tour à tour en avant puis en arrière à chaque cycle de la séquence ou si elle doit revenir à son point de départ ou se répéter :
    - animation-direction: normal;
    L'animation doit se jouer vers l'avant à chaque cycle. En d'autres termes, à chaque fois que l'animation fait un cycle, elle est réinitialisée à son début et recommence de nouveau. Ceci est la valeur par défaut de cette propriété.

    Roule !

    - animation-direction: alternate;
    L'animation doit changer de sens à chaque cycle. Lorsqu'elle est jouée à l'envers, les étapes de l'animation sont appliquées à reculons. De plus, la temporisation est aussi inversée. Par exemple une animation ease-in est remplacée par une animation ease-out lorsqu'elle est jouée à l'envers.

    Roule !

    - animation-direction: reverse;
    L'animation est jouée à l'envers à chaque cycle. A chaque fois que l'animation fait un cycle, elle est réinitialisée à son début et recommence de nouveau.

    Roule !

    - animation-direction: alternate-reverse;
    Comme pour la valeur alternate, l'animation change de sens à chaque cycle. L'animation est jouée à l'envers lors du premier cycle, puis à l'endroit, ensuite à l'envers, et ainsi de suite.

    Roule !



    animation-duration:
    Configure la durée que l'animation doit utiliser pour compléter un cycle.

    animation-iteration-count:
    Configure le nombre de fois que l'animation doit se répéter : vous pouvez définir infinite pour que l'animation se répète indéfiniment.

    animation-name:
    Définit le nom de l'animation utilisée aprés @keyframes décrivant les étapes.

    animation-play-state:
    Vous permet de mettre en pause et de reprendre la lecture de la séquence animée :
    running ou paused.
    Exemple avec javascript

    animation-timing-function:
    Configure la temporisation de l'animation ; c'est-à-dire, comment l'animation se déroule entre les keyframes, en définissant les courbes d'accélération.
    Il est possible d'utiliser cette propriété au sein même des étapes de l'animation(@keyframes) afin de rédéfinir un timing différents pour chaque étape.

    ease - départ lent, rapide, puis fin lente
    linear - même vitesse du début à la fin
    ease-in - Départ lent et fin rapide
    ease-out - Départ rapide et fin lente
    ease-in-out - specifies an animation with a slow start and end
    cubic-bezier(n,n,n,n) - écrire sa propre fonction d'une courbe de bézier
    steps - Écrie le nombre d'étapes de l'animation

    animation-fill-mode:
    Cette propriété définit l'état de départ et de fin de votre animation. Voici les différentes valeurs possibles :
    forwards;
    indique au navigateur de laisser l'élément dans sont état final lors de la dernière itération. L'élément ne revient pas à son état initial
    backwards;
    indique au navigateur de placer l'élément dans son état définit au keyframe 0% au chargement de la page, même si un délai négatif est indiqué.
    both;
    appliquera les deux valeurs précédentes.
    none;
    indiquera au navigateur de styler l'élément selon son état à la première keyframe visible et de ramener l'animation à la keyframe 0% après la dernière itération.
    Ceci est le comportement par défaut.

    h1 {
        animation-duration: 3s;
        animation-name: slidein;
        animation-iteration-count: infinite;
        animation-direction: alternate;
        animation-timing-function: ease-in;
      }
    
  • Les keyframes

    Définition de la séquence

    Une fois la temporisation de l'animation définie, il est nécessaire de définir l'apparence de l'animation.
    Mise en place d'une ou plusieurs keyframe avec @keyframes.
    Chaque keyframe décrit comment l'élément animé doit être rendu à un certain instant de la séquence animée.
    Le navigateur va effectuer une transition entre ces keyframes.

    0% indique le premier instant de la séquence, tandis que 100% indique l'instant final de l'animation.
    Ces deux instants ont aussi des alias particuliers : from et to.

    Animation titres

    Voir code
    .animContainer h2 {
    position:absolute;
    }
    .animContainer h2.test1 {
        animation: slideInTop 3s infinite alternate-reverse ease-out;
        color:#333
    }
    .animContainer h2.test2 {
        animation: slideInBottom 3s infinite alternate-reverse ease-out;
        color:#222;
        z-index: 10;
    }
    .animContainer h2.test3 {
        animation: slideInLeft 3s infinite alternate-reverse ease-out;
        color:#111;
    }
    .animContainer h2.test4 {
        animation: slideInRight 3s infinite alternate-reverse ease-out;
        color:#888;
    }
    .animContainer {
    	background-color:#ccc;
    	color:#fff;
    	min-height:250px;
    	width:60%;
    	margin:2rem auto;
    	overflow:hidden;
        display: flex;
        justify-content: center;
        align-items: center;
        position: relative;
    }
    @keyframes slideInBottom {
        0% { 
          top:200px;
          opacity:0;
        }
        70% {
          top: 0;
          opacity: 1;
          color:#333;
        }
        80% {
            top: calc(50% - 3rem);
            opacity: 1;
            color:#fff;
        }
        100% {
          top: calc(50% - 6rem);
          opacity: 1;
        color:#fff;
        transform: scale(1.5);
        }
    }
    @keyframes slideInTop {
        0% { 
          bottom:200px;
          opacity:0;
        }
        70% {
          bottom: 0;
          opacity: 1;
        }
        80% {
          bottom: 50%;
          opacity: 1;
        }
        100% {
          bottom: 50%;
          opacity: 1;
        }
    }
    @keyframes slideInLeft {
        0% { 
            left:200px;
            bottom:200px;
            opacity:0;
        }
        70% {
            bottom: 0;
            left:0;
            opacity: 1;
        }
        80% {
            bottom: 50%;
            left:calc(50% - 12rem);
            opacity: 1;
        }
        100% {
            bottom: 50%;
            left:calc(50% - 12rem);
            opacity: 1;
        }
    }
    @keyframes slideInRight {
        0% { 
            right:200px;
            bottom:200px;
            opacity:0;
        }
        70% {
            bottom: 0;
            right:0;
            opacity: 1;
        }
        80% {
            bottom: 50%;
            right:calc(50% - 12rem);
            opacity: 1;
        }
        100% {
            bottom: 50%;
            right:calc(50% - 12rem);
            opacity: 1;
        }
    }
    

    SlideIn

    SlideIn

    SlideIn

    SlideIn

    Animation portrait

    Voir code
    .portr {
    background:url(img/portrait.jpg) no-repeat center center;
    width:200px;
    height:200px;
    border-radius:50%;
    border:2px #333 dotted;
    position:relative;
    
    }
    .portr::after, .portr::before {
    content:"";
    display:block;
    position:absolute;
    top:0;
    left:0;
    width:100%;
    height:100%;
    border:2px dotted #333;
    border-radius:50%;
    animation:portrait 2s infinite alternate forwards paused;
    }
    .portr::before {
    animation-delay:0.3s;
    }
    .portr:hover::after, .portr:hover::before {
    animation-play-state:running;	
    }
    @keyframes portrait {
        0% {
        transform:scale(1);
        opacity:0.2;
        }
        100% {
        transform:scale(1.2);
        opacity:1;
        }
    }
    

    Animation nuages

    Vous pouvez aussi ajouter des keyframes additionnelles qui décrivent des état intermédiaires entre le point de départ et le point d'arrivée de l'animation.

    Voir code
    .animNuage {
    	background-image:url('img/nuage.png'), url('img/nuage2.png'), url('img/montagne.jpg');
    	background-repeat:no-repeat;
    	background-position:-500px 0%, calc(100% + 600px) -400px, center top;
    	background-size:auto, auto, cover;
    	min-height:300px;
    	display:flex;
    	justify-content:center;
    	align-items:center;
    	animation: translateNuage 60s infinite ease;	
    }
    @keyframes translateNuage {
    	0% {
    		background-position:-500px 0%, calc(100% + 600px) -400px, center top;
    	}
    	50% {
    		background-position:50%  12%, 200px 100px, center top;
    	}
    	100% {
    		background-position:calc(100% + 500px) -100%, -600px 50%, center top;
    	}
    }
    
    Animation background nuage

    Défilement background à l'infini

    Voir code
    #fruits {
        background-image: url('<svg></svg>'), url('img/fruits.jpg');
        background-repeat: no-repeat;
        animation: 6s translateFruits infinite normal paused linear;
    }
    @keyframes translateFruits {
        0% {
           background-position: 0 0, 0 0;
        }
        100% {
            background-position: 0 0, 100% 0;
        }
    }
    #fruits:hover {
        animation-play-state: running;
    }   
    

    Animation slides transform

    Voir code
    .containerSlides {
        position: relative;
        min-height: 400px;
        width: 80%;
        background-color: yellowgreen;
        margin: 2rem auto;
        overflow: hidden;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    .containerSlides h2 {
        color: yellowgreen;
        position: relative;
        z-index: 10;
    }
    .containerSlides .slide {
        position: absolute;
        width: 150%;
        transform: rotate(45deg);
        background-color: #212121;
    }
    .containerSlides .slide:first-child {
        left:100%;
        height: 10%;
        animation: slideScreenLeft infinite 1s normal ease-out;
    }
    .containerSlides .slide:nth-child(2) {
        left:100%;
        height: 40%;
        animation: slideScreenLeft infinite 1s normal 0.5s ease-out;
    }
    .containerSlides .slide:nth-child(3) {
        right:100%;
        height: 20%;
        animation: slideScreenRight infinite 1s normal ease-out;
    }
    .containerSlides .slide:nth-child(4) {
        right:100%;
        height: 30%;
        animation: slideScreenRight infinite 1s normal .5s ease-out;
    }
    .containerSlides .slide:last-child {
        right:100%;
        height: 10%;
        animation: slideScreenRightScale infinite 3s normal 2s ease-out;
    }
    @keyframes slideScreenLeft {
        0% {
            left:100%;
        }
        100% {
            left:-100%;
        }
    }
    @keyframes slideScreenRight {
        0% {
            right:100%;
        }
        100% {
            right:-100%;
        }
    }
    @keyframes slideScreenRightScale {
        0% {
            right:100%;
        }
        10% {
            right:20%;
        }
        30% {
            right:0;
            height:400%;
            width: 200%;
        }
        60% {
            right:-50%;
            height:200%;
            width: 200%;
        }
        100% {
            right:-100%;
            height:0;
        }
    }
    

    LOREM IPSUM


    Animation double avec un sprite

    Voir code
    .containerSlideSprite{
       width:90%;
        overflow: hidden;
        position: relative;
        margin: 2rem auto;
        background-color: #000;
        min-height: 145px;
    }
    .spriteSlide {
        height: 120px;
        margin: 1rem;
        width: 118px;
        animation:sprite .8s steps(6) infinite alternate, slideLeftSprite 3s infinite normal;
        background-image:url(../11/img/sprite.jpg);
        position: absolute;
        bottom: 0;
    }
    @keyframes sprite {
     0% {background-position:0;}
     100% {background-position:-710px;}
    }
    @keyframes slideLeftSprite {
     0% {transform:translateX(0);}
     100% {transform:translateX(80vw);}
    }
    
  • Exos

    1- Faites une pluie de cubes
    2- Une balle qui rebondit
    3- Réaliser le tuto en vous l'appropriant Tuto animations SVG + CSS

    Liens utiles :
    Smashing : CSS3 Keyframes
    Smashing : guide animations CSS
    Exemple animations SVG + CSS
    Smashing :animations SVG + CSS
    Tuto : CSS3 transformations 3d