Estilo da Web de última geração

Fique por dentro de alguns dos recursos incríveis do CSS moderno.

toneladas de coisas interessantes acontecendo no CSS neste momento, e muitos deles já são compatíveis com os navegadores de hoje. Nossa palestra na CDS 2019, que você pode assistir abaixo, aborda vários recursos novos e futuros que achamos que deveriam chamar atenção.

Esta postagem se concentra nos recursos que você pode usar atualmente, então não deixe de assistir para uma discussão mais profunda sobre os próximos recursos, como o Houdini. Você também pode encontrar demonstrações de todos os recursos discutidos em nossa Página CSS@CDS.

Índice

Ajuste de rolagem

Ajuste de rolagem: permite definir pontos de ajuste conforme o usuário rola o conteúdo na vertical, na horizontal ou em ambos. Ele tem inércia e desaceleração de rolagem integradas, além de ter o toque ativado.

Este exemplo de código configura a rolagem horizontal em um elemento <section> com pontos de ajuste alinhados aos lados esquerdos dos elementos filhos <picture>:

section {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
}

section > picture {
  scroll-snap-align: start;
}

Veja como funciona:

  • No elemento <section> pai,
    • overflow-x está definido como auto para permitir a rolagem horizontal.
    • overscroll-behavior-x é definido como contain para evitar que qualquer elemento pai role quando o usuário atingir os limites da área de rolagem do elemento <section>. Isso não é estritamente necessário para a segmentação, mas é geralmente uma boa ideia.
    • scroll-snap-type é definido como x (para ajuste horizontal) e mandatory, para garantir que a janela de visualização sempre se ajuste ao ponto de ajuste mais próximo.
  • Nos elementos filhos <picture>, scroll-snap-align é definido para começar, o que define os pontos de ajuste no lado esquerdo de cada imagem (supondo que direction esteja definido como ltr).

E aqui está uma demonstração ao vivo:

Também é possível conferir as demonstrações de ajuste de rolagem vertical e ajuste de rolagem da matriz.

:focus-within

O :focus-within resolve um problema de acessibilidade de longa data: há muitos casos em que o foco em um elemento filho precisa afetar a apresentação de um elemento pai para que a interface fique acessível a usuários de tecnologias adaptativas.

Por exemplo, se você tiver um menu suspenso com vários itens, ele vai permanecer visível enquanto qualquer um deles estiver em foco. Caso contrário, o menu desaparecerá para os usuários do teclado.

:focus-within instrui o navegador a aplicar um estilo quando o foco está em qualquer elemento filho de um elemento especificado. Voltando ao exemplo do menu, definindo :focus-within no elemento do menu, você pode garantir que ele permaneça visível quando um item de menu estiver em foco:

.menu:focus-within {
  display: block;
  opacity: 1;
  visibility: visible;
}

Uma ilustração que mostra a diferença de comportamento entre foco e foco interno.

Navegue pelos elementos focalizáveis na demonstração abaixo. Você notará que os menus permanecem visíveis quando focar nos itens de menu:

Consultas de mídia nível 5

As novas consultas de mídia oferecem maneiras poderosas de ajustar a experiência do usuário nos nossos apps com base nas preferências do dispositivo do usuário. Basicamente, o navegador serve como um proxy para preferências no nível do sistema que podemos responder no nosso CSS usando o grupo prefers-* de consultas de mídia:

Um diagrama que mostra consultas de mídia interpretando as preferências do usuário no nível do sistema.

Estas são as novas consultas que os desenvolvedores vão gostar mais:

Essas consultas são uma grande conquista para a acessibilidade. Anteriormente, não tínhamos como saber, por exemplo, se um usuário havia definido o SO para o modo de alto contraste. Se você quisesse fornecer um modo de alto contraste para um aplicativo da web que permanecesse fiel à sua marca, você tinha que pedir aos usuários para escolhê-lo na interface do seu aplicativo. Agora você pode detectar a configuração de alto contraste do SO usando prefers-contrast.

Uma implicação empolgante dessas consultas de mídia é que podemos projetar várias combinações de preferências do usuário no nível do sistema para acomodar a ampla gama de preferências do usuário e necessidades de acessibilidade. Se um usuário quiser o modo escuro de alto contraste em ambientes com pouca iluminação, você pode fazer isso.

