Magníficos SVGs com propriedades personalizadas CSS – Smashing Magazine

PUBLICIDADE

Magníficos SVGs com propriedades personalizadas CSS - Smashing Magazine

Expliquei recentemente como uso , e consultas de mídia CSS para desenvolver o que chamo de SVGs adaptativos. Os símbolos nos permitem definir um elemento uma vez e depois usar repeti-lo repetidamente, tornando as animações SVG mais fáceis de manter, mais eficientes e leves.

Desde que escrevi essa explicação, projetei e implementei novos gráficos animados do Magnificent 7 em meu site. Eles jogam com o tema pioneiro do web design, apresentando sete magníficos personagens do Velho Oeste.

Veja este SVG animado no meu site. (Visualização grande)

e deixe-me definir um design de personagem e reutilizá-lo em vários SVGs e páginas. Primeiro, criei meus personagens e coloquei cada um em um dentro de uma biblioteca oculta SVG:

Em seguida, referenciei esses símbolos em dois outros SVGs, um para telas grandes e outro para telas pequenas:



 
 




 
 

Elegante. Mas então veio o irritante. Eu poderia reutilizar os personagens, mas não poderia animá-los ou estilizá-los. Adicionei regras CSS visando elementos dentro dos símbolos referenciados por um mas nada aconteceu. As cores permaneceram as mesmas e as coisas que deveriam se mover permaneceram estáticas. Parecia que eu havia encontrado uma barreira invisível, e foi o que aconteceu.

Compreendendo a barreira Shadow DOM

Quando você faz referência ao conteúdo de um symbol com useum navegador cria uma cópia dele no Shadow DOM. Cada instância se torna sua própria cópia encapsulada do referenciado o que significa que o CSS externo não pode romper a barreira para estilizar qualquer elemento diretamente. Por exemplo, em circunstâncias normais, este tapping valor aciona uma animação CSS:


.tapping {
  animation: tapping 1s ease-in-out infinite;
}

Mas quando a mesma animação é aplicada a um instância desse mesmo pé, nada acontece:


 



.tapping {
  animation: tapping 1s ease-in-out infinite;
}

Isso porque o dentro do elemento está em uma árvore de sombra protegida, e o CSS Cascade para no final limite. Esse comportamento pode ser frustrante, mas é intencional, pois garante que o conteúdo do símbolo reutilizado permaneça consistente e previsível.

Ao aprender como desenvolver SVGs adaptativos, encontrei todos os tipos de tentativas de contornar esse comportamento, mas a maioria delas sacrificou a capacidade de reutilização que torna o SVG tão elegante. Eu não queria duplicar meus personagens apenas para fazê-los piscar em momentos diferentes. eu queria um único com instâncias que têm seus próprios tempos e expressões.

Vários elementos animados em um único símbolo SVG. (Visualização grande)

Propriedades personalizadas CSS para o resgate

Enquanto trabalhava em minhas animações pioneiras, aprendi que valores CSS regulares não podem cruzar os limites do Shadow DOM, mas as propriedades personalizadas CSS podem. E mesmo que você não possa estilizar elementos diretamente dentro de um você poderá transmitir valores de propriedades customizadas para eles. Assim, quando você insere propriedades personalizadas em um estilo embutido, um navegador olha para a cascata e esses estilos ficam disponíveis para elementos dentro do estilo. sendo referenciado.

Eu adicionei rotate para um estilo embutido aplicado ao contente:


  

Em seguida, definimos a animação de bater o pé e aplicamos ao elemento:

@keyframes tapping {
  0%, 60%, 100% { --foot-rotate: 0deg; }
  20% { --foot-rotate: -5deg; }
  40% { --foot-rotate: 2deg; }
}

use[data-outlaw="1"] {
  --foot-rotate: 0deg;
  animation: tapping 1s ease-in-out infinite;
}

Passando vários valores para um símbolo

Depois de configurar um símbolo para usar propriedades personalizadas CSS, posso passar quantos valores quiser para qualquer exemplo. Por exemplo, eu poderia definir variáveis ​​para fill, opacityou transform. O que é elegante é que cada instância pode então ter seu próprio conjunto de valores.


  

use[data-outlaw="1"] {
  --eyelids-colour: #f7bea1; 
  --eyelids-opacity: 1;
}

