
O @property
at-rule recentemente ganhou suporte em todos os navegadores modernos, desbloqueando a capacidade de definir explicitamente uma sintaxe, valor inicial e herança para propriedades personalizadas CSS. Parece que faz uma eternidade que o CSS Houdini e sua API de Propriedades e Valores CSS foram inicialmente introduzidos. Eu experimentei com moderação ao longo do tempo, lendo artigos que dançavam em torno dos conceitos, mas eu mal tinha arranhado a superfície do que @property
poderia oferecer. A demonstração subsequente explora o que é possível na próxima geração de CSS.
Chamadas para ação
Já viu aqueles elementos de página da web elegantes, chamativos e brilhantes de call-to-action? Ondas de sites pela web, especialmente aqueles que comercializam serviços e softwares pedindo para você “Atualizar sua conta” ou “Inscrever-se hoje”, descobriram o visual e aderiram. Não estou aqui para criticá-lo e admito que acho que é meio novo. Pensei em experimentar esse estilo eu mesmo. Confira o resultado no CodePen abaixo.
Há muito o que desempacotar nesta demonstração. Vamos começar com aquele brilho girando em volta do botão. Abra o painel CSS da demonstração para encontrar uma coleção de @property
regras relacionadas a essas propriedades personalizadas que precisam ser animadas. Aqui está a definida para --gradient-angle
:
@property --gradient-angle {
syntax: "<angle>";
initial-value: 0deg;
inherits: false;
}
A @property
regra comunica ao navegador que <angle>
é a sintaxe permitida para essa propriedade personalizada e seu valor inicial é 0deg
. Isso permite que o navegador faça uma transição suave de 0deg
para 360deg
e produza um gradiente rotativo.
@keyframes rotate-gradient {
to { --gradient-angle: 360deg; }
}
.rotate-gradient {
background: conic-gradient(from var(--gradient-angle), transparent, black);
animation: rotate-gradient 10s linear infinite;
}
Eu montei uma demonstração simples de gradiente para focar nas poucas linhas necessárias para renderizar esse conceito.
Podemos obter o efeito de borda animada brilhante evoluindo um pouco esse código. Vamos introduzir a linear-gradient
como o primeiro valor da background
propriedade do elemento e definir a background-origin
para cada valor.
- A origem do
linear-gradient
é definida comopadding-box
. Isso evita que o gradiente se espalhe para a área da borda. - A
conic-gradient
origem é definida comoborder-box
. Este gradiente transborda para o espaço criado pela largura da borda. - Para revelar a rotação
conic-gradient
, uma borda transparente de pixel único é adicionada.
.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;
}
No painel CSS da demonstração de rotação de gradiente simples, descomente o .border-gradient
conjunto de regras para revelar a borda animada brilhante. Parece bem bacana! Para mais exemplos, incluí um monte de artigos sobre bordas de gradiente animadas na seção de recursos no final do post.
Transições de foco suaves e sedosas
Alguns ingredientes especiais ajudam a facilitar uma transição de gradiente suave e amanteigada quando o elemento é passado por cima. Vamos nos aprofundar em seus background
valores:
.shiny-cta {
background:
linear-gradient(var(--shiny-cta-bg), var(--shiny-cta-bg)) padding-box,
conic-gradient(
from calc(var(--gradient-angle) - var(--gradient-angle-offset)),
transparent,
var(--shiny-cta-highlight) var(--gradient-percent),
var(--gradient-shine) calc(var(--gradient-percent) * 2),
var(--shiny-cta-highlight) calc(var(--gradient-percent) * 3),
transparent calc(var(--gradient-percent) * 4)
)
border-box;
}
Tive que ajustar os valores de porcentagem e deslocamento até que o comprimento do brilho e a transição parecessem opticamente alinhados. Finalmente, o --gradient-shine
brilho é atenuado para se misturar mais perfeitamente com as cores de destaque adjacentes.
Vá mais devagar
Esta dica CSS para desacelerar uma rotação ao passar o mouse realmente me surpreendeu. No código de exemplo da dica, a mesma animação de rotação é declarada duas vezes. A segunda é invertida e pausada, sua duração é dividida pela metade. Quando o elemento é passado o mouse, animation-play-state: running
substitui o paused
valor e desacelera a rotação para metade da velocidade. A parte alucinante, pelo menos para mim, é que a animação acelera de volta para a posição atual quando o elemento não está mais passado o mouse. Sem voltar para uma posição inicial, sem elementos wrapper extras necessários. Essa é uma dica e tanto.
As animações de call-to-action dependem desse método para desacelerá-las quando o botão é passado. Essa técnica mantém todas as rotações e movimentos sincronizados conforme mudam de velocidade.
Pequenos pontos brilhantes
Olhando ainda mais de perto, descobriremos pontos do tamanho de um furo de alfinete brilhando dentro do botão conforme a borda brilhante passa perto deles. Para renderizar esse padrão de pontos, um radial-gradient
fundo é criado.
.shiny-cta::before {
--position: 2px;
--space: calc(var(--position) * 2);
background: radial-gradient(
circle at var(--position) var(--position),
white calc(var(--position) / 4),
transparent 0
)
padding-box;
background-size: var(--space) var(--space);
background-repeat: space;
}
Lembra daquela --gradient-angle
propriedade personalizada? Ela retornou! Mas, desta vez, está sendo usada em uma conic-gradient
máscara que revela partes do padrão de pontos conforme ele gira. O ângulo do gradiente é deslocado em 45 graus para alinhá-lo perfeitamente 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
);
}
Para um último toque de mágica, um gradiente contendo a cor de destaque é adicionado ao ::after
pseudoelemento, girando em uníssono com a área de brilho. Esses destaques fluindo pelo botão adicionam um ambiente agradável e acolhedor que estava faltando anteriormente.
Melhorando as cores do hover
Os estilos hover pareciam decentes. Mas não pareciam totalmente finalizados. Senti o desejo de melhorar. Criar mais profundidade. Fazer estourar, como dizem.
Os elementos do botão ::before
e ::after
pseudo já estavam em uso, então envolvi o texto do botão em um span
elemento. Um desfocado box-shadow
contendo a cor de destaque é aplicado a um de seus pseudo elementos, que é então expandido para preencher as dimensões do botão. Ao passar o mouse, o pseudo elemento aumenta e diminui lentamente, evocando uma vibração semelhante à respiração relaxada. Emparelhado com a cor de destaque giratória dentro do botão, o efeito finalmente ressoou comigo. Este botão de call-to-action intrincadamente projetado parecia completo.