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 atualmente, e muitas delas já são compatíveis com os navegadores de hoje. Nossa palestra na CDS 2019, que pode ser assistida abaixo, aborda vários recursos novos e futuros que podem ser interessantes para você.

Esta postagem se concentra nos recursos que você pode usar atualmente, então assista à palestra para ver mais detalhes sobre os próximos recursos, como o Houdini. Também é possível encontrar demonstrações de todos os recursos discutidos na página CSS@CDS.

Conteúdo

Ajustar a rolagem

O Ajuste de rolagem permite definir pontos de ajuste conforme o usuário rola o conteúdo verticalmente, horizontalmente ou ambos. Ele tem inércia e desaceleração de rolagem integradas, além de ser ativado por toque.

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

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,
    • A overflow-x está definida como auto para permitir a rolagem horizontal.
    • overscroll-behavior-x é definido como contain para evitar que qualquer elemento pai seja rolado quando o usuário atingir os limites da área de rolagem do elemento <section>. Isso não é estritamente necessário para o ajuste, 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 encaixe no ponto de ajuste mais próximo.
  • Nos elementos <picture> filhos, a scroll-snap-align é definida para iniciar, 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:

Você também pode dar uma olhada nas demonstrações do ajuste de rolagem vertical e do ajuste de rolagem da matriz.

:focus-within

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

Por exemplo, se você tem um menu suspenso com vários itens, ele precisa permanecer visível enquanto qualquer um dos itens estiver em foco. Caso contrário, o menu desaparecerá para 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 de menu, você pode garantir que ele permaneça visível quando um item do menu estiver em foco:

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

Ilustração mostrando a diferença de comportamento entre foco e foco interno.

Tente percorrer os elementos focalizáveis na demonstração abaixo. Você notará que os menus permanecem visíveis quando você se concentra nos itens de menu:

Consultas de mídia nível 5

As novas consultas de mídia nos oferecem maneiras eficazes 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 das preferências no nível do sistema a que podemos responder no CSS usando o grupo prefers-* de consultas de mídia:

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

Confira as novas consultas que vão deixar os desenvolvedores mais animados:

Essas consultas são um grande benefício para a acessibilidade. Antes não era possível saber, por exemplo, que um usuário tinha configurado o SO para o modo de alto contraste. Se você quisesse fornecer um modo de alto contraste para um app da Web que permanecesse fiel à sua marca, era necessário pedir aos usuários para escolhê-lo na interface do seu app. Agora você pode detectar a configuração de alto contraste do SO usando prefers-contrast.

Uma implicação interessante dessas consultas de mídia é que podemos projetar várias combinações de preferências do usuário em nível de 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 implementado 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 significa que há movimento. Aqui está um exemplo que usa uma animação de fading cruzado quando o usuário prefere movimento reduzido:

Propriedades lógicas

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

Diagrama mostrando as propriedades de layout CSS tradicional.

Ao criar páginas para vários idiomas com diferentes modos de escrita, os desenvolvedores tiveram que ajustar todas essas propriedades individualmente em vários elementos, o que rapidamente se torna um pesadelo de manutenção.

As propriedades lógicas permitem manter a integridade do layout nos 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 in-line é paralela ao fluxo de texto em uma linha. Em inglês, inline-size é o mesmo que width.

Esses nomes de dimensão 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 novas propriedades de layout lógico CSS.

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

Confira 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. Nesse momento, ele para de rolar com o restante 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 para cima.

O posicionamento fixo permite criar muitos efeitos úteis que antes precisavam do JavaScript. Para mostrar algumas das possibilidades, criamos várias demonstrações. Cada demonstração usa basicamente o mesmo CSS e ajusta apenas um pouco a 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 à medida que o usuário rola para baixo. Os elementos fixos compartilham a mesma posição presa.

Slide fixo

Aqui, os elementos aderentes são os primos. Ou seja, os 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 mais altos. Em outras palavras, eles parecem competir pela posição travada.

Sticky Desperado (link em inglês)

Como o Sticky Slide, os elementos fixos nesta demonstração são os primos. No entanto, eles foram colocados em contêineres definidos com 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ó podiam ser alcançados usando invasões complicadas de CSS e JavaScript com uma linha de CSS.

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

Já temos uma ótima postagem sobre backdrop-filter. Acesse essa página para saber mais.

:is()

Embora a pseudoclasse :is() tenha mais de dez anos, ela ainda não tem tanto uso quanto achamos que merece. Ela usa uma lista de seletores separados por vírgulas como argumento e corresponde a todos os seletores nessa lista. Essa flexibilidade torna o serviço 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

O layout de grade CSS usa gap (anteriormente grid-gap) há algum tempo. Ao especificar o espaçamento interno de um elemento contêiner em vez do espaçamento em torno de elementos filhos, o gap resolve muitos problemas comuns de layout. Por exemplo, com uma lacuna, você não precisa se preocupar com as margens nos elementos filhos que causam espaços em branco indesejados nas bordas de um elemento contêiner:

Ilustração mostrando como a propriedade &quot;gap&quot; evita 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, trazendo os mesmos benefícios de espaçamento que a grade oferece:

  • Há uma declaração de espaçamento em vez de muitas.
  • Não é necessário estabelecer convenções para o projeto sobre quais elementos filhos devem ter o espaçamento adequado. Em vez disso, o elemento contêiner é proprietário do espaçamento.
  • O código é mais fácil de entender do que estratégias mais antigas, como a coruja lobotomizada (link em inglês).

O vídeo a seguir 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, somente o FireFox oferece suporte a gap em layouts flexíveis, mas confira esta demonstração para ver como funciona:

CSS Houdini

Houdini é um conjunto de APIs de baixo nível para o mecanismo de renderização do navegador que permite informar ao navegador como interpretar a CSS personalizada. Em outras palavras, ela dá acesso ao modelo de objeto CSS, permitindo que você estenda 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.
  • É mais eficiente do que o polyfill de CSS que fazemos atualmente com JavaScript, já que o navegador não vai mais precisar 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 o Houdini funciona em comparação com polyfills de JavaScript tradicionais.

Houdini é um nome abrangente para várias APIs. Se quiser mais informações sobre eles e o status atual deles, consulte Is Houdini Ready ainda?. Na nossa conversa, abordamos a API Properties and Values, a API Paint e o Worklet Animation porque são os mais com suporte no momento. Podemos facilmente dedicar uma postagem completa a cada uma dessas APIs interessantes, mas, por enquanto, confira nossa palestra para 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

Ainda há mais algumas coisas que queríamos discutir, mas não tivemos tempo de abordar isso em detalhes. Por isso, explicamos cada uma delas em uma rodada rápida. Dica Se você ainda não ouviu falar de alguns desses recursos, assista a última parte da palestra.

  • size: uma propriedade que permite definir a altura e a largura ao mesmo tempo.
  • aspect-ratio: uma propriedade que define uma proporção para elementos que não têm um intrinsecamente
  • min(), max() e clamp(): funções que permitem definir restrições numéricas em qualquer propriedade CSS, não apenas na largura e altura.
  • list-style-type uma propriedade, mas em breve ela vai oferecer suporte a uma variedade maior de valores, incluindo emojis e SVGs.
  • display: outer inner: em breve, a propriedade display vai aceitar dois parâmetros, o que permite especificar explicitamente os layouts externo e interno em vez de usar palavras-chave compostas, como inline-flex.
  • Regiões CSS: permitem preencher uma área não retangular especificada, da 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 que facilita a realização de operações em