use[data-outlaw="2"] {
  --eyelids-colour: #ba7e5e; 
  --eyelids-opacity: 0;
}

O suporte para passar propriedades personalizadas de CSS como essa é sólido e todos os navegadores contemporâneos lidam com esse comportamento corretamente. Deixe-me mostrar algumas maneiras pelas quais tenho usado essa técnica, começando com um sistema de ícones multicoloridos.

Um sistema de ícones multicoloridos

Quando preciso manter um conjunto de ícones, posso definir um ícone dentro de um e, em seguida, use propriedades personalizadas para aplicar cores e efeitos. Em vez de precisar duplicar SVGs para cada tema, cada use pode carregar seus próprios valores.

Propriedades personalizadas para cores de preenchimento em vários ícones Bluesky. (Visualização grande)

Por exemplo, apliquei um --icon-fill propriedade personalizada para o padrão fill cor do neste ícone Bluesky:


  

Então, sempre que eu precisar variar a aparência desse ícone – por exemplo, em um

e

— Posso passar novo fill valores de cores para cada instância:

Esses ícones têm o mesmo formato, mas parecem diferentes graças aos seus estilos embutidos.

Visualizações de dados com propriedades personalizadas CSS

Podemos usar e de maneiras muito mais práticas. Eles também são úteis para criar visualizações de dados leves, então imagine um infográfico sobre três xerifes famosos do Velho Oeste: Wyatt Earp, Pat Garrett e Bat Masterson.

Visualizações de dados com propriedades personalizadas CSS. (Visualização grande)

O perfil de cada xerife usa o mesmo conjunto de três símbolos SVG: um para uma barra que representa a duração da carreira de um xerife, outro para representar o número de prisões feitas e mais um para o número de mortes. Passando valores de propriedades personalizadas para cada um A instância pode variar o comprimento das barras, a escala das prisões e a cor das eliminações sem duplicar SVGs. Primeiro criei símbolos para esses itens:


  
    
  
  
  
    
  
  
  
    
  

Cada símbolo aceita um ou mais valores:

  • --career-length ajusta o width da barra de carreira.
  • --career-colour muda o fill cor dessa barra.
  • --arrest-scale controla o tamanho do crachá de prisão.
  • --kill-colour define o fill cor do ícone de matar.

Posso usá-los para desenvolver um perfil de cada xerife usando elementos com diferentes estilos embutidos, começando com Wyatt Earp.

Cada compartilha os mesmos elementos de símbolo, mas as variáveis ​​embutidas mudam suas cores e tamanhos. Posso até animar esses valores para destacar suas diferenças:

@keyframes pulse {
  0%, 100% { --arrest-scale: 1; }
  50% { --arrest-scale: 1.2; }
}

use[href="#arrests-badge"]:hover {
  animation: pulse 1s ease-in-out infinite;
}

As propriedades personalizadas CSS não são úteis apenas para estilização; eles também podem canalizar dados entre HTML e a geometria interna do SVG, vinculando atributos visuais como cor, comprimento e escala a semânticas como números de prisões, duração da carreira e mortes.

Animações ambientais

Comecei a aprender a animar elementos dentro de símbolos enquanto criava os gráficos animados para o Magnificent 7 do meu site. Para reduzir a complexidade e tornar meu código mais leve e mais fácil de manter, precisei definir cada caractere uma vez e reutilizá-lo em SVGs:

Os 7 caracteres magníficos do meu site. (Visualização grande)

Mas eu não queria que esses personagens permanecessem estáticos; Eu precisava de movimentos sutis que lhes dessem vida. Eu queria que seus olhos piscassem, seus pés batessem e seus bigodes se mexessem. Então, para animar esses detalhes, passo os dados da animação para os elementos dentro desses símbolos usando CSS Custom Properties, começando pelo piscar.

Implementei o efeito de piscar colocando um grupo SVG sobre os olhos dos bandidos e depois mudando seu opacity.

Efeito piscante ao animar a opacidade das pálpebras. (Visualização grande)

Para tornar isso possível, adicionei um estilo inline com uma propriedade personalizada CSS ao grupo:

Então, defini a animação piscante alterando --eyelids-opacity:

@keyframes blink {
  0%, 92% { --eyelids-opacity: 0; }
  93%, 94% { --eyelids-opacity: 1; }
  95%, 97% { --eyelids-opacity: 0.1; }
  98%, 100% { --eyelids-opacity: 0; }
}

…e apliquei a todos os personagens:

use[data-outlaw] {
  --blink-duration: 4s;
  --eyelids-opacity: 1;
  animation: blink var(--blink-duration) infinite var(--blink-delay);
}

…para que cada personagem não piscasse ao mesmo tempo, defini um valor diferente --blink-delay antes que todos comecem a piscar, passando outra propriedade personalizada:

use[data-outlaw="1"] { --blink-delay: 1s; }
use[data-outlaw="2"] { --blink-delay: 2s; }

use[data-outlaw="7"] { --blink-delay: 3s; }
Efeito de batida de pé ao animar a rotação do pé. (Visualização grande)

Alguns dos personagens batem os pés, então adicionei um estilo embutido com uma propriedade personalizada CSS a esses grupos também:


  

Definindo a animação do toque de pé:

@keyframes tapping {
  0%, 60%, 100% { --foot-rotate: 0deg; }
  20% { --foot-rotate: -5deg; }
  40% { --foot-rotate: 2deg; }
}

E adicionando essas propriedades personalizadas extras à declaração dos personagens:

use[data-outlaw] {
  --blink-duration: 4s;
  --eyelids-opacity: 1;
  --foot-rotate: 0deg;
  animation: 
    blink var(--blink-duration) infinite var(--blink-delay),
    tapping 1s ease-in-out infinite;
}
Efeito de balanço ao animar a tradução dos bigodes. (Visualização grande)

…antes de finalmente fazer os bigodes do personagem balançarem por meio de um estilo inline com uma propriedade personalizada CSS que descreve como seu bigode se transforma:


  
    
  

Definindo a animação jiggle:

@keyframes jiggle {
  0%, 100% { --jiggle-x: 0px; }
  20% { --jiggle-x: -3px; }
  40% { --jiggle-x: 2px; }
  60% { --jiggle-x: -1px; }
  80% { --jiggle-x: 4px; }
}

E adicionando essas propriedades à declaração dos personagens:

use[data-outlaw] {
  --blink-duration: 4s;
  --eyelids-opacity: 1;
  --foot-rotate: 0deg;
  --jiggle-x: 0px;
  animation: 
    blink var(--blink-duration) infinite var(--blink-delay),
    jiggle 1s ease-in-out infinite,
    tapping 1s ease-in-out infinite;
}

Com essas partes móveis, os personagens ganham vida, mas minha marcação permanece notavelmente enxuta. Ao combinar diversas animações em uma única declaração, posso coreografar seus movimentos sem adicionar mais elementos ao meu SVG. Todo bandido compartilha a mesma base e sua individualidade vem inteiramente das propriedades personalizadas do CSS.

Armadilhas e soluções

Mesmo que esta técnica possa parecer à prova de balas, existem algumas armadilhas que é melhor evitar:

  • Propriedades personalizadas CSS só funcionam se forem referenciadas com um var() dentro de um . Esqueça isso e você se perguntará por que nada é atualizado. Além disso, propriedades que não são herdadas naturalmente, como fill ou transformpreciso usar var() em seu valor para se beneficiar da cascata.
  • É sempre melhor incluir um valor substituto junto com uma propriedade personalizadacomo opacity: var(--eyelids-opacity, 1); para garantir que os elementos SVG sejam renderizados corretamente, mesmo sem a aplicação de valores de propriedades personalizadas.
  • Estilos embutidos definidos por meio do style atributo tem precedênciaportanto, se você misturar CSS in-line e externo, lembre-se de que as Propriedades Personalizadas seguem regras normais de cascata.
  • Você sempre pode usar o DevTools para inspecionar valores de propriedades personalizadas. Selecione um instância e verifique o painel Estilos Computados para ver quais propriedades personalizadas estão ativas.

Conclusão

O e elementos estão entre os aspectos mais elegantes, mas às vezes frustrantes, do SVG. A barreira Shadow DOM torna a animação deles mais complicada, mas Propriedades personalizadas CSS atuam como uma ponte. Eles permitem que você passe cor, movimento e personalidade através dessa fronteira invisível, resultando em animações mais limpas, mais leves e, o melhor de tudo, divertidas.

(gg, sim)



Fonte: Tecmundo, Olhar Digital, MeioBit

Mais recentes

PUBLICIDADE

WP Twitter Auto Publish Powered By : XYZScripts.com