• 15 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 11/25/19

Modifiez le point d’ancrage d’un élément grâce à transform-origin

Log in or subscribe for free to enjoy all this course has to offer!

Transform  nous permet de créer une multitude d'effets de mouvement : nous pouvons absolument tout faire…

Sauf un mouvement de balancier…

Ou changer d’échelle du haut vers le bas… 🙃

Mais comme toujours en CSS, il y a une solution !

Découvrez le point d'ancrage

Par défaut, toutes les fonctions de  transform  partent du centre de l’élément. Donc quand on change l’échelle d’un objet, il s’agrandit vers l’extérieur :

Le changement d'échelle se fait depuis le centre

Et quand on fait pivoter un élément, il reste sur son axe :

Le pivotement se fait sur un axe

Et souvent, c’est très bien. Mais parfois, ça ne suffit pas.

La propriété  transform-origin  est là pour ça ! Elle permet de déplacer un point d’ancrage où on veut, pour faire partir nos animations de ce point.

Nous pouvons par exemple déplacer le point d’origine d'un élément à son sommet et le faire grandir :

Un exemple de la propriété transform-origin

Nous pouvons mettre le point dans un coin et faire balancer l’objet :

Exemple de la propriété transform-origin

Dans ce chapitre, allons apprendre à maîtriser la propriété  transform-origin  pour apprendre à faire tout cela. C'est parti !

Déplacez le centre

C'est à nouveau la propriété  transform  qui sera notre alliée ici.

Créons donc une barre de chargement, avec une image vide qui se remplit pendant le chargement : sa progression ne correspond pas réellement au pourcentage de chargement, mais sert de transition entre deux blocs de contenu.

<div class="container">
    <div class="btn">Charger!</div>
    <div class="progress">
        <div class="progress__bar"></div>
    </div>
</div>

Nous avons stylisé l’image avec une bordure et un peu de marge intérieure, et la barre avec une couleur de fond, qui s’affiche comme ça :

Barre de chargement pleine

Maintenant, ajoutons la propriété  transform  à notre barre, et servons-nous de la fonction scale-x qui nous est déjà familière sur 0 :

.progress {
    &__bar {
    transform: scaleX(0);
    }
}

Et voilà notre barre de progression vide !

Barre de chargement vide

Nous pouvons utiliser le pseudosélecteur  :active  pour la remplir afin d'agrandir la barre à 100 % de largeur quand on clique sur le bouton “Charger”.

.btn {
    &:active {
    & + .progress {
        & > .progress__bar {
                transform: scaleX(1);
            }
        }
    }
}

.progress {
    &__bar {
        transform: scaleX(0);
    }
}

Maintenant, quand on clique sur le bouton, la barre de chargement se remplit… immédiatement.

 Barre de chargement immédiat

Mais nous sommes dans un cours d'animation ici ! Nous voulons donc remplir la barre petit à petit. Pour cela, ajoutons donc une transition, en l’animant sur une durée de 2 secondes :

.btn {
    &:active {
        & + .progress {
            & > .progress__bar {
                transform: scaleX(1);
            }
        }
    }
}
.progress {
    &__bar {
        transform: scaleX(0);
        transition: transform 1000ms;
    }
}

Voyons voir comment notre barre se comporte maintenant :

La barre de chargement qui se remplit depuis le centre, dans les deux sens

Heuuuu, ce n'est pas exactement l'effet que nous recherchions. Quoique, on va peut-être lancer une nouvelle mode ? 😏

Les barres de chargement se remplissent normalement depuis la gauche vers la droite. Ici, la barre se remplit, mais en partant du milieu. Pour corriger notre barre, nous pouvons maintenant tester la propriété  transform-origin.

transform-origin  nous permet de déplacer le centre d'origine de notre transformation, selon les valeurs que nous lui assignons.

Pour déplacer le centre d’origine, on peut utiliser des unités comme les pixels, ou un pourcentage des dimensions d’un élément, de la même manière que pour la fonction  translate  . Dans les deux cas, l’axe X est mesuré à partir de la bordure gauche de l’élément, et l’axe Y est mesuré depuis le bord supérieur.

Le point d’origine par défaut, au centre de l’élément, peut donc être écrit de cette manière :  transform-origin: 50% 50% ;

Ici, nous voulons placer le point d’origine de notre barre de chargement sur sa bordure gauche, pour qu’elle progresse vers la droite. Nous devons donc mettre l'origine de x à 0 % :

.btn {
    &:active {
        & + .progress {
            & > .progress__bar {
                transform: scaleX(1);
            }
        }
    }
}
.progress {
    &__bar {
        transform-origin: 0% 50%;
        transform: scaleX(0);
        transition: transform 1000ms; 
    }
}

On devrait voir la barre être vide au départ. Puis au clic sur le bouton, elle devrait s’agrandir vers la droite jusqu’à remplir le cadre :

Une animation CSS d'une barre de chargement complète

Parfait ! Mettons notre touche finale en ajoutant notre propre fonction de timing   cubic-bezier(). Nous voulons que la barre commence avec un ease-in peu prononcé, mais que son ease-out soit bien perceptible à la fin. Le profil de la courbe ressemblerait à quelque chose comme ça :

La courbe de notre animation

Les valeurs de notre courbe d’accélération sont   cubic-bezier(.32, 0, .07, 1). Rentrons-les dans notre fonction de timing :

.btn {
    &:active {
        & + .progress {
            & > .progress__bar {
                transform: scaleX(1);
            }
        }
    }
}
.progress {
    &__bar {
        transform-origin: 0% 50%;
        transform: scaleX(0);
        transition: transform 1000ms cubic-bezier(.32,0,.07,1);
    }
}

La barre de chargement fonctionne

Et c'est encore une réussite pour vous ! Bravo !💪

Utilisez la bonne valeur

Les valeurs de  transform-origin  ne se limitent pas à des longueurs ou des pourcentages.

On peut aussi utiliser des mots clés CSS pour définir les points d’ancrage, comme  left  pour le mettre sur le bord gauche, ou  right  pour le mettre à droite :

.box--left-origin {
// positionne l'origine du côté gauche
    transform-origin: left 50%;
}
.box--right-origin {
// positionne l'origine du côté droit
    transform-origin: right 50%;
}

Animation de Transform-origin left et right

On peut aussi utiliser  top  et  bottom  :

.box--top-origin {
// positionne l'origine au sommet de l'élément
    transform-origin: 50% top;
}
.box--bottom-origin {
// positionne l'origine en bas de l'élément
    transform-origin: 50% bottom;
}
Animation de transform-origin top et bottom

Concrètement, les mots clés  left  et  top  correspondent à 0 %, tandis que  right  et   bottom correspondent à 100 %. Mais l'utilisation de ces mots clés permet d'être explicite dans la manière d'écrire notre code.

Le dernier mot clé est  center. Il peut être assigné à l’axe X ou Y, et correspond à une valeur de 50 :

.box--left-origin {
// positionne l'origine au centre de l'élément
    transform-origin: center center;
}
Animation de transform-origin center

Jusqu’à maintenant, nous avons toujours assigné deux valeurs à  transform-origin, une pour X et l’autre pour Y. Mais une seule valeur peut aussi suffire. Si cette valeur est un nombre, elle s’appliquera à l’axe X et laissera Y à la valeur par défaut de 50 %.

Dans le cas de notre barre de progression, c'est surtout la valeur de X qui nous intéresse. La valeur de 50 % pour l’axe Y est donc superflue. Retirons cette valeur, ce qui simplifie le code et montre plus explicitement que nous modifions l'axe X quand nous relirons le code dans le futur :

.btn {
    &:active {
        & + .progress {
            & > .progress__bar {
                transform: scaleX(1);
            }
        }
    }
}
.progress {
    &__bar {
        transform-origin: 0%;
        transform: scaleX(0);
    transition: transform 1000ms cubic-bezier(.32,0,.07,1);
    }
}

Notre code est plus propre et fonctionne toujours de la même manière dans le navigateur :

La barre de chargement fonctionne de la même façon

Et le navigateur n'a pas fini de nous étonner :  si on assigne un simple mot clé à  transform-origin, le navigateur va comprendre de lui-même à quel axe l’appliquer, et laisser l’autre axe sur sa valeur par défaut.

Il est plus explicite d’utiliser le mot clé  left  plutôt que de mettre un  transform-origin  à 0 %, car cela nous indique instantanément que nous avons déplacé le  transform-origin  sur le côté gauche. Revenons une dernière fois à notre barre de chargement et remplaçons la valeur numérique de  transform-origin  par le mot clé  left, pour rendre notre code aussi clair et concis que possible :

.btn {
    &:active {
        & + .progress {
            & > .progress__bar {
                transform: scaleX(1);
            }
        }
    }
}
.progress {
    &__bar {
        transform-origin: left;
        transform: scaleX(0);
        transition: transform 1000ms cubic-bezier(.32,0,.07,1);
    }
}

Passez dans la troisième dimension

Nous avons vu que la propriété  transform  permet de manipuler des éléments en deux dimensions... mais aussi en trois. Et  transform-origin fonctionne parfaitement avec des valeurs X et Y en 2D. Mais comment faire pour changer le point d’origine de transformations 3D ?

Vous l’avez peut-être deviné 😎 : on ajoute une troisième valeur à la liste ! On peut utiliser les valeurs X et Y comme en 2D, avec des pourcentages ou des mots-clés, mais l’axe Z DOIT obligatoirement être défini avec des unités réelles comme les pixels, les centimètres, etc.

.btn {
    perspective: 500px;
    &:active {
        & > .btn__flip {
            transform: rotateX(-90deg);
    }
}
&__flip {
    transform-style: preserve-3d;
        transform-origin: center bottom 7.5vw;
        transition: transform 500ms cubic-bezier(.7, 0, .23, 1);
        &--off {
            transform: rotateX(0deg) translateZ(7.5vw);
        }
        &--on {
            transform: rotateX(90deg) translateZ(7.5vw);
        }
    }
}

Alors, tentons de combiner les fonctions de transformation 3D avec des valeurs transform-origin 3D pour créer des objets à trois dimensions, comme des boutons à plusieurs faces !

Un bouton en 3D

Vous trouverez le code source de notre bouton sur ce CodePen.

Avez-vous essayer de changer la vitesse de l'animation ou la couleur des faces du bouton ?

Et chose promise, chose due. Je vous parlais dans la vidéo d'introduction d'un fameux sabre Jedi : voici ce que donne une animation CSS de sabre Jedi avec la propriété transform-origin. Le code source est ici

                                          Animation d'un sabre Jedi qui s'allume

Encore une fois, n'hésitez pas à manipuler les valeurs indiquées.

En résumé :

  • transform-origin  permet de repositionner le point d’ancrage, qui se trouve par défaut au centre de l’élément ;

  • on peut régler ce point d’origine en utilisant des unités comme px, rem, vh, etc. ;

  • il est aussi possible d'utiliser des pourcentages pour X et Y ;

  • ou encore, on peut utiliser des mots clés :  left  et   right  pour l’axe X,  top  et  bottom  pour l’axe Y, et  center  pour les deux ;

  • il est possible de ne pas indiquer la valeur de l'axe Y ou, quand on utilise des mots clés, de mettre uniquement une valeur : le navigateur comprend de lui-même à quel axe la valeur s'applique ;

  • quand on change le point d’origine en 3D, la valeur de Z doit être exprimée en unités (et non en pourcentages) ! 

Créer des animations, c'est bien, mais pouvoir analyser leurs performances, c'est mieux. C'est ce que vous allez découvrir dans le chapitre suivant.

Example of certificate of achievement
Example of certificate of achievement