Nous étudions le principe de fonctionnement des unités em à l'aide de l'exemple de la tâche «Agencement d'un préchargeur flexible»

J'aime proposer différents éléments d'interface, et une fois j'ai voulu faire un préchargeur.



Pour l'implémenter, j'avais besoin du balisage suivant:


<div class="preloader"></div> 

Selon mon idée, le préchargeur se compose de deux carrés: un grand avec une taille de 60x60px et un petit - 15x15px.


Puisqu'un grand carré est un contour pour un petit, j'ai utilisé l'élément div .prealoder pour l'implémenter. Mais pour un carré imbriqué, j'avais besoin d'un pseudo-élément auparavant.


 .preloader { width: 60px; height: 60px; border: 2px solid #fff; position: relative; } .preloader::before { content: ""; width: 15px; height: 15px; background-color: #fff; position: absolute; top: calc(50% - 7.5px); left: calc(50% - 7.5px); } 

Pour l'animation, j'ai écrit le script suivant:


 .preloader::before { animation: preloader 2.25s ease-out both infinite; } @keyframes preloader { 0%, 10%, 90%, 100% { transform: translate3d(0, 0, 0) scale(0); } 20%, 70% { transform: translate3d(0, 0, 0) scale(1); } 30% { transform: translate3d(-15px, -15px, 0) scale(1); } 40% { transform: translate3d(15px, -15px, 0) scale(1); } 50% { transform: translate3d(15px, 15px, 0) scale(1); } 60% { transform: translate3d(-15px, 15px, 0) scale(1); } } 

En plus de l'affichage principal, je voulais ajouter un préchargeur aux dimensions du contour 120x120px et du carré intérieur 30x30px.


 .preloader_l { width: 120px; height: 120px; } .preloader_l::before { width: 30px; height: 30px; top: calc(50% - 15px); left: calc(50% - 15px); animation-name: preloader-l; } @keyframes preloader-l { 0%, 10%, 90%, 100% { transform: translate3d(0, 0, 0) scale(0); } 20%, 70% { transform: translate3d(0, 0, 0) scale(1); } 30% { transform: translate3d(-30px, -30px, 0) scale(1); } 40% { transform: translate3d(30px, -30px, 0) scale(1); } 50% { transform: translate3d(30px, 30px, 0) scale(1); } 60% { transform: translate3d(-30px, 30px, 0) scale(1); } } 


Tout s'est déroulé comme prévu. Je suis allé boire du thé, et la pensée m'est venue que si j'ai besoin d'ajouter une autre taille, je devrai encore indiquer les tailles (largeur et hauteur), la position (en haut et à gauche) et le script d'animation.


Pour résoudre ce problème, j'utiliserai l'unité de mesure em. Avec lui, je serai en mesure de lier toutes les valeurs de propriété à une seule valeur de taille de police, avec laquelle je changerai les dimensions du préchargeur.


Par conséquent, le code changera comme suit:


 /*  Xem  Xpx     em   px. */ .preloader { width: Xem; height: Xem; font-size: Xpx; } .preloader::before { width: Xem; height: Xem; animation: preloader 2.25s ease-out both infinite; } @keyframes preloader { 0%, 10%, 90%, 100% { transform: translate3d(0, 0, 0) scale(0); } 20%, 70% { transform: translate3d(0, 0, 0) scale(1); } 30% { transform: translate3d(-Xem, -Xem, 0) scale(1); } 40% { transform: translate3d(Xem, -Xem, 0) scale(1); } 50% { transform: translate3d(Xem, Xem, 0) scale(1); } 60% { transform: translate3d(-Xem, Xem, 0) scale(1); } } .preloader_l { font-size: Xpx; } 


Solution


Pour résoudre le problème, la formule de calcul em est utile pour moi:


 Vem = Vpx / Fs 

Vpx est la valeur en px précédemment définie. La valeur Fs est un nombre apparié par lequel il est commode de diviser la valeur Vpx.


Vous pouvez maintenant commencer à calculer les propriétés suivantes:


 .preloader { width: 60px; height: 60px; } .preloader::before { width: 15px; height: 15px; top: calc(50% - 7.5px); left: calc(50% - 7.5px); } 

Pour ce faire, sélectionnez la valeur de taille de police. Selon mon idée, cette propriété définira les dimensions du contour, il est donc logique d'utiliser la même valeur qui est maintenant définie pour la largeur et la hauteur.


 Width(em) = 60px / 60px = 1em Height(em) = 60px / 60px = 1em 

 .preloader { width: 1em; height: 1em; font-size: 60px; } 

Ensuite, je vais calculer les valeurs de largeur, hauteur, haut et gauche de l'élément .preloader :: before. Pour ce faire, vous n'avez plus besoin de sélectionner la valeur de taille de police, car elle sera héritée de la taille de police de l'élément .preloader.


 Width(em) = 15px / 60px = 0.25em Height(em) = 15px / 60px = 0.25em Top(em) = 7.5px / 60px = 0.125em; Left(em) = 7.5px / 60px = 0.125em; 

 .preloader::before { width: 0.25em; height: 0.25em; top: calc(50% - 0.125em); left: calc(50% - 0.125em); } 

Reste à changer les valeurs dans le script d'animation.


 @keyframes preloader { 0%, 10%, 90%, 100% { transform: translate3d(0, 0, 0) scale(0); } 20%, 70% { transform: translate3d(0, 0, 0) scale(1); } 30% { transform: translate3d(-15px, -15px, 0) scale(1); } 40% { transform: translate3d(15px, -15px, 0) scale(1); } 50% { transform: translate3d(15px, 15px, 0) scale(1); } 60% { transform: translate3d(-15px, 15px, 0) scale(1); } } 

Si vous regardez les valeurs sans tenir compte du signe, vous devez traduire seulement 15px. Je l'ai déjà fait auparavant et ils correspondent à 0,25em.


 @keyframes preloader { 0%, 10%, 90%, 100% { transform: translate3d(0, 0, 0) scale(0); } 20%, 70% { transform: translate3d(0, 0, 0) scale(1); } 30% { transform: translate3d(-0.25em, -0.25em, 0) scale(1); } 40% { transform: translate3d(0.25em, -0.25em, 0) scale(1); } 50% { transform: translate3d(0.25em, 0.25em, 0) scale(1); } 60% { transform: translate3d(-0.25em, 0.25em, 0) scale(1); } } 

Vous pouvez maintenant définir la taille à 120 pixels pour l'élément .preloader_l.


 .preloader_l { font-size: 120px; } 

Il convient de noter que j'ai supprimé la règle CSS .preloader_l :: before et le script d'animation preloader-l car ils ne sont plus nécessaires.


Devoirs


Afin de consolider cette astuce, j'ai préparé une tâche. Cela nécessite de traduire les valeurs de px en em, qui sont utilisées dans le script d'animation. Toutes les valeurs de propriété précédemment calculées sont conservées.


 @keyframes preloader { 0%, 70%, 100% { transform: translate3d(0, 0, 0) scale(0); } 10%, 60% { transform: translate3d(0, 0, 0) scale(1); } 20% { transform: translate3d(9px, -21px, 0) scale(1); } 30% { transform: translate3d(3px, 21px, 0) scale(1); } 40% { transform: translate3d(-9px, -21px, 0) scale(1); } 50% { transform: translate3d(-9px, 21px, 0) scale(1); } } 

Source: https://habr.com/ru/post/fr443292/


All Articles