É importante para Adam que "prefere movimento reduzido" não seja implementada como "sem movimento". O usuário está dizendo que prefere menos movimento, não que não quer nenhuma animação. Ele afirma que movimento reduzido não é nenhum movimento. Confira um exemplo que usa uma animação de crossfade quando o usuário prefere movimento reduzido:

Propriedades lógicas

As propriedades lógicas resolvem um problema que ganha visibilidade à medida que mais desenvolvedores abordam a internacionalização. Muitas propriedades de layout, como margin e padding, pressupõem um idioma que é lido de cima para baixo e da esquerda para a direita.

Um diagrama mostrando as propriedades de layout CSS tradicionais.

Ao projetar páginas para vários idiomas com modos de escrita variados, os desenvolvedores precisavam ajustar todas essas propriedades individualmente em vários elementos, o que rapidamente se tornou um pesadelo em termos de manutenção.

As propriedades lógicas permitem manter a integridade do layout em todos os modos de tradução e escrita. Eles são atualizados dinamicamente com base na ordem semântica do conteúdo, e não na organização espacial. Com propriedades lógicas, cada elemento tem duas dimensões:

  • A dimensão block é perpendicular ao fluxo de texto em uma linha. Em inglês, block-size é o mesmo que height.
  • A dimensão inline é paralela ao fluxo do texto em uma linha. Em inglês, inline-size é o mesmo que width.

Esses nomes de dimensões se aplicam a todas as propriedades de layout lógico. Por exemplo, em inglês, block-start é igual a top e inline-end é igual a right.

Um diagrama mostrando as novas propriedades de layout lógico de CSS.

Com propriedades lógicas, você pode atualizar automaticamente o layout para outros idiomas mudando as propriedades writing-mode e direction da página em vez de atualizar dezenas de propriedades de layout em elementos individuais.

É possível ver como as propriedades lógicas funcionam na demonstração abaixo definindo a propriedade writing-mode no elemento <body> com valores diferentes:

position: sticky

Um elemento com position: sticky permanece no fluxo de blocos até começar a sair da tela. e parará de rolar com o resto da página. e permanece na posição especificada pelo valor top do elemento. O espaço alocado para esse elemento permanece no fluxo, e o elemento retorna a ele quando o usuário rola de volta para cima.

O posicionamento fixo permite criar muitos efeitos úteis que anteriormente exigiam JavaScript. Para mostrar algumas das possibilidades, criamos várias demonstrações. Cada demonstração usa basicamente o mesmo CSS e só faz pequenos ajustes na marcação HTML para criar cada efeito.

Pilha fixa

Nesta demonstração, todos os elementos fixos compartilham o mesmo contêiner. Isso significa que cada elemento fixo desliza sobre o anterior conforme o usuário rola para baixo. Os elementos fixos compartilham a mesma posição de fixação.

Slide fixo

Aqui, os elementos aderentes são primos. Ou seja, seus pais são irmãos. Quando um elemento fixo atinge o limite inferior do contêiner, ele se move para cima com o contêiner, criando a impressão de que os elementos fixos mais baixos estão empurrando os elementos mais altos para cima. Em outras palavras, eles parecem competir pela posição presa.

Desperado pegajoso

Assim como o slide aderente, os elementos fixos nesta demonstração são primos. No entanto, eles foram colocados em contêineres definidos para um layout de grade de duas colunas.

backdrop-filter

A propriedade backdrop-filter permite aplicar efeitos gráficos à área atrás de um elemento, e não ao próprio elemento. Isso gera muitos efeitos interessantes que antes só eram conseguidos com truques complicados de CSS e JavaScript usando uma única linha de CSS.

Por exemplo, esta demonstração usa backdrop-filter para o desfoque no estilo do SO:

Já temos uma ótima postagem sobre backdrop-filter, então acesse para saber mais.

:is()

Embora a pseudoclasse :is() tenha mais de 10 anos, ela ainda não recebe tanto uso quanto achamos que merece. Ele usa uma lista separada por vírgulas de seletores como argumento e corresponde a todos os seletores dessa lista. Essa flexibilidade torna esse recurso incrivelmente útil e pode reduzir significativamente a quantidade de CSS que você envia.

Veja um exemplo rápido:

button.focus,
button:focus {
  
}

article > h1,
article > h2,
article > h3,
article > h4,
article > h5,
article > h6 {
  
}

/* selects the same elements as the code above */
button:is(.focus, :focus) {
  
}

article > :is(h1,h2,h3,h4,h5,h6) {
  
}

gap

Há algum tempo, o layout de grade CSS teve o gap (anteriormente grid-gap). Ao especificar o espaçamento interno de um elemento contêiner em vez do espaçamento ao redor de elementos filhos, o gap resolve muitos problemas comuns de layout. Por exemplo, com a lacuna, você não precisa se preocupar com margens em elementos filhos causando espaços em branco indesejados ao redor das bordas de um elemento contêiner:

Ilustração mostrando como a propriedade de lacuna evita o espaçamento não intencional ao redor das bordas de um elemento de contêiner.

Uma notícia ainda melhor: o gap está chegando ao flexbox, com os mesmos benefícios de espaçamento da grade:

  • Há uma declaração de espaçamento em vez de várias.
  • Não é necessário estabelecer convenções para seu projeto sobre quais elementos filhos devem ter o espaçamento; o elemento que os contém é o proprietário do espaçamento.
  • O código é mais fácil de entender do que estratégias mais antigas, como a coruja lobotomizada.

O vídeo abaixo mostra os benefícios de usar uma única propriedade gap para dois elementos, um com layout de grade e outro com layout flexível:

No momento, apenas o FireFox oferece suporte a gap em layouts flexíveis, mas confira esta demonstração para ver como ele funciona:

CSS Houdini

O Houdini é um conjunto de APIs de baixo nível para o mecanismo de renderização do navegador que permite instruir o navegador a interpretar o CSS personalizado. Em outras palavras, você tem acesso ao modelo de objetos CSS, o que permite estender o CSS via JavaScript. Essa mudança gera vários benefícios:

  • Com ela, você tem muito mais poder para criar recursos CSS personalizados.
  • É mais fácil separar as preocupações de renderização da lógica do aplicativo.
  • É melhor do que o polyfilling CSS que fazemos atualmente com JavaScript, já que o navegador não terá mais que analisar scripts e fazer um segundo ciclo de renderização. O código Houdini é analisado no primeiro ciclo de renderização.

Ilustração mostrando como a Houdini funciona em comparação com os polyfills tradicionais do JavaScript.

Houdini é um nome abrangente para várias APIs. Para saber mais sobre ela e o status atual dela, consulte Is Houdini Ready Yet? (em inglês) Em nossa conversa, abordamos a API Properties e Values, a API Paint e o Worklet de animação porque elas são as mais compatíveis no momento. Poderíamos facilmente dedicar uma postagem completa a cada uma dessas APIs incríveis, mas, por enquanto, confira nossa palestra para ter uma visão geral e algumas demonstrações interessantes que começam a dar uma noção do que você pode fazer com as APIs.

Menu flutuante

Há mais alguns tópicos que gostaríamos de discutir, mas não tivemos tempo de abordar em mais detalhes. Por isso, conferimos rapidamente todos eles. ⚡ Se você ainda não conhece alguns desses recursos, assista a última parte da palestra.

  • size: uma propriedade que permite definir altura e largura ao mesmo tempo.
  • aspect-ratio: uma propriedade que define uma proporção para elementos que não têm uma.
  • min(), max() e clamp(): funções que permitem definir restrições numéricas em qualquer propriedade CSS, não apenas de largura e altura.
  • list-style-type é uma propriedade existente, mas em breve vai ser compatível com uma variedade maior de valores, incluindo emojis e SVGs.
  • display: outer inner: em breve, a propriedade display aceitará dois parâmetros, o que permitirá especificar explicitamente os layouts interno e externo em vez de usar palavras-chave compostas, como inline-flex.
  • Regiões do CSS: permitem preencher uma área especificada e não retangular na qual o conteúdo pode entrar e sair
  • Módulos CSS: o JavaScript poderá solicitar um módulo CSS e recuperar um objeto avançado, facilitando a realização de operações no