- Com o suporte do CSS
@property nos navegadores modernos em geral, passou a ser possível declarar sintaxe, valor inicial e herança em propriedades customizadas, permitindo que o navegador faça a interpolação dos valores de forma natural
- O botão CTA do exemplo define
--gradient-angle como <angle> para fazer a transição de 0deg a 360deg e criar uma borda brilhante giratória com conic-gradient
- O efeito de hover atribui tipos a propriedades como
--gradient-percent, --gradient-angle-offset e --gradient-shine, para que o comprimento e o brilho do reflexo mudem suavemente
- A velocidade de rotação é controlada declarando a mesma animação duas vezes, deixando a segunda em direção reversa e pausada, e no hover ela desacelera para metade da velocidade a partir da posição atual
- Definir propriedades customizadas com base em
@property viabiliza expressões em CSS que antes eram difíceis de implementar, com potencial de uso também em aplicações grandes e sistemas de design
Animações de propriedades customizadas com @property
@property é uma regra para declarar a sintaxe permitida, o valor inicial e se há herança em propriedades customizadas do CSS
- É um recurso ligado à CSS Properties and Values API do CSS Houdini e, recentemente, passou a ter suporte em todos os navegadores modernos
- Quando o navegador conhece o tipo de uma propriedade customizada, ele consegue interpolar entre os valores, o que facilita criar transições e animações mais suaves do que usando apenas variáveis CSS comuns
Borda brilhante giratória em botão CTA
- O exemplo implementa em CSS um estilo de botão CTA brilhante, comum na web
- A propriedade customizada principal é
--gradient-angle, e com @property são declarados a sintaxe <angle> e o valor inicial 0deg
@property --gradient-angle {
syntax: "<angle>";
initial-value: 0deg;
inherits: false;
}
- Graças a essa definição, o navegador faz a transição de
0deg para 360deg de forma natural, renderizando como se o conic-gradient estivesse girando
@keyframes rotate-gradient {
to { --gradient-angle: 360deg; }
}
.rotate-gradient {
background: conic-gradient(from var(--gradient-angle), transparent, black);
animation: rotate-gradient 10s linear infinite;
}
Brilho de borda criado com camadas de fundo
- A borda brilhante é criada colocando
linear-gradient e conic-gradient juntos em background e definindo origens diferentes para cada fundo
linear-gradient usa padding-box, então não ultrapassa a área da borda
conic-gradient usa border-box, então se estende até o espaço criado pela largura da borda
- Uma borda transparente de
1px é adicionada para revelar o conic-gradient em rotação
.border-gradient {
background:
linear-gradient(black, black) padding-box,
conic-gradient(from var(--gradient-angle), transparent 25%, white, transparent 50%) border-box;
border: 1px solid transparent;
}
Gradiente que muda suavemente no hover
- Para cada propriedade customizada necessária na transição de hover, a
syntax é declarada em @property para que o navegador possa interpolar as mudanças de valor
- O fundo do botão é composto por um
linear-gradient, responsável pela cor interna, e um conic-gradient, responsável pelo brilho da borda
--gradient-percent define o tamanho da área de brilho e, no hover, muda para uma porcentagem maior, alongando o reflexo
--gradient-angle-offset é usado para reajustar o ângulo do gradiente durante o hover, evitando que o brilho pareça saltar para frente e para trás
- O brilho
--gradient-shine é reduzido para se misturar de forma mais natural com a cor de destaque ao redor
Como reduzir a velocidade de rotação no hover
- A dica em CSS para desacelerar a rotação é declarar a mesma animação de rotação duas vezes
- A segunda animação fica em direção reversa, com a duração reduzida pela metade, e no estado padrão é configurada como
paused
- No hover,
animation-play-state: running sobrescreve o paused, reduzindo a rotação para metade da velocidade
- Quando o hover termina, a animação não salta de volta para a posição inicial e acelera novamente a partir da posição atual
- A animação do botão CTA usa esse método para manter rotação e movimento sincronizados mesmo quando a velocidade muda
Pequenos brilhos e destaque interno
- O pequeno padrão de pontos dentro do botão é renderizado criando um fundo
radial-gradient no pseudo-elemento ::before
--gradient-angle também é reutilizada aqui, e uma máscara conic-gradient gira revelando apenas parte do padrão de pontos
- O ângulo do gradiente da máscara recebe um deslocamento de
45deg para alinhar com a rotação da borda brilhante
.shiny-cta::before {
mask-image: conic-gradient(
from calc(var(--gradient-angle) + 45deg),
black,
transparent 10% 90%,
black
);
}
- No pseudo-elemento
::after, é adicionado um gradiente com a cor de destaque para girar junto com a área brilhante
- O destaque interno reforça a sensação de luz fluindo pela parte interna do botão
Ajuste de cor no hover e refinamento final
- Como
::before e ::after já estão em uso no botão, o texto do botão é envolvido em um span
- Em um dos pseudo-elementos do
span, aplica-se um box-shadow desfocado com a cor de destaque, expandido até o tamanho do botão
- No hover, esse pseudo-elemento cresce e encolhe lentamente, criando uma sensação suave, como uma respiração
- Combinado com a cor de destaque girando por dentro, isso completa o efeito final do botão CTA
Possibilidades que se estendem ao sistema de design
1 comentários
Opiniões no Hacker News
Não sou desenvolvedor web, mas já criei sites de brinquedo sem framework e fiz tarefas básicas em alguns frameworks web. Quando o CSS apareceu, dava para, depois de pouco tempo, guardar tudo na cabeça e usar
O CSS do primeiro exemplo no CodePen parece quase uma sintaxe esotérica irreconhecível, e fico me perguntando se realmente precisamos ter até uma pequena linguagem de programação de animações dentro do sistema de estilos
Parece algo que poderia ser feito com JavaScript, e entendo a resistência a usar JS para tudo, mas, ainda assim, se é uma linguagem de programação, isso parece mais próximo do seu trabalho principal
Claro que também dá para fazer com JavaScript, e também dá para colocar um
canvase programar efeitos na GPU com WebGL. Em compensação, você teria de recriar por conta própria todos os recursos de acessibilidade de um botão HTML, e não sei se isso seria mais fácilMotores JS modernos são incríveis, mas não são tão eficientes quanto código nativo, o que aumenta o uso de CPU e, no fim, também é ruim para a duração da bateria
Pelo mesmo motivo, agradeço quando um site não torna JavaScript obrigatório
Algumas plataformas de hospedagem, por segurança, permitem personalização em HTML e CSS, mas bloqueiam JS. É o caso de lugares como o Itch.io, onde dá para personalizar jogos e perfis; usando animações CSS, é possível criar efeitos legais sem conceder acesso a JS, o que é razoável e útil
Ao ler este texto, senti meu cérebro resistindo a conceitos desconhecidos. Antes de ver os exemplos do blog, recomendo ler primeiro o artigo da MDN linkado na primeira frase
@propertyé algo que provavelmente só dá para pegar o jeito mexendo na prática, e, se você quer implementar UIs complexas reduzindo a dependência de JS, conhecer esses recursos esotéricos de CSS vira uma arma poderosaVariáveis CSS também eram afetadas pela cascata e podiam ser sobrescritas por classes etc.; coisas como
bg-opacitydo Tailwind não funcionam desse jeito?Pela MDN, soa quase igual às antigas variáveis CSS, mas com escopo limitado a um elemento específico ou seus filhos, e com restrições adicionais que reconhecem unidades CSS como ângulos e porcentagens
Ainda assim, não acho que eu vá usar. Um benefício pequeno desse tamanho não justifica o custo de complexidade e compatibilidade, e tento evitar nova sintaxe desnecessária. Depois das variáveis CSS, perdi bastante o interesse por novos recursos do CSS
Não entendo bem qual é a vantagem em relação a usar
transformno CSSGosto de trabalhar com CSS, mas, como também trabalho com colegas que têm dificuldade com CSS, recomendo fortemente o canal do Kevin Powell no YouTube
Ele já abordou esse recurso algumas vezes, e em um vídeo publicado uma semana atrás mostrou uma funcionalidade útil que propriedades registradas tornam possível: https://youtu.be/U8NykwZNbGs
Também há um artigo que explica propriedades registradas com exemplos fáceis de acompanhar: https://moderncss.dev/providing-type-definitions-for-css-wit...
O trabalho recente em CSS, especialmente Houdini, me deixa animado. Fazia tempo que eu não sentia isso desde que vi um livro de recursos do IE 5.5
Nos últimos 14 anos, muitos recursos novos chegaram ao CSS, mas eram mais próximos de funcionalidades básicas esperadas de um framework de estilos, como novas opções de layout ou variáveis
Mas os desenvolvedores do IE eram realmente ousados, e dava até para transformar código JS em módulos e anexá-los a elementos via CSS. Parece que esses recursos radicais finalmente estão voltando
Ex.: https://developer.chrome.com/docs/css-ui/houdini
É um texto curto e bom. Se quiser ver mais exemplos, especialmente exemplos bem mais simples e fáceis de pegar rapidamente, recomendo um artigo antigo do CSS-Tricks
É de 2021, mas continua válido e bem feito: https://css-tricks.com/exploring-property-and-its-animating-...
Acho que você vai gostar especialmente do exemplo de display flip com números de aeroporto/temporizador
Fiquei um tempo afastado do desenvolvimento web, e demorei demais para entender o que esse recurso faz de fato. Acho que o texto não explicou bem
Pelo que entendi, em vez de um valor primitivo como
360deg, você escreve algo comofrom var(--gradient-angle), e esse valor é trazido e substituído a partir do ponto em que foi definido no bloco@property --gradient-angle {...}Também há
inherits: false;; entendo o comportamento em si, mas não sei por que isso é necessário. Já dá para controlar herança com seletores CSS, então agora também dá para controlar em outro lugar? É difícil acompanharTambém me pergunto por que é preciso definir o tipo no bloco
@property. Em outras partes do CSS não se define tipo; será que o navegador não poderia inferir olhando onde o@propertyé usado?Em um experimento antigo para transformar o design do YouTube em algo neon, fiz com que a cor principal fosse controlada por uma única variável CSS e movi lentamente o matiz por todo o espectro
Sem
@property, não dá para animar variáveis CSS; então não é simplesmente usar uma variável no lugar de um valor primitivo, e sim poder animar essa variável junto com todos os lugares em que ela é referenciada. Com um único@keyframes neon-flow { from { --dc-neon-hue: 0; } to { --dc-neon-hue: 360; } }, dá para mover a cor principal, sombras etc.inherits: falsecontrola como uma propriedade personalizada é herdada. Ela pode ser herdada pelos filhos, comocolor: red, ou se aplicar só ao próprio elemento, comodisplay: flexO tipo parece necessário para saber, em tempo estático, o que será animado. Variáveis CSS podem ser qualquer coisa, mas propriedades CSS comuns carregam a informação de tipo na própria propriedade, como
colorO interessante é que essa sintaxe de tipos é a mesma sintaxe formal vista no MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/color#forma... Parece que partes internas do CSS foram expostas como uma API utilizável por desenvolvedores
@property; por exemplo, era possível declarar--my-prop: 10pxe depois usá-la em outro lugar comvar(--my-prop)O novo recurso,
@property, permite definir a propriedade antecipadamente, especificando que tipo de sintaxe ela deve aceitar, se deve herdar o valor do pai e qual é o valor padrão,initial-valueAssim, se algum elemento colocar
--my-prop: 5pxem uma propriedade declarada como tipo ângulo, isso será ignorado. Antes, seria um valor válido e poderia causar efeitos colaterais inesperados dependendo do ponto de usoAlém disso, ao escrever algo como
--my-prop: initial, é possível fazer com que ela use oinitial-valuesem saber exatamente qual é o valor padrão@propertyfaz nem como usá-loIsso fica completamente encoberto por um exemplo excessivamente complexo
Esse site me deixou de bom humor
Sempre gostei de mexer com CSS, mas, depois de mais de 10 anos fazendo desenvolvimento web e trabalhando profissionalmente com web, também passei a entender o quanto as pessoas odeiam CSS
Posso passar um tempo infinito explorando e experimentando HTML+CSS escrito à mão, e até faço deploy para ver como fica em um celular de verdade. 99% disso nunca é usado em lugar nenhum
Para a maioria, seria perda de tempo, mas esse site realmente alegrou meu dia
Ele ficou mais complexo nos últimos 10 anos, mas hoje dá para fazer de forma muito mais simples coisas que fazíamos há 10 anos, e o código daquela época ainda funciona
E tudo bem. Eu também não entendo APEX, APL nem o framework mais novo do momento. Mas entendo CSS, então gosto bastante
Para algumas pessoas, ele faz sentido; para outras, não. O problema surge quando alguém para quem CSS não encaixa precisa trabalhar com CSS por profissão, e aí naturalmente passa a odiá-lo. Se meu trabalho fosse manter uma instalação do Active Directory, eu também odiaria. Mas isso não significa que CSS em si seja ruim
Deve haver algum fórum com discussões sérias em algum lugar, mas parece que estou perdendo isso
Em produção, especialmente, escrevi quase todo o frontend em JSX, mas, depois de cair na toca do coelho do web scraping, minha compreensão de lógica de seletores melhorou bastante
Como pensamento provocativo relacionado, se usássemos mais elementos semânticos no trabalho prático, acho que a lógica de seletores não seria tão problemática quanto é hoje. Também não precisaríamos manter manualmente comportamentos que o HTML puro já definiu, como modais
Antigamente, a Microsoft era a mais famosa por violar especificações; hoje, acho que é a Apple
Essas animações fazem tudo parecer anúncio display dos anos 2000. No mau sentido
Espero muito que essa estética não vire moda
Essas coisas têm uma vibe forte de marketing e manipulação. Prefiro que me deixem ler o site e decidir o que vou fazer. Não quero ser interrompido por elementos que forçam meu olhar para aquilo que gera dinheiro
Caso contrário, todo mundo vai implementar isso dentro de ecossistemas fechados
PFM, ou seja, “pura magia”, é exatamente a sensação que dá ao ver o que é possível fazer com animações em CSS
Mas é algo tão especializado para CSS e somente CSS que fica mais difícil de aprender e conceitualizar do que implementar proceduralmente em JS. Não consigo pensar muito bem desse jeito, e só as opções de uso de CSS
flexjá são complicadas o bastanteMas é poderoso, realmente incrivelmente poderoso, e muito eficiente na maioria dos navegadores. A esmagadora maioria dos desenvolvedores de apps web não precisa de 99% do que o CSS oferece, mas é legal saber que esses recursos existem
Eu coloco na página elementos sem estilo conectados à lógica de negócio, e o designer pode estilizá-los como quiser. Se necessário, depois iteramos no refinamento da UI
Do ponto de vista puramente imperativo, é preciso algum tempo lendo a especificação e experimentando, mas considero uma forma de pensar que vale mais do que apenas usar SQL e CSS. Claro que SQL e CSS em si já valem bastante
Eu ficaria muito feliz se eles apenas decidissem o nome do recurso de CSS “masonry”[1] para que pudéssemos usá-lo sem scripts
[1] https://github.com/w3c/csswg-drafts/issues/9733
propertyfaz parte da CSS Houdini API e permite manipular CSS a partir de JavaScript de forma muito mais poderosa do que anteshttps://developer.mozilla.org/en-US/docs/Web/API/Houdini_API...
Faz quase 10 anos que eu não via o autor demonstrar tanto entusiasmo por um novo pedaço de CSS, e isso é muito bom
Se eu estivesse na casa dos 20, teria passado horas, dias, brincando com as possibilidades desse recurso. Era divertido fazer algo funcionar em CSS
Hoje, com
flexbox,gride com a maioria dos sites e apps seguindo princípios de design padronizados, ficou bem mais fácil, e acho que UI web está perto de ser um problema resolvidoAinda há momentos em que preciso reler as partes ambíguas de
flexegrid. O posicionamentostickyé um dos recursos mais úteis, mas quando, por algum motivo, não funciona, depurar e entender a causa é muito difícil ou quase impossível. Há também problemas como verificar se algum ancestral temoverflowem algum lugarTambém é difícil encontrar documentação que explique bem esses casos de borda, e depurar CSS apenas pelo código-fonte, sem ferramentas de desenvolvedor, é quase impossível; é preciso inspecionar os elementos em tempo de execução
A maioria dos elementos de entrada nativos ainda tem possibilidades de estilização muito limitadas, e tivemos que esperar anos por modais e popovers nativos. Da última vez que verifiquei, ainda nem era possível animar a altura de
display: noneparablockFico pensando se não ficamos tão acostumados aos vários problemas do CSS que perdemos o senso crítico