• 6 heures
  • Moyenne

Mis à jour le 20/11/2019

Les transformations 2D

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Nous entrons maintenant dans l'une des nouveautés les plus excitantes apportées par CSS3 : l'univers des transformations et des animations.

Nous allons découvrir ensemble dans cet ordre :

  1. Les transformations 2D : comment étirer, déplacer, faire tourner un objet de la page. Ce sera le sujet de ce chapitre.

  2. Les transitions et animations : comment animer un objet lors d'une transformation. Par exemple, comment faire tourner progressivement un objet, comment le faire apparaître petit à petit...

  3. Les transformations 3D : nous passerons dans la troisième dimension pour travailler avec de la perspective et donner l'impression à vos visiteurs que certains objets de votre site sont en 3D ! Et comme vous saurez faire des animations, vous pourrez même vous amuser à créer des animations en 3D ! :D 

Commençons déjà dans ce chapitre par les transformations 2D. Il existe plusieurs types de transformations :

  • L'agrandissement et le rétrécissement ;

  • Le déplacement (translation) qui va vous rappeler un peu la propriétéposition: relative;  de CSS ;

  • La rotation ;

  • La transformation oblique ;

  • ... et le super-pouvoir de la transformation à base de matrice, pour les plus matheux d'entre vous. ;)
    Il vous permettra de faire subir à peu près tout ce que vous voulez à vos objets.

En jouant un peu sur toutes ces fonctionnalités de transformation, on peut faire ce qu'on veut sur tous les objets de la page : textes, images, menus... Par exemple ici, voici une image que l'on a étirée et retournée :

Cette image a subi de multiples transformations !
Cette image a subi de multiples transformations en CSS !

Parés à devenir des pros du bistouri ? C'est parti ! :pirate:

Premier exemple simple : la rotation

Vous pouvez aussi bien faire des transformations sur du texte que sur des photos. En fait, n'importe quel élément HTML de la page peut être transformé.

Commençons par créer une simple page HTML avec une photo :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Transformations</title>
        <link rel="stylesheet" href="style.css" />
    </head>

    <body>
        <div><img src="nature.jpg" alt="" id="photo" /></div>
    </body>
</html>

Appliquons en CSS une transformation sur l'image #photo :

#photo
{
    transform: rotate(10deg);
}

Toutes les transformations s'effectueront avec la propriététransform. Celle-ci est bien reconnue par tous les navigateurs, à l'exception notable de Safari (pour Mac et iOS) qui a besoin du préfixe-webkit . Donc pour bien faire, il faudrait doubler la propriété :

#photo
{
    -webkit-transform: rotate(10deg); /* Safari */
    transform: rotate(10deg); /* Tous les autres navigateurs */
}

Pour rester simple et lisible, je ne garderai que la propriété principaletransform  dans les exemples suivants de ce chapitre. Un jour, certainement, Safari gèrera les transformations sans ce préfixe. Ce jour-là, on ne verra plus de petit symbole "-" sur le site caniuse.com pour Safari, ce qui signifiera que le navigateur gèrera enfin la propriété comme tous les autres.

Bon, où en étions-nous déjà ? Ah oui, nous venions de faire notre première transformation. Nous avons appliqué la fonctionrotate()  d'un angle de 10 degrés sur la photo. Voyons le résultat :

Cette image vient de subir une rotation !
Cette image vient de subir une rotation !

L'origine de la transformation

Toute transformation doit partir d'un point précis. Par défaut, la transformation se fait à partir du centre de l'élément. Par exemple, imaginez qu'on a placé une punaise au centre de la photo et qu'on la fait tourner autour de cette punaise :

La transformation a lieu par défaut à partir du centre
La transformation a lieu par défaut à partir du centre

On peut modifier l'origine de la transformation (l'emplacement de la punaise dans notre cas). Par exemple, on peut partir du coin en haut à gauche :

La transformation part du coin en haut à gauche
La transformation part du coin en haut à gauche

Pour modifier l'origine de la transformation, on a recours àtransform-origin. Malheureusement cette propriété est moins bien supportée par les navigateurs et il faudra ajouter tout un tas de préfixes :

#photo
{
    -webkit-transform-origin: 0 0;/* Safari, Chrome */
    -ms-transform-origin: 0 0; /* IE */
    -moz-transform-origin: 0 0; /* Firefox */
    -o-transform-origin: 0 0; /* Opera */
    transform-origin: 0 0; /* La transformation partira du coin en haut à gauche */
    
    transform: rotate(10deg);
}

Cette propriété prend deux valeurs en pixels ou pourcentages. Avec "0 0", on indique que la transformation part du point en haut à gauche de l'élément.

La valeur par défaut est "50% 50%", ce qui correspond au centre de l'élément :

#photo
{
    transform-origin: 50% 50%; /* Centre */
}

Vous pouvez donc faire une transformation à partir d'en bas à droite, comme ceci :

#photo
{
    transform-origin: 100% 100%; /* En bas à droite */
}

Vous pouvez aussi indiquer des valeurs en pixels et indiquer un côté. Par exemple  :

#photo
{
    transform-origin: top 0 left 30px;
}

... démarrera la transformation d'un point situé en haut de l'élément et à 30px du bord gauche.

L'agrandissement (et le rétrécissement)

Pour agrandir un élément (ou bien le rétrécir), vous pouvez utiliser la fonctionscale() , toujours avec la propriététransform  :

#photo
{
    transform: scale(1.3);
}

Une valeur de 1 signifie "taille normale". Une valeur de 2 signifie "2 fois plus grand". Donc 1.3 signifie "1,3 fois plus grand". :)

L'image a été agrandie
L'image a été agrandie (et sort ici du cadre d'origine)

On peut réduire la taille de l'objet avec une valeur inférieure à 1 :

#photo
{
    transform: scale(0.6);
}
L'image a été réduite par rapport à sa taille initiale
L'image a été réduite par rapport à sa taille initiale

A noter qu'il est possible d'indiquer deux valeurs, en X et en Y.  Par exemple :

#photo
{
    transform: scale(1.3, 0.6);
}

Agrandira de 1,3 fois sur l'axe des X et réduira à 0,6 sur l'axe des Y. Ce qui nous donne une photo bien martyrisée :

Modification de la taille sur différents axes
Modification de la taille sur différents axes

Les fonctionsscaleX()  etscaleY()  existent aussi et permettent d'appliquer la modification uniquement sur un des axes :

#photo
{
    transform: scaleX(1.3);
}

La translation (déplacement)

Avec la translation, vous pouvez déplacer un objet comme bon vous semble sur la page.

#photo
{
    transform: translate(30px, 90px);
}

... déplacera l'objet de 30px sur l'axe des X (de gauche à droite) et de 90px sur l'axe des Y (de haut en bas).

Résultat :

Une translation
Une translation

Cette fonction suit en fait le même principe qu'unposition: relative;  d'un élément que vous connaissez probablement maintenant.

Notez qu'il existe aussi les fonctionstranslateX()  ettranslateY()  pour déplacer l'élément uniquement sur un axe :

#photo
{
    transform: translateX(30px);
}

La transformation oblique

Ce type de transformation "étire" un des côtés du bloc pour en faire un losange. On utilise pour cela les fonctionsskewX()  etskewY()  (la fonctionskew()  existait mais a été retirée).

Regardons ce que ça donne :

La transformation oblique
La transformation oblique

Pour y parvenir, le code est très simple :

#photo
{
    transform: skewX(20deg);
}

La transformation s'exprime en degrés et vous pouvez utiliser des valeurs négatives au besoin pour changer de sens.

Combinez les transformations !

Il faut savoir qu'on peut sans problème combiner plusieurs transformations d'affilée. Il suffit d'écrire les fonctions les unes à la suite des autres sur la même ligne, séparées à chaque fois par un espace.

#photo
{
    transform: scale(0.7) rotate(15deg) skewY(10deg);
}

Ce qui nous donne l'objet torturé suivant :

Rétrécissement, rotation, obliquatiooon !!!
Rétrécissement, rotation, obliquatiooon !!!

La matrice : la mère de toutes les transformations

Toutes les transformations que nous avons vues obéissent aux mêmes lois mathématiques. Derrière chaque transformation se cache... une matrice.

Comment ça une matrice ? o_O
Tu veux dire qu'on est DANS la matrice ?! On doit s'inquiéter ?

Ceux qui ont fait des maths à un niveau un peu avancé savent de quoi je parle. Pour les autres, pas d'inquiétude. Une matrice est simplement un groupe de nombres :

$\[\left( \begin{array}{ccc} 10 & -2 & 14 \\ 20 & 1 & 0 \\ 1 & 1 & 0 \end{array} \right)\]$

Ces nombres sont organisés en tableau. Ici, c'est une matrixe 3x3, mais on peut faire des matrices plus grandes (ou plus petites).

Et donc, par toute une série de calculs mathématiques (qu'il serait vraiment trop long de détailler ici), on peut appliquer n'importe quelle transformation grâce à une matrice.

Par défaut, chaque objet est à sa position normale, définie par une matrice qui contient uniquement des 0, avec des 1 en diagonale, comme ceci :

$\[\left( \begin{array}{ccc} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{array} \right)\]$

Si vous voulez agrandir l'objet sur l'axe des X, il suffit de modifier le premier nombre en haut à gauche (oui, celui-là et pas les autres !) :

$\[\left( \begin{array}{ccc} 1.4 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{array} \right)\]$

... ici l'objet sera agrandi d'un facteur de 1.4 sur l'axe des X.

Si vous voulez l'agrandir sur l'axe des Y plutôt, il faut cette fois changer le nombre au centre de la matrice. Et si vous voulez le déplacer sur l'axe des X, il faut modifier le nombre en haut à droite :

$\[\left( \begin{array}{ccc} 1 & 0 & 20 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{array} \right)\]$

Voici comment je ferais en CSS une translation en X de 20px (correspondant à la matrice précédente) :

#photo
{
    transform: matrix(1, 0, 0, 1, 20, 0);
}

Pourquoi il n'y a que 6 nombres alors que la matrice comporte 9 nombres ?

Parce qu'on fait une transformation 2D, et en 2D nous n'avons pas besoin de toucher aux 3 nombres dans la ligne en bas de la matrice.

Pour faire le lien entre les mathématiques et le CSS, il faut savoir que la matrice suivante :

$\[\left( \begin{array}{ccc} 1 & 3 & 5 \\ 2 & 4 & 6 \\ 0 & 0 & 1 \end{array} \right)\]$

... s'écrira comme ceci en CSS :

#photo
{
    transform: matrix(1, 2, 3, 4, 5, 6);
}

Mais tout ça, c'est magique en fait ?

Non, c'est comme ça que les ordinateurs font pour calculer les transformations des objets. C'est très pratique pour eux. Et dans le monde de la 3D c'est d'ailleurs pareil, on se base sur des matrices tout le temps.

Bon, mais ça sert à quoi ? Autant utiliser les fonctionsscale(),rotate() et cie non, c'est plus simple !

Je suis complètement d'accord avec vous, c'est plus simple. Mais avec la matrice, vous pouvez combiner d'un coup toutes les fonctions si vous le souhaitez. En fait, vous n'utiliserez probablement la matrice que si vous avez besoin d'une transformation très précise et que vous êtes déjà à l'aise avec ce concept mathématique.

Exemple de certificat de réussite
Exemple de certificat de réussite