2 pontos por GN⁺ 2024-09-05 | 1 comentários | Compartilhar no WhatsApp
  • 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

 
GN⁺ 2024-09-05
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

    • Não entendo bem essa sensação. Se você não é desenvolvedor web, especialmente frontend, provavelmente nem teria muito motivo para criar elementos HTML com esses efeitos chamativos; então não vejo por que seria um problema o que o CSS consegue fazer com recursos avançados
      Claro que também dá para fazer com JavaScript, e também dá para colocar um canvas e 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ácil
    • É por causa da performance. Em JS, isso precisa rodar sem engasgos 60 vezes por segundo, mas JS é single-threaded, então no momento em que a thread principal trava, você perde frames
      Motores 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
    • Qualquer oportunidade de evitar JavaScript em um site é bem-vinda, mesmo que dê mais trabalho. Visitantes que navegam com JavaScript desativado conseguem evitar muitos exploits e rastreadores que atormentam a web hoje
      Pelo mesmo motivo, agradeço quando um site não torna JavaScript obrigatório
    • Não é uma boa ideia precisar de uma linguagem de programação completa para coisas que dizem respeito apenas à estética da página
      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
    • Parece que, sem entender bem o domínio do problema e sem conhecer a sintaxe, você está vendo como mudança negativa algo que não entende de imediato
  • 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 poderosa

    • Mesmo lendo o artigo da MDN, simplesmente não consigo entender. Isso não é literalmente uma variável CSS?
      Variáveis CSS também eram afetadas pela cascata e podiam ser sobrescritas por classes etc.; coisas como bg-opacity do Tailwind não funcionam desse jeito?
    • Também acho parecido. Este texto parece explicar muito mal
      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
    • Achei que fosse só comigo, mas realmente parece muito estranho
      Não entendo bem qual é a vantagem em relação a usar transform no CSS
  • Gosto 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

    • Não sei bem se “ousados” aqui está sendo usado em sentido positivo ou negativo
    • Acho que não era assim que o css3pie(http://css3pie.com/) funcionava?
  • É 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 como from 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 acompanhar
    També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?

    • Para mim, a maior vantagem foi que esse recurso permite animar variáveis CSS
      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: false controla como uma propriedade personalizada é herdada. Ela pode ser herdada pelos filhos, como color: red, ou se aplicar só ao próprio elemento, como display: flex
      O 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 color
      O 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
    • As propriedades CSS em si já existiam antes de @property; por exemplo, era possível declarar --my-prop: 10px e depois usá-la em outro lugar com var(--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-value
      Assim, se algum elemento colocar --my-prop: 5px em 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 uso
      Além disso, ao escrever algo como --my-prop: initial, é possível fazer com que ela use o initial-value sem saber exatamente qual é o valor padrão
    • Obrigado por essa explicação. É difícil entender um texto que não explica o que @property faz nem como usá-lo
      Isso 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

    • Gosto muito de CSS. Acho que é fácil o suficiente de entender
      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
    • As pessoas que falam alto que odeiam CSS geralmente são pessoas que não entendem CSS
      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
    • CSS é divertido de brincar, e os novos recursos também valem explorar. Só que às vezes parece que os recursos de CSS surgem num clima de “o que mais dá para criar?”
      Deve haver algum fórum com discussões sérias em algum lugar, mas parece que estou perdendo isso
    • Ainda está bem minimalista, mas estou tentando escrever mais CSS à mão para pegar a sensação de trabalhar fora de ferramentas como Bootstrap ou Tailwind
      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
    • No momento em que você precisa implementar algo com suporte razoavelmente amplo, em vez de lidar só com a combinação específica do seu dispositivo, tela, navegador, versão do navegador e sistema operacional, pequenas violações da especificação ficam realmente irritantes
      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

    • Também acho. Foi interessante ver que dava para fazer os exemplos do CodePen só com CSS, mas achei um pouco exagerado; se visse o primeiro botão de chamada para ação em um site real, acharia brega e constrangedor
      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
    • No começo, achei que o CodePen estava tentando me vender um upgrade
    • Essas coisas já são feitas em código de apps nativos, então a web também precisa ter recursos correspondentes
      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 flex já são complicadas o bastante

    • CSS realmente parece um domínio alienígena próprio. O fato de a sintaxe ser estranha para a maioria dos desenvolvedores também não ajuda
      Mas é 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
    • Por isso contratamos um designer que sabe codar HTML+CSS
      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
    • É um paradigma declarativo, como SQL
      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
    • JS é sempre, absolutamente sempre, o último recurso. Nos últimos anos, conforme recursos de CSS chegaram à maioria dos navegadores, removi muito JS do código, e gosto de deixar páginas com JavaScript Zero
      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
    • Neste caso, property faz parte da CSS Houdini API e permite manipular CSS a partir de JavaScript de forma muito mais poderosa do que antes
      https://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, grid e 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 resolvido

    • Fico curioso para saber quais seriam esses princípios de design padronizados
    • Não entendo o que teria sido resolvido. Layout?
      Ainda há momentos em que preciso reler as partes ambíguas de flex e grid. O posicionamento sticky é 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 tem overflow em algum lugar
      També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: none para block
      Fico pensando se não ficamos tão acostumados aos vários problemas do CSS que perdemos o senso crítico