Wir untersuchen das Funktionsprinzip von em-Einheiten am Beispiel der Aufgabe „Aufbau eines flexiblen Vorladers“.

Ich habe mir gerne verschiedene Interface-Elemente ausgedacht und wollte einmal einen Preloader machen.



Um es zu implementieren, brauchte ich das folgende Markup:


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

Nach meiner Idee besteht der Preloader aus zwei Quadraten: einem großen mit einer Größe von 60 x 60 Pixel und einem kleinen mit einer Größe von 15 x 15 Pixel.


Da ein großes Quadrat ein Umriss für ein kleines ist, habe ich das div .prealoder-Element verwendet, um es zu implementieren. Aber für ein verschachteltes Quadrat brauchte ich vorher ein Pseudoelement.


 .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); } 

Für die Animation habe ich folgendes Skript geschrieben:


 .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); } } 

Zusätzlich zum Hauptdisplay wollte ich einen Preloader mit den Abmessungen der Kontur 120x120px und des inneren Quadrats 30x30px hinzufügen.


 .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); } } 


Alles verlief wie geplant. Ich ging Tee trinken und kam mir der Gedanke, dass ich, wenn ich eine andere Größe hinzufügen muss, wieder die Größen (Breite und Höhe), die Position (oben und links) und das Animationsskript angeben muss.


Um dies zu beheben, werde ich die Maßeinheit em verwenden. Damit kann ich alle Eigenschaftswerte an einen einzigen Wert für die Schriftgröße binden, mit dem ich die Größe des Preloaders ändern kann.


Infolgedessen ändert sich der Code wie folgt:


 /*  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; } 


Lösung


Um das Problem zu lösen, ist die Berechnungsformel em nützlich für mich:


 Vem = Vpx / Fs 

Vpx ist der zuvor festgelegte Wert in px. Der Fs-Wert ist eine übereinstimmende Zahl, durch die der Vpx-Wert bequem geteilt werden kann.


Jetzt können Sie die folgenden Eigenschaften berechnen:


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

Wählen Sie dazu den Wert für die Schriftgröße. Nach meiner Idee werden mit dieser Eigenschaft die Abmessungen des Umrisses festgelegt. Daher ist es logisch, denselben Wert zu verwenden, der jetzt für Breite und Höhe festgelegt ist.


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

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

Als nächstes berechne ich die Werte für Breite, Höhe, obere und linke Seite des .preloader :: before-Elements. Dazu müssen Sie den Wert für die Schriftgröße nicht mehr auswählen, da er von der Schriftgröße des .preloader-Elements geerbt wird.


 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); } 

Die Werte im Animationsskript müssen noch geändert werden.


 @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); } } 

Wenn Sie die Werte ohne Rücksicht auf das Vorzeichen betrachten, müssen Sie nur 15px übersetzen. Ich habe das schon einmal gemacht und sie entsprechen 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); } } 

Jetzt können Sie die Größe für das Element .preloader_l auf 120px festlegen.


 .preloader_l { font-size: 120px; } 

Es ist erwähnenswert, dass ich die CSS-Regel .preloader_l :: before und das Animationsskript pretoader-l entfernt habe, da sie nicht mehr benötigt werden.


Hausaufgaben


Um diesen Trick zu festigen, habe ich eine Aufgabe vorbereitet. Dazu müssen die Werte von px nach em übersetzt werden, die im Animationsskript verwendet werden. Alle zuvor berechneten Eigenschaftswerte bleiben erhalten.


 @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/de443292/


All Articles