14 pontos por GN⁺ 2025-08-30 | 3 comentários | Compartilhar no WhatsApp
  • As principais causas recentes da queda de desempenho em sites são o uso excessivo de JavaScript e scripts de rastreamento, e em muitos casos isso pode ser substituído suficientemente apenas com HTML/CSS
  • Recursos adicionados recentemente, como aninhamento em CSS, cores relativas e novas unidades de viewport (lvh, svh, dvh), permitem resolver de forma simples tarefas que antes dependiam de JS ou preprocessadores
  • CSS não é apenas uma ferramenta de estilo, mas uma linguagem poderosa capaz de implementar animações, validação de entrada, temas em modo escuro e menus sanfona
  • Também em termos de desempenho, o CSS usa aceleração por GPU e roda em uma thread separada, sendo mais suave e eficiente que JS em animações e transições
  • O autor destaca o CSS não apenas como uma ferramenta prática, mas como um meio de expressão e arte, e recomenda que desenvolvedores aproveitem mais o potencial do CSS moderno

Introdução: a complexidade da web e uma nova tentativa

  • Muitos sites sofrem com queda de desempenho e complexidade por causa do uso excessivo de frameworks JavaScript
    • Apps em React levam vários segundos para carregar, e o NextJS provoca erros de hidratação
    • A pasta node_modules ocupa vários gigabytes
  • Mesmo sem JavaScript, é possível implementar recursos poderosos apenas com HTML e CSS
    • Fora carrinhos de compra complexos de sites de e-commerce ou dashboards, JavaScript pode não ser essencial
  • Este texto apresenta os recursos mais recentes do CSS e incentiva desenvolvedores a explorarem várias possibilidades sem depender apenas de JavaScript

Equívocos e percepção sobre CSS

CSS é mesmo difícil e desconfortável?

  • A percepção negativa sobre CSS vem da falta de aprendizado básico
    • Muitos desenvolvedores pulam os fundamentos de CSS e focam em JavaScript ou TypeScript
    • CSS não é uma simples ferramenta de estilização, mas uma linguagem específica de domínio com recursos poderosos
  • CSS permite criar layouts complexos com facilidade usando ferramentas como flexbox
    • Exemplo: centralizar uma div com display: flex e justify-content: center é simples
    • As ferramentas de desenvolvedor do navegador oferecem widgets para ajustar visualmente propriedades de flexbox
  • Se você se aprofunda só em um lado (por exemplo, JS) e negligencia CSS, é natural que a dificuldade aumente
Publicidade

A dor de escrever CSS, e o que mudou

  • Antigamente CSS realmente não era tão confortável, por isso surgiram ferramentas como Sass e Tailwind
    • Ex.: era preciso gerenciar cadeias longas de seletores como .post > .buttons .like:hover
  • Recentemente foram adicionados recursos de melhoria de qualidade (como aninhamento), tornando o desenvolvimento agradável mesmo só com CSS puro
    • O aninhamento em CSS reúne estilos relacionados em um só lugar e melhora a legibilidade
      • Ex.: .post { & > .buttons { .like { &:hover { ... } } } }
      • A relação entre pai e filho fica clara, permitindo nomes de classe mais curtos e simples
  • Cores relativas facilitam o ajuste de cores
    • É possível ajustar a luminosidade com hsl(from #123456 h s calc(l + 10))
    • color-mix() mistura duas cores para gerar cores dinâmicas
  • A sintaxe de intervalo em media queries permite condições intuitivas como (width <= 768px)
  • A unidade lh permite estilização alinhada à altura da linha
  • A propriedade scrollbar-gutter resolve problemas de deslocamento de layout causados pela barra de rolagem
  • O Baseline garante compatibilidade de recursos entre os principais navegadores
    • newly available funciona em navegadores recentes
    • widely available é compatível até com navegadores de 2,5 anos atrás
    • Ex.: aninhamento em CSS é suportado por todos os navegadores desde dezembro de 2023
Publicidade

Por que desenvolver só com CSS/HTML?

  • Alguns usuários desativam o JavaScript por padrão (por motivos de segurança, privacidade etc.)
  • Ao oferecer um site apenas com CSS/HTML puro, aumenta a chance de esses usuários conseguirem usá-lo
  • Do ponto de vista de desenvolvimento e da experiência do usuário, usar apenas CSS/HTML traz vantagens em velocidade, acessibilidade e uso de CPU/bateria
    • Animações em CSS rodam na thread do compositor, reduzindo a carga na CPU
    • JavaScript roda via event loop e pode introduzir um pequeno atraso
  • Há melhora em acessibilidade e facilidade de uso
    • Efeitos de hover em botões, animações de toast e validação de entrada podem ser implementados facilmente com CSS

Exemplos práticos e principais recursos de CSS

Criando animações de entrada naturais com @starting-style

  • Antes, implementar animações de entrada de elementos exigia estruturas complexas com keyframes, gatilhos em JS etc.
  • Com a introdução de @starting-style, ficou simples definir o estado inicial. É fácil implementar a animação do estado inicial do elemento (por exemplo, fade-in)
    • Configuração com transition: opacity 1s; @starting-style { opacity: 0; }
    • Funciona sem @keyframes separado nem JavaScript
  • Basta declarar o estado inicial junto com a transition para que a animação seja aplicada naturalmente
    • Ex.: tratar suavemente a transição de opacidade e posição de uma mensagem toast

Configuração fácil de tema claro/escuro

  • color-scheme: light dark alterna o tema automaticamente conforme a preferência do usuário
  • A função light-dark(#000, #FFF) define cores apropriadas para modo claro/escuro
  • Botões de rádio e o seletor :has permitem que o usuário escolha o tema
    • É possível trocar de tema só com CSS, sem JavaScript
    • Opcionalmente, JavaScript pode ser adicionado para salvar/carregar o tema
    Publicidade

Criando UI customizada com rádio/checkbox e :has, :checked etc.

  • Interações complexas como abas, sanfonas e toggles também podem ser implementadas sem JavaScript
  • Botões de rádio podem receber estilo customizado com :checked e :has
    • Ex.: label:has(input:checked) define o estilo do botão selecionado
    • O elemento de entrada pode ser ocultado com opacity: 0, mantendo a acessibilidade para leitores de tela
  • O elemento details é ideal para implementar menus sanfona como os de FAQ
    • O atributo name permite controlar um único item aberto por vez
    • Também é possível adicionar animações conforme o estado [open]

Validação de entrada e reflexão de estado

  • A combinação de atributos HTML como pattern e required com pseudoclasses CSS (:valid, :invalid, :user-valid etc.) oferece validação em tempo real e feedback visual
  • Melhorias na experiência do usuário, como mudar o estilo de outline/border dos campos de entrada
  • O atributo pattern do HTML permite validar campos de entrada
    • Ex.: \w{3,16} permite letras, números e underscore com 3 a 16 caracteres
  • :valid e :invalid do CSS permitem estilização conforme a validade
    • :user-valid e :user-invalid só aplicam estilo depois que o usuário interage
    Publicidade
  • O seletor :has permite estilizar outros elementos de acordo com o estado do input
  • Em alguns casos (por exemplo, condições de entrada complexas), JS é necessário, mas na maioria CSS/HTML é suficiente

Como usar corretamente unidades de viewport

  • As unidades vw/vh têm problemas de precisão no mobile por causa do aparecimento/desaparecimento da barra de endereço (navegação)
  • Recomenda-se usar as novas unidades de viewport, como lvh/svh/dvh (largest/smallest/dynamic viewport height)
    • lvh: para tela cheia (ex.: plano de fundo de tela inteira)
    • svh: para botões, links e outros elementos que sempre precisam permanecer visíveis na tela
    • dvh: para alocar tamanho de forma dinâmica conforme mudanças como rolagem
  • Sobreposição do teclado pode ser tratada com a propriedade interactive-widget ou com a VirtualKeyboard API
    • <meta name="viewport" content="width=device-width, interactive-widget=resizes-content">
    • Em navegadores baseados em Chromium: navigator.virtualKeyboard.overlaysContent = true

Wishlist de CSS (o que faz falta ou seria desejável)

  • Blocos reutilizáveis: aplicar outra classe dentro de uma classe (ex.: @apply border)
  • Seletores combinados com media query: combinar @media e seletor de classe
  • Variável de nth-child: span { --nth: nth-child(); } para estilização dinâmica
  • Seletor nth-letter: estilizar uma letra específica (ex.: p::nth-letter(2))
  • Remoção de unidade: gerar valor sem unidade com calc(100vw / 1px)
  • Função image(): suporte a cor alternativa e fragmentos de imagem
  • Tag style dentro do body: suporte oficial no padrão para aliviar problemas de FOUC

Encerramento: CSS e a dimensão artística da web

  • CSS não é apenas uma ferramenta, mas um meio de expressão criativa
  • Ferramentas de IA ou cadeias de build (linters, minificadores) podem limitar a criatividade
  • CSS atende ao mesmo tempo desempenho, acessibilidade e expressão artística
  • Este texto foi escrito com cerca de 49 kB de HTML/CSS sem JavaScript
    • Todos os widgets interativos e elementos visuais foram implementados manualmente
    • Ex.: CSS Click Game prova o potencial do CSS como linguagem de programação

3 comentários

 
duqduqduq 2025-09-01

Eu era full stack, mas conforme a carreira vai subindo, você acaba tendo cada vez menos oportunidades de trabalhar com FE, então fiquei uns 10 anos sem mexer nisso. Recentemente tive que dar uma aula em uma empresa e fui dar uma olhada para fazer uma introdução rápida, e fiquei realmente impressionado com o quanto tudo mudou. Se juntar com scss, fica melhor ainda. Mas essa área de CSS é bem curiosa. Aprender é fácil, mas usar bem a ponto de ser reconhecido por isso, na minha opinião, depende muito do senso estético e da criatividade de cada pessoa. É uma pena que, em uma era da web que valoriza mais usabilidade e design, o valor dos publishers não pareça ser mais reconhecido.

 
ahwjdekf 2025-09-01

Desta vez, como hobby para experimentar tecnologias de desenvolvimento web, sem nem o básico e aprendendo na marra, tentei criar um quadro de posts básico usando nextjs, authjs, tailwind e shadcn... no fim, a maior dificuldade de aprendizado foi CSS.

 
GN⁺ 2025-08-30
Opiniões no Hacker News
  • Sou grato pelo recurso de nesting adicionado ao CSS desta vez, mas, no geral, CSS é realmente estranho e, pessoalmente, acho que é uma linguagem ruim. Pode ser culpa minha por não saber usá-lo direito, mas é tão complexo e bagunçado que parece que estou movendo runas indecifráveis de um lado para o outro. O sistema de estilização e o de layout estão misturados, e como herança e inclusão seguem relações diferentes, fica ainda mais confuso. Acho que juntar estilização e layout foi um erro, e não sinto que adicionar mais recursos a um sistema que já está quebrado na base possa ser a solução.

    • Eu também ganho a vida com CSS há 10 anos, mas parece que CSS não foi exatamente projetado como uma linguagem, e sim expandido conforme a necessidade. Novos módulos vão sendo anexados em cima de propriedades antigas, e isso faz com que entrem em conflito ou funcionem de forma ligeiramente diferente, o que dificulta o debug. Dá para citar como exemplo o box model e o layout flex funcionando de formas diferentes, e a propriedade gap se comportando de modo distinto em flex e grid (link). Depois que você cria um layout, ele na prática fica quase congelado; sem encapsulamento complexo nativo ou baseado em JS, é difícil alterá-lo com flexibilidade. Aí começam a surgir problemas como a espessura da fonte mudando do nada ou o menu mobile aparecendo também no desktop.
    • Eu discordo. Acho que a principal razão de vermos tantas opiniões negativas sobre CSS é que as pessoas não o aprendem direito ou, principalmente, não entendem a cascade. Já me aprofundei bastante na especificação de CSS e acabei achando que é uma linguagem muito bem projetada para o objetivo de separar a semântica do markup do estilo.
    • Acho impossível separar estilização e layout. Qualquer pessoa que já fez desenvolvimento de UI sente que os dois elementos são intrinsecamente ligados e interdependentes. Por exemplo, comprimento e tamanho do texto, overflow, margin, padding etc. afetam uns aos outros. Se você muda a borda ou o espaçamento de um elemento, o espaço disponível para o conteúdo interno também muda. Não dá para separar os dois completamente.
    • Acho que o verdadeiro problema do CSS é a cascade. E boa parte do desenvolvimento frontend moderno, na verdade, gira em torno de bloquear essa cascade. A componentização de UI é um exemplo disso. Layout é um problema separado, mas fica mais complexo por causa da compatibilidade. Se todo layout funcionasse por padrão só com flexbox ou grid, e inline e non-inline não fossem misturados no mesmo contêiner, seria muito melhor. O React Native funciona exatamente assim. No React Native, os estilos não fazem cascade, então é muito mais fácil de gerenciar.
    • Tudo isso faz sentido. Mas é isso que temos hoje. Já pensei se não seria possível criar um modelo conceitualmente mais consistente e transpilar para CSS. Talvez desse até para implementar um sistema de layout mais organizado matematicamente com container queries e calc. As linguagens de pré-processamento atuais acabam só empilhando recursos inacabados em cima de conceitos já inacabados do CSS, o que deixa tudo ainda mais confuso.
  • Acho que a pior parte do CSS é que muita gente nem aprende direito e, depois de ter sido forçada a usá-lo por um dia, já sai com opiniões fortíssimas.

    • Eu tive esse “um dia” também. Estava fazendo um app de podcast e queria criar um footer flutuante que (1) ficasse sempre embaixo, (2) fosse sempre visível, (3) não cobrisse o conteúdo e (4) funcionasse sem hacks adicionais. Aí descobri que isso é impossível em CSS. Excelente sistema, de fato.
    • Aprendi CSS 20 anos atrás. Minha conclusão é que, por causa da cascade, CSS deveria se chamar Crappy Style Sheets. Quando várias pessoas colaboram, o comportamento padrão é “muda isso aqui e quebra algo aleatório ali”. A linguagem é marcada por regras complexas para sobrescrever outras regras, e isso é um péssimo fundamento. Os meios de fazer targeting complexo ficam cada vez mais complicados, e no fim você acaba com código tipo .foo > .bar:nth-child(2n) ~ .baz. Aí isso quebra o código do colega também. Até fazer um layout simples já dá dor de cabeça. Melhorou bastante nos últimos anos, mas acho que o problema sempre foi essa estrutura centrada na cascade. Outras críticas, como a sintaxe, são secundárias. Se fosse prática e fácil de usar, a sintaxe seria aceitável, mas CSS não era assim. Criar layout para web não deveria virar uma profissão.
    • Sobre a ideia de que “muita gente usa CSS sem aprender”, exigir que a pessoa tenha de estudar mais de 20 especificações para ter direito de usá-lo é uma abordagem absurda. Se as pessoas usam uma ferramenta e encontram problemas, é preciso avaliar se o problema está na ferramenta, e não culpar as pessoas. Em vez de exigir que todos usem a serra com mais cuidado, o certo é colocar proteções nela.
  • Não me convence muito a justificativa, neste texto, de que “alguns usuários não querem JavaScript”. Eu mesmo sou usuário de Arch e sou bem entusiasta de scripting e crawling, mas não acho particularmente importante focar em ambientes “NoScript”. Isso me parece um gosto muito minoritário e, no geral, dá para ignorar. Lembra um pouco a era do “10% usam IE6”. Ainda assim, acho que há inúmeras outras razões pelas quais CSS é superior. De qualquer forma, esse não é o ponto principal, mas a sensação geral da discussão me parece essa.

    • Aquilo que eu consigo fazer declarativamente em poucas linhas de CSS, se eu fizer de forma imperativa em JS, vira dezenas de linhas e traz mais comportamentos estranhos, problemas de compatibilidade com frameworks e atraso no tempo até interatividade. O ambiente NoScript é só um bônus. No fundo, o que eu sinto falta mesmo é de DSSSL.
    • No texto principal, os usuários avessos a JavaScript são mencionados só de passagem; a maior parte do artigo está focada em mostrar os próprios recursos de CSS. Desempenho é uma das motivações, mas apresentar as técnicas de CSS é uma abordagem muito mais produtiva.
    • Eu uso a internet normalmente em ambiente NoScript. Só libero exceções para sites que realmente precisam de JS. Isso é bem melhor para desempenho, bateria e segurança. Você já tentou viver mais de uma semana com NoScript? Eu também tinha essa mesma opinião antes de usar. E, aliás, eu sou o autor deste post de blog.
    • Não acho que o público NoScript seja tão relevante ou precise ser um alvo. Mas, mesmo que o autor não tenha dito isso explicitamente naquela breve menção, acho que há um valor enorme em escrever menos código e depender mais da plataforma do navegador. Deixar o máximo possível a cargo do navegador traz uma eficiência muito grande.
    • Acho que, na verdade, quase todos os usuários não querem JavaScript.
  • Eu não sabia que nesting já tinha virado padrão oficial. Até recentemente achei que ainda estava em fase de proposta. CSS tem muitas esquisitices, mas passa uma sensação de evolução para uma linguagem cada vez melhor, como aconteceu com JavaScript. Flexbox, o seletor :has e nesting aliviaram bastante vários pontos de dor antigos.

  • Duas funcionalidades de CSS que estavam na minha wishlist já existem na especificação.

  • Acho a sintaxe de CSS péssima. Trabalho com 10 a 15 linguagens, mas CSS é a mais difícil de ler e entender. É ainda mais enigmática do que assembly x86. CSS parece uma entrada pré-tokenizada para um renderizador, mas sem ser realmente tokenizada, e é estranho demais para humanos escreverem. Parece algo que deveria ser usado como exemplo do que não fazer, como ASN.1 em RFC.

    • Fico curioso para saber quantas dessas linguagens são declarativas ou específicas de domínio. Comparar CSS com assembly não é apropriado. CSS é declarativo, assembly é o oposto. A maioria dos desenvolvedores frontend também sofre no começo ao sair de linguagens imperativas para CSS, mas melhora com o tempo. A terminologia e os conceitos de CSS vêm muito mais do design e da editoração do que da computação. Muitos desenvolvedores abordam CSS como se fosse um conjunto explícito de comandos, mas CSS funciona de uma forma peculiar, em que as coisas se influenciam mutuamente. Uma única propriedade pode até mudar o algoritmo de layout inteiro (Introdução aos algoritmos de layout em CSS).
    • Mesmo que você “trabalhe com 15 linguagens”, acho que CSS continua sendo realmente difícil de conhecer de verdade. Mesmo usando muitas linguagens de programação, atingir um nível em que se possa dizer que realmente “conhece” uma delas exige uma quantidade enorme de experiência prática (wiki sobre a ilusão de profundidade explicativa). A melhor forma de entender CSS é observar diretamente o resultado da renderização e avaliá-lo. Eu o uso assim há décadas.
    • Eu também sinto que CSS é o pior do trio HTML/CSS/JS.
    • Eu gostaria de ouvir de forma mais concreta o que significa dizer que “CSS é uma entrada pré-tokenizada”.
    • Um código como font-size: 12px me parece perfeitamente legível por humanos, então não entendo por que isso parece tão difícil para algumas pessoas. Para mim, é realmente simples.
  • Fico em dúvida se o exemplo de abas com rádio é bom do ponto de vista de acessibilidade. Pelo que sei, segundo o WAI-ARIA, atributos como aria-selected, tabindex e aria-controls precisam ser atualizados por JS quando a aba muda, mas não tenho certeza. Acessibilidade muitas vezes fica em segundo plano, e às vezes as pessoas acham erroneamente que usar só HTML/CSS já garante acessibilidade automaticamente. É algo para considerar mais uma vez ao escolher a abordagem.

    • Pelo que eu sei, essas abas com rádio funcionam bem com navegação por teclado e leitor de tela, e seguem o fluxo de navegação entre aba e conteúdo do exemplo do WAI-ARIA (exemplo do WAI-ARIA). Não tenho formação em acessibilidade, mas estou tentando verificar isso o máximo possível. Também testei pessoalmente com várias ferramentas de acessibilidade.
    • No texto original, o autor menciona acessibilidade várias vezes e até se esforçou para contornar bugs de navegador relacionados a isso (nota relacionada).
    • A acessibilidade deste próprio post de blog (especialmente o contraste) é tão ruim que, como desenvolvedor web que trabalha em uma organização voltada a pessoas com deficiência, acho difícil usá-lo como referência.
  • Também é possível implementar efeitos interativos assim sem JS (página de exemplo).

      • Animação de confete caindo
      • Janela de notificação com botão de fechar
      • Ao fechar a notificação, o confete também desaparece
      • Também há comportamento de abas (mas, nesse exemplo, exige recarregamento do servidor)
      • Se adicionar JS, a animação fica mais suave e mais rica
  • Como desenvolvedor web há 10 anos, sinto que textos assim precisam sacudir nossas certezas. O título não é dos melhores, então quase deixei passar. Só para constar: não dá para renderizar mapas apenas com CSS.

    • Com CSS+SVG dá para renderizar mapas. Claro, recursos adicionais como navegação precisariam ser implementados separadamente.
  • Pode haver preconceito por causa do nome Vega, mas eu realmente gosto deste site. O design geral é ótimo, e o conteúdo desta página também é excelente. Vou certamente compartilhar este link com pessoas que desenvolvem para a web no futuro. Também gosto muito de arrupted, que já produziu coisas incríveis antes, então foi bom ver esse domínio familiar aparecendo na página principal desta vez.