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 graphique. Il est donc possible de modifier l'apparence d'un élément grâce à un ensemble fonctions 2D :
- Translation (translate),
- Mise à l'échelle (scale),
- Rotation (rotate)
- Inclinaison (skew)
- Matrice de transformation (matrix)
Syntaxe
La syntaxe est simple d'emploi.
transform: function(value);
Il est souvent nécessaire d'utiliser les préfixes vendeurs (-webkit-
, -moz-
, etc.) devant la propriété transform
pour utiliser les transformations 2D sur les versions actuelles et passées de navigateurs. Reportez-vous aux tableaux de compatibilité pour savoir ce qu'il en est des moteurs, et à partir de quelles versions.
Il est également possible d'effectuer des transformations combinées en espaçant les fonctions d'un simple caractère blanc.
transform : function1(value1) function2(value2) function3(value3);
La propriété transform-origin
Pour pouvoir appliquer des transformations, nous avons besoin de savoir quel est le point d'origine (d'ancrage) de la transformation. La propriété transform-origin
définit ce point d'origine.
La valeur initiale de cette propriété est le centre de l'élément, ce qui équivaut à la notation :
transform-origin: 50% 50%;
Il est possible de changer cette valeur en utilisant un mot-clef de position (top
, right
, bottom
, left
) suivi d'une valeur chiffrée dont l'unité peut varier (px
, %
, etc.)
div {
transform-origin: top 0 left 0;
transform: scale(1.25);
}
Il s'agit là de la syntaxe proposée par le W3C. À l'heure actuelle (2012) aucun navigateur n'implémente cette syntaxe correctement. Cependant, il suffit de supprimer les mots-clefs de position pour obtenir des résultats sur tous les navigateurs récents (toujours à condition d'utiliser les préfixes vendeurs -webkit-
,-moz-
,-ms-
,-o-
selon les versions);
Quelques exemples de positionnements :
Point d'origine en haut à gauche
transform-origin: 0 0;
Point d'origine en bas à droite
transform-origin: 100% 100%;
Point d'origine en bas et centré
transform-origin: 50% 100%:
Voici quelques exemples en démonstration de transformations avec la fonction scale
(cf. le détail plus loin) dont le point d'origine varie.
Les fonctions de la propriété transform
Une fois l'origine choisie, nous pouvons affecter des transformations à nos éléments avec la propriété transform
.
La fonction translate
Elle permet d'effectuer une translation (un déplacement) de l'élément sur les axes X et Y.
Il n'y a ici aucune notion de flux, l'élément part de son emplacement courant, quel que soit le type de positionnement que vous lui aurez attribué.
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.
Les fonctions translateX
et translateY
Ces fonctions permettent de réaliser une translation sur l'axe X (translateX
) ou Y (translateY
).
transform: translateX(value) translateY(value);
Si vous pensiez comme moi que ces fonctions permettent une modification de l'une des deux valeurs du vecteur initial, dans le cas par exemple où la transformation vient en écraser une autre, alors vous faites erreur. Essayez le code suivant pour comprendre :
div {
transform: translate(20px, 35px);
}
div:hover {
/* redéfinition de la valeur X ? */
transform: translateX(20px);
}
En définissant uniquement translateX
sur l'évènement :hover
, translateY
est implicitement redéfini avec la valeur 0
.
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, et 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, par exemple pour un agrandissement d'un facteur 1.25
:
transform: scale(1.25);
Les valeurs de x
et y
peuvent être aussi négatives. Il est possible d'effectuer ce "zoom" sur tous les éléments a priori... mais ce n'est pas parce que vous pouvez le faire qu'il faut le faire. N'oubliez pas qu'une image agrandie pourra être floue ou mal interpolée selon sa résolution initiale et celle de l'écran de destination.
Les fonctions scaleX
et scaleY
Sur le même principe que pour les fonctions dérivées de translate
, ces deux fonctions permettent de définir indépendamment les valeurs x
et y
.
Si scaleX
est uniquement renseigné, scaleY
vaudra implicitement 1 (aucun effet de scale
en y
donc), et inversement.
transform: scaleY(1.25);
Cette transformation va élargir l'élément ainsi que son contenu éventuel. Il suffit de regarder la démonstration suivante pour constater la transformation (prêtez attention au texte de l'encadré vert).
La fonction rotate
Il s'agit d'une des plus simples fonctions à comprendre. Comme son nom l'indique, elle permet d'effectuer une rotation de l'élément ciblé.
Cette rotation s'exprime en degrés (unité deg
). et 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 présenter, 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(5deg);
Attention cependant, le point d'origine de la transformation a son importance comme le présente la démonstration qui suit.
La fonction skew
Cette fonction permet d'obliquer la forme d'un élément. À ma grande surprise, la documentation du W3C ne parle que des fonctions skewX
et skewY
, et pour cause :
Important, transform: skew() is not supported anymore (spec and gecko). (But skewX an skewY are).
— Paul Rouget(@paulrouget) Avril 12, 2012
Attention : les navigateurs qui prennent en charge la fonction skew()
font du zèle. Cette fonction n'est pas prévue par le W3C, et ne sera plus supportée (prochainement par Gecko), dans un avenir proche. Pour faire les choses correctement, utilisez les fonctions skewX
et skewY
.
Les fonction skewX
et skewY
Il s'agit des fonctions dérivées de skew
. Voici deux exemples de transformation en utilisant les deux fonctions. Vous aurez compris la syntaxe de base :
transform: skewX(15deg);
...ou en changeant les valeurs de X et Y :
transform: skewX(15deg) skewY(15deg);
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 ensemble sous la forme d'une matrice. Très concrètement, les détails ne seront pas abordés ici car ils font beaucoup plus appel à des notions mathématiques complexes que beaucoup d'entre nous ont mis de côté.
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);
}
Pour comprendre comment fonctionne tout ceci, lisez l'excellent article de Useragentman.com : The CSS3 matrix() Transform for the Mathematically Challenged. Sachez qu'il existe un éditeur en ligne qui vous permet de manipuler une boîte dans le but d'obtenir des coordonnées matricielles : www.useragentman.com/matrix/
Ordre des déclarations
La propriété transform
accepte plusieurs fonctions les unes à la suite des autres, comme proposé précédemment. Cependant, l'ordre des fonctions a son importance.
En effet, les deux transformations suivantes n'ont pas le même résultat :
div {
transform: scale(2) translate(20px, 20px);
}
et différent de :
div {
transform: translate(20px, 20px) scale(2) ;
}
De la même manière :
div {
transform: translate(40px, 40px) scale(2) ;
}
propose le même résultat que :
div {
transform: scale(2) translate(20px, 20px);
}
En effet, les transformations se font dans l'ordre où elles sont déclarées, ainsi une translation de 20px
est équivalente à 40px
si un scale
de 2
la précède. Vous me suivez ?
Attention donc à l'ordre de déclaration de ces fonctions.
Du transform
sur tous les navigateurs
Internet Explorer possède son propre filtre pour effectuer des transformations. En plus du filtre propriétaire "Matrix", le comportement des transformations est différent puisque IE va tenter de transformer l'élément en restant collé aux bords haut et gauche de la boîte originelle (représentée par le cadre en pointillés dans les démo de cet article).
L'outil IE TransformsTranslator permet de corriger le tir en appliquant automatiquement des marges aux éléments transformés pour IE.
Tableau des compatibilités
Navigateurs | Versions | Détails |
---|---|---|
Internet Explorer 9+ |
Avant la version 9, il est possible d'utiliser les filtres propriétaires. A partie de la 10 : sans préfixe -ms-. |
|
Firefox 3.5+ | à partir de 16.0 : sans préfixe -moz- | |
Chrome 4+ Chrome Mobile (Android 4) |
avec préfixe -webkit- jusqu'à 23.0 (+ ?) | |
Opera 10.5+ Opera Mobile 11+ |
à partir de 12.5 : sans préfixe -o- et 11.0 sans préfixe pour Opera Mobile | |
Safari 3.1+ |
avec préfixe -webkit- | |
Android Browser 2.1+ | avec préfixe -webkit- |
Commentaires
J'entend de plus en plus parler de ces fonctions mais je me demande à chaque fois : dans quels cas doit-on utiliser la fonction translate, et dans quels cas doit-on jouer avec les margins, top, etc... ?
Il existe un plugin jQuery qui permet de faire des rotations sur les 3 axes et plus encore : http://ricostacruz.com/jquery.transit/
@palisir : tout dépend du niveau de support navigateurs attendu et des besoins. Ils sont tous combinables et ont tous des effets différents que je ne peux te détailler dans ce commentaire. Cependant ce peut être un sujet d'article intéressant ;)
@CodeUtah : merci pour cette ressource, que je trouve un peu limitée tout de même.
Il me semblait qu'il était recommandé de ne pas utiliser les transformations 2D mais plutôt les transformations 3D (même pour de la 2D) car les navigateurs utilisent le GPU pour le layout 3D ce qui accélère les perfs de rendu. De mémoire, c'est important surtout pour les sites mobile.
@palisir : Si tu utilise ie 7 tu va te servir de margin-top par contre si tu as un navigateur compatible HTML5 tu peux utiliser les deux.