Eu gosto de criar vários elementos de interface e uma vez quis criar um pré-carregador.
Para implementá-lo, eu precisava da seguinte marcação:
<div class="preloader"></div>
Segundo a minha ideia, o pré-carregador consiste em dois quadrados: um grande com um tamanho de 60x60px e um pequeno - 15x15px.
Como um quadrado grande é um esboço para um pequeno, usei o elemento div .prealoder para implementá-lo. Mas para um quadrado aninhado, eu precisava de um pseudoelemento antes.
.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); }
Para animação, escrevi o seguinte script:
.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); } }
Além da tela principal, eu queria adicionar um pré-carregador com as dimensões do contorno 120x120px e do quadrado interno 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); } }
Tudo acabou como planejado. Fui tomar chá, e pensei que, se precisar adicionar outro tamanho, novamente terei de indicar os tamanhos (largura e altura), posição (superior e esquerda) e o script de animação.
Para corrigir isso, usarei a unidade de medida em. Com ele, poderei vincular todos os valores de propriedade a um único valor de tamanho de fonte, com o qual alterarei as dimensões do pré-carregador.
Como resultado, o código será alterado da seguinte maneira:
.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; }
Solução
Para resolver o problema, a fórmula de cálculo em é útil para mim:
Vem = Vpx / Fs
Vpx é o valor em px que foi definido anteriormente. O valor Fs é um número correspondente pelo qual é conveniente dividir o valor Vpx.
Agora você pode começar a calcular as seguintes propriedades:
.preloader { width: 60px; height: 60px; } .preloader::before { width: 15px; height: 15px; top: calc(50% - 7.5px); left: calc(50% - 7.5px); }
Para fazer isso, selecione o valor do tamanho da fonte. De acordo com minha ideia, essa propriedade definirá as dimensões do contorno, portanto, é lógico usar o mesmo valor agora definido para largura e altura.
Width(em) = 60px / 60px = 1em Height(em) = 60px / 60px = 1em
.preloader { width: 1em; height: 1em; font-size: 60px; }
A seguir, vou calcular os valores de largura, altura, superior e esquerda do elemento .preloader :: before. Para fazer isso, você não precisa mais selecionar o valor do tamanho da fonte, porque ele será herdado do tamanho da fonte do elemento .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); }
Resta alterar os valores no script de animação.
@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); } }
Se você observar os valores sem considerar o sinal, precisará converter apenas 15 px. Eu já fiz isso antes e eles correspondem a 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); } }
Agora você pode definir o tamanho como 120px para o elemento .preloader_l.
.preloader_l { font-size: 120px; }
Vale ressaltar que removi a regra CSS .preloader_l :: before e o script de animação preloader-l porque eles não são mais necessários.
Lição de casa
Para consolidar esse truque, preparei uma tarefa. Requer a tradução dos valores de px para em, que são usados no script de animação. Todos os valores de propriedade calculados anteriormente são preservados.
@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); } }