Os últimos meses foram uma época de ouro para a interface da Web. Os novos recursos da plataforma foram lançados com a adoção de vários navegadores que oferecem suporte a mais recursos da Web e de personalização do que nunca.
Confira 20 dos recursos mais interessantes e impactantes que foram lançados recentemente ou serão lançados em breve:
- Consultas de contêiner
- Consultas de estilo
- Seletor
:has()
- Microsintaxe nth-of
text-wrap: balance
initial-letter
- Unidades dinâmicas da janela de visualização
- Espaços de cor de ampla gama
color-mix()
- Aninhamento
- Camadas em cascata
- Estilos com escopo
- Funções trigonométricas
- Propriedades de transformação individuais
- Popover
- Posicionamento de âncora
- selectmenu
- Transições de propriedades discretas
- Animações de rolagem
- Visualizar transições
O novo responsivo
Vamos começar com alguns novos recursos de design responsivo. Os novos recursos da plataforma permitem criar interfaces lógicas com componentes que têm as próprias informações de estilo responsivo, criar interfaces que aproveitam os recursos do sistema para oferecer interfaces com uma sensação mais nativa e permitir que o usuário faça parte do processo de design com consultas de preferências do usuário para personalização completa.
Consultas em contêiner
As consultas de contêiner recentemente se tornaram estáveis em todos os navegadores modernos. Eles permitem que você consulte o tamanho e o estilo de um elemento pai para determinar os estilos que devem ser aplicados a qualquer um dos filhos. As consultas de mídia só podem acessar e aproveitar informações da janela de visualização. Isso significa que elas só funcionam em uma visualização macro de um layout de página. As consultas de contêiner, por outro lado, são uma ferramenta mais precisa que pode ser usada com qualquer número de layouts ou layouts dentro de layouts.
No exemplo da caixa de entrada a seguir, a Caixa de entrada principal e a barra lateral Favoritos são contêineres. Os e-mails neles ajustam o layout de grade e mostram ou ocultam o carimbo de data/hora com base no espaço disponível. Esse é o mesmo componente na página, mas aparece em visualizações diferentes.
Como temos uma consulta de contêiner, os estilos desses componentes são dinâmicos. Se você ajustar o tamanho e o layout da página, os componentes vão responder ao espaço alocado individualmente. A barra lateral se torna uma barra superior com mais espaço, e o layout se parece mais com a caixa de entrada principal. Quando há menos espaço, os dois são mostrados em um formato condensado.
Saiba mais sobre consultas de contêineres e como criar componentes lógicos nesta postagem.
Consultas de estilo
A especificação de consulta do contêiner também permite consultar os valores de estilo de um contêiner pai. No momento, isso está parcialmente implementado no Chrome 111, em que é possível usar propriedades personalizadas de CSS para aplicar estilos de contêiner.
O exemplo a seguir usa características climáticas armazenadas em valores de propriedades personalizados, como chuva, ensolarado e nublado, para estilizar o plano de fundo e o ícone indicador do card.
@container style(--sunny: true) {
.weather-card {
background: linear-gradient(-30deg, yellow, orange);
}
.weather-card:after {
content: url(<data-uri-for-demo-brevity>);
background: gold;
}
}
Isso é apenas o começo das consultas de estilo. No futuro, vamos ter consultas booleanas para determinar se um valor de propriedade personalizada existe e reduzir a repetição de código. No momento, estamos discutindo consultas de intervalo para aplicar estilos com base em um intervalo de valores. Dessa forma, é possível aplicar os estilos mostrados aqui usando um valor percentual para a chance de chuva ou nuvens.
Saiba mais e veja mais demonstrações na nossa postagem do blog sobre consultas de estilo.
:has()
Falando em recursos dinâmicos e poderosos, o seletor :has() é um dos novos recursos de CSS mais poderosos que chegam aos navegadores modernos. Com a :has()
, é possível aplicar estilos verificando se um elemento pai contém a presença de filhos específicos ou se eles estão em um estado específico. Isso significa que agora temos um seletor pai.
Com base no exemplo de consulta de contêiner, você pode usar :has()
para tornar os componentes ainda mais dinâmicos. Nele, um item com um elemento "estrela" recebe um plano de fundo cinza, e um plano de fundo azul para um item com uma caixa de seleção marcada.
No entanto, essa API não é limitada à seleção de pais. Também é possível estilizar qualquer elemento filho dentro do elemento pai. Por exemplo, o título é em negrito quando o item tem o elemento de estrela presente. Isso é feito com .item:has(.star) .title
. O uso do seletor :has()
dá acesso a elementos pais, filhos e até mesmo irmãos, tornando essa uma API muito flexível, com novos casos de uso surgindo todos os dias.
Para saber mais e conferir mais demonstrações, acesse esta postagem do blog sobre :has()
.
Sintaxe de nth-of
Compatibilidade com navegadores
A plataforma da Web agora tem uma seleção de n-filho mais avançada. A sintaxe avançada de n-ésima criança fornece uma nova palavra-chave ("de"), que permite usar a microsintaxe de An+B, com um subconjunto mais específico para pesquisar.
Se você usar um filho n-ésimo regular, como :nth-child(2)
na classe especial, o navegador vai selecionar o elemento que tem a classe especial aplicada e também é o segundo filho. Isso é diferente de :nth-child(2 of .special)
, que primeiro pré-filtra todos os elementos .special
e depois escolhe o segundo da lista.
Saiba mais sobre esse recurso no artigo sobre sintaxe de nth-of.
text-wrap: balance
Os seletores e as consultas de estilo não são os únicos lugares em que podemos incorporar lógica aos nossos estilos. A tipografia também é um deles. No Chrome 114 e versões mais recentes, é possível usar o balanceamento de texto para títulos usando a propriedade text-wrap
com o valor balance
.
Para equilibrar o texto, o navegador realiza uma busca binária pela menor largura, sem a criação de linhas adicionais, parando em um pixel CSS (não um pixel de exibição). Para minimizar ainda mais as etapas na pesquisa binária, o navegador começa com 80% da largura média da linha.
Saiba mais neste artigo.
initial-letter
Outra melhoria legal na tipografia da Web é a initial-letter
. Essa propriedade CSS oferece melhor controle para o estilo do limite de queda.
Você usa initial-letter
no pseudoelemento :first-letter
para especificar:
o tamanho da letra com base em quantas linhas ela ocupa.
O deslocamento de bloco, ou "coletor", da letra para onde a letra ficará.
Saiba mais sobre como usar o intial-letter
neste link.
Unidades dinâmicas da janela de visualização
Compatibilidade com navegadores
Um problema comum enfrentado pelos desenvolvedores da Web hoje é o dimensionamento preciso e consistente do viewport completo, especialmente em dispositivos móveis. Como desenvolvedor, você quer que 100vh
(100% da altura da janela de visualização) signifique "ser do tamanho da janela de visualização", mas a unidade vh
não considera coisas como barras de navegação retráteis em dispositivos móveis. Por isso, às vezes, ela acaba sendo muito longa e causa rolagem.
Para resolver esse problema, agora temos novos valores de unidade na plataforma da Web, incluindo:
- Altura e largura pequenas da janela de visualização (ou svh
e svw
), que representam o menor tamanho da janela de visualização ativa.
- Altura e largura de janela de visualização grande (lvh
e lvw
), que representam o tamanho maior.
- Altura e largura dinâmicas da janela de visualização (dvh
e dvw
).
As unidades de visualização dinâmica mudam de valor quando as barras de ferramentas dinâmicas adicionais do navegador, como o endereço na parte de cima ou a barra de guias na parte de baixo, estão visíveis ou não.
Para mais informações sobre essas novas unidades, leia As unidades de viewport grandes, pequenas e dinâmicas.
Espaços de cor com ampla gama
Outra novidade importante da plataforma da Web são os espaços de cores da ampla gama. Antes que a ampla gama de cores ficasse disponível na plataforma da Web, era possível tirar uma foto com cores vivas, que podia ser visualizada em dispositivos modernos, mas não era possível usar um botão, cor de texto ou plano de fundo que combinasse com esses valores.
Mas agora temos uma variedade de novos espaços de cores na plataforma da Web, incluindo REC2020, P3, XYZ, LAB, OKLAB, LCH e OKLCH. Conheça os novos espaços de cores da Web e muito mais na Guia de cores em alta definição.
E você pode ver imediatamente no DevTools como o intervalo de cores foi expandido, com essa linha branca delineando onde o intervalo de sRGB termina e onde começa o intervalo de cores da gama mais ampla.
Muitas ferramentas disponíveis para cores! Não perca todas as melhorias de gradiente. Há até uma nova ferramenta criada por Adam Argyle para ajudar você a testar um novo seletor de cores da Web e um criador de gradientes. Confira em gradient.style.
color-mix()
A função color-mix()
se expande nos espaços de cor expandidos. Esta função suporta a mistura de dois valores de cor para criar novos valores com base nos canais das cores sendo misturadas. O espaço de cores em que você mistura afeta os resultados. Trabalhar em um espaço de cores mais perceptivo, como o oklch, passará por um intervalo de cores diferente de algo como srgb.
color-mix(in srgb, blue, white);
color-mix(in srgb-linear, blue, white);
color-mix(in lch, blue, white);
color-mix(in oklch, blue, white);
color-mix(in lab, blue, white);
color-mix(in oklab, blue, white);
color-mix(in xyz, blue, white);
A função color-mix()
fornece um recurso solicitado há muito tempo: a capacidade de preservar valores de cores opacas e, ao mesmo tempo, adicionar um pouco de transparência a eles. Agora, você pode usar as variáveis de cor da marca ao criar variações dessas cores em diferentes opacidades. Para fazer isso, misture uma cor com transparência. Ao misturar a cor azul com 10% de transparência, você obtém uma cor de marca 90% opaca. Você pode ver como isso permite construir rapidamente sistemas de cores.
Você pode ver isso em ação no Chrome DevTools hoje com um bom ícone do diagrama de Venn de visualização no painel de estilos.
Confira mais exemplos e detalhes na nossa postagem do blog sobre a função color-mix ou teste este playground da função color-mix().
Fundamentos do CSS
Criar novos recursos que tragam benefícios claros para os usuários é uma parte da equação, mas muitos dos recursos do Chrome têm como objetivo melhorar a experiência do desenvolvedor e criar uma arquitetura CSS mais confiável e organizada. Esses recursos incluem anilhamento de CSS, camadas em cascata, estilos de escopo, funções trigonométricas e propriedades de transformação individuais.
Aninhamento
O aninhamento de CSS, algo que as pessoas adoram no Sass e uma das principais solicitações de desenvolvedores de CSS por anos, finalmente chegou à plataforma da Web. A Transição permite que os desenvolvedores escrevam em um formato mais sucinto e agrupado que reduz a redundância.
.card {}
.card:hover {}
/* can be done with nesting like */
.card {
&:hover {
}
}
Também é possível aninhar Consultas de mídia, o que também significa que é possível aninhar Consultas de contêiner. No exemplo a seguir, um card mudará de um layout de retrato para um layout de paisagem se houver largura suficiente no contêiner:
.card {
display: grid;
gap: 1rem;
@container (width >= 480px) {
display: flex;
}
}
O ajuste de layout para flex
ocorre quando o contêiner tem mais (ou igual a) 480px
de espaço inline disponível. O navegador simplesmente vai aplicar esse novo estilo de exibição quando as condições forem atendidas.
Para mais informações e exemplos, confira nossa postagem sobre anilhamento de CSS.
Camadas em cascata
Outro ponto problemático que identificamos é garantir a consistência de quais estilos vencem os outros. Uma parte da solução é ter um melhor controle sobre a hierarquia do CSS.
As camadas em cascata resolvem isso dando aos usuários o controle sobre quais camadas têm precedência maior do que outras, o que significa um controle mais preciso de quando seus estilos são aplicados.
Saiba mais sobre como usar camadas em cascata neste artigo.
CSS com escopo
Os estilos com escopo do CSS permitem que os desenvolvedores especifiquem os limites para quais estilos específicos se aplicam, criando essencialmente um namespace nativo no CSS. Antes, os desenvolvedores dependiam de scripts de terceiros para renomear classes ou de convenções de nomenclatura específicas para evitar a colisão de estilos, mas em breve você poderá usar @scope
.
Aqui, estamos definindo o escopo de um elemento .title
para um .card
. Isso evita que esse elemento de título entre em conflito com qualquer outro elemento .title
na página, como o título de uma postagem de blog ou outro cabeçalho.
@scope (.card) {
.title {
font-weight: bold;
}
}
Você pode conferir @scope
com limites de escopo e @layer
nesta demonstração ao vivo:
Saiba mais sobre @scope
na especificação css-cascade-6.
Funções trigonométricas
Outra parte do novo CSS são as funções trigonométricas que foram adicionadas às funções matemáticas do CSS. Agora, essas funções são estáveis em todos os navegadores modernos e permitem criar layouts mais orgânicos na plataforma da Web. Um ótimo exemplo é este layout de menu radial, que agora pode ser projetado e animado usando as funções sin()
e cos()
.
Na demonstração abaixo, os pontos giram em torno de um ponto central. Em vez de girar cada ponto em torno do próprio centro e depois movê-lo para fora, cada ponto é traduzido nos eixos X e Y. As distâncias nos eixos X e Y são determinadas considerando o cos()
e, respectivamente, o sin()
do --angle
.
Consulte nosso artigo sobre funções trigonométricas para mais informações sobre esse tópico.
Propriedades de transformação individuais
A ergonomia do desenvolvedor continua a melhorar com funções de transformação individuais. Desde a última vez que realizamos E/S, as transformações individuais se tornaram estáveis em todos os navegadores modernos.
Antes, você usava a função de transformação para aplicar subfunções para dimensionar, girar e traduzir um elemento da interface. Isso envolveu muita repetição e foi especialmente frustrante ao aplicar várias transformações em momentos diferentes da animação.
.target {
transform: translateX(50%) rotate(30deg) scale(1.2);
}
.target:hover {
transform: translateX(50%) rotate(30deg) scale(2); /* Only scale changed here, yet you have to repeat all other parts */
}
Agora, você pode ter todos esses detalhes nas animações CSS separando os tipos de transformação e aplicando-os individualmente.
.target {
translate: 50% 0;
rotate: 30deg;
scale: 1.2;
}
.target:hover {
scale: 2;
}
Com isso, mudanças na translação, rotação ou escala podem acontecer simultaneamente em diferentes taxas de mudança em diferentes momentos durante a animação.
Leia esta postagem sobre funções de transformação individuais para mais informações.
Componentes personalizáveis
Para resolver algumas das principais necessidades dos desenvolvedores na plataforma da Web, estamos trabalhando com o grupo da comunidade OpenUI e identificamos três soluções para começar:
- Funcionalidade de pop-up integrada com manipuladores de eventos, uma estrutura DOM declarativa e padrões acessíveis.
- Uma API CSS para fazer o tethering de dois elementos entre si e permitir o posicionamento da âncora.
- Um componente de menu suspenso personalizável para quando você quiser estilizar o conteúdo dentro de uma seleção.
Pop-up
A API Popover oferece aos elementos alguns recursos integrados de suporte a navegadores, como:
- Compatibilidade com a camada superior, para que você não precise gerenciar
z-index
. Quando você abre um pop-up ou uma caixa de diálogo, está promovendo esse elemento para uma camada especial na parte superior da página. - Comportamento de dispensar o pop-up de forma simples sem custo financeiro em pop-ups
auto
. Assim, quando você clica fora de um elemento, o pop-over é dispensado, removido da árvore de acessibilidade e é selecionado de forma adequada. - Acessibilidade padrão para o tecido conjuntivo do destino do pop-up e o próprio pop-up.
Isso significa que é necessário escrever menos JavaScript para criar todas essas funcionalidades e acompanhar todos esses estados.
A estrutura DOM para pop-over é declarativa e pode ser escrita de forma tão clara quanto fornecer ao elemento pop-over um id
e o atributo popover
. Em seguida, sincronize esse ID com o elemento que abriria o pop-up, como um botão com o atributo popovertarget
:
<div id="event-popup" popover>
<!-- Popover content goes in here -–>
</div>
<button popovertarget="event-popup">Create New Event</button>
popover
é uma abreviação de popover=auto
. Um elemento com popover=auto
fechará outros pop-ups quando aberto, receberá o foco quando aberto e poderá ser dispensado. Por outro lado, os elementos popover=manual
não forçam o fechamento de nenhum outro tipo de elemento, não recebem foco imediatamente e não são dispensados. Eles são fechados com um botão de alternância ou outra ação de fechamento.
A documentação mais atualizada sobre popovers atualmente pode ser encontrada no MDN.
Posicionamento de âncora
Os pop-ups também são usados com frequência em elementos como caixas de diálogo e dicas, que geralmente precisam ser ancorados a elementos específicos. Veja este exemplo de evento. Quando você clica em um evento da agenda, uma caixa de diálogo aparece perto do evento. O item da agenda é a âncora, e o pop-up é a caixa de diálogo que mostra os detalhes do evento.
É possível criar uma dica de ferramenta centralizada com a função anchor()
, usando a largura da âncora para posicionar a dica de ferramenta a 50% da posição x da âncora. Em seguida, use os valores de posicionamento atuais para aplicar o restante dos estilos de posicionamento.
Mas o que acontece se o pop-up não couber na viewport com base na forma como você o posicionou?
Para resolver isso, a API de posicionamento da âncora inclui posições substitutas que podem ser personalizadas. O exemplo a seguir cria uma posição de substituição chamada "de cima para baixo". O navegador primeiro tenta posicionar a dica de ferramenta na parte de cima e, se ela não couber na janela de visualização, a posiciona abaixo do elemento de ancoragem, na parte de baixo.
.center-tooltip {
position-fallback: --top-then-bottom;
translate: -50% 0;
}
@position-fallback --top-then-bottom {
@try {
bottom: calc(anchor(top) + 0.5rem);
left: anchor(center);
}
@try {
top: calc(anchor(bottom) + 0.5rem);
left: anchor(center);
}
}
Saiba mais sobre o posicionamento de âncoras nesta postagem do blog.
<selectmenu>
Com o posicionamento de pop-up e âncora, é possível criar menus de seleção totalmente personalizáveis. O grupo da comunidade do OpenUI tem investigado a estrutura fundamental desses menus e procurado maneiras de permitir a personalização de qualquer conteúdo neles. Confira estes exemplos visuais:
Para criar o exemplo de selectmenu
mais à esquerda, com pontos coloridos correspondentes à cor que seria mostrada em um evento da agenda, você pode escrever da seguinte maneira:
<selectmenu>
<button slot="button" behavior="button">
<span>Select event type</span>
<span behavior="selected-value" slot="selected-value"></span>
<span><img src="icon.svg"/></span>
</button>
<option value="meeting">
<figure class="royalblue"></figure>
<p>Meeting</p>
</option>
<option value="break">
<figure class="gold"></figure>
<p>Lunch/Break</p>
</option>
...
</selectmenu>
Transições de propriedades discretas
Para que tudo isso faça a transição dos pop-ups de forma suave, a Web precisa de uma maneira de animar propriedades discretas. Essas são propriedades que normalmente não eram animadas no passado, como animações de e para a camada superior e animações de e para display: none
.
Como parte do trabalho para ativar transições legais para popovers, menus de seleção e até mesmo elementos existentes, como caixas de diálogo ou componentes personalizados, os navegadores estão ativando novos recursos para oferecer suporte a essas animações.
A demonstração de pop-up a seguir anima a entrada e a saída de pop-ups usando :popover-open
para o estado aberto, @starting-style
para o estado antes de abrir e aplica um valor de transformação ao elemento diretamente para o estado após a abertura. Para que tudo funcione com a tela, é necessário adicionar à propriedade transition
, como esta:
.settings-popover {
&:popover-open {
/* 0. before-change */
@starting-style {
transform: translateY(20px);
opacity: 0;
}
/* 1. open (changed) state */
transform: translateY(0);
opacity: 1;
}
/* 2. After-change state */
transform: translateY(-50px);
opacity: 0;
/* enumarate transitioning properties, including display */
transition: transform 0.5s, opacity 0.5s, display 0.5s allow-discrete;
}
Interações
E agora vamos falar sobre interações, a última parada neste tour pelos recursos da interface da Web.
Já falamos sobre a animação de propriedades discretas, mas também há algumas APIs muito interessantes no Chrome relacionadas a animações com rolagem e transições de visualização.
Animações de rolagem
Animações de rolagem permitem que você controle a reprodução de uma animação com base na posição de rolagem de um contêiner de rolagem. Isso significa que, conforme você rola para cima ou para baixo, a animação vai para frente ou para trás. Além disso, com as animações de rolagem, você também pode controlar uma animação de acordo com a posição de um elemento dentro do seu contêiner de rolagem. Assim, você cria efeitos interessantes, como uma imagem de fundo com efeito paralaxe, barras de rolagem de progresso e imagens que se revelam à medida que aparecem.
Essa API oferece suporte a um conjunto de classes JavaScript e propriedades CSS que permitem a fácil criação de animações declarativas de rolagem.
Para controlar uma animação CSS por rolagem, use as novas propriedades scroll-timeline
, view-timeline
e animation-timeline
.
Para direcionar uma API JavaScript Web Animations, transmita uma instância ScrollTimeline
ou ViewTimeline
como a opção timeline
para Element.animate()
Essas novas APIs funcionam em conjunto com as APIs de animações da Web e de animações com CSS, ou seja, elas se beneficiam das vantagens dessas APIs. Isso inclui a capacidade de executar essas animações fora da linha de execução principal. Sim, você leu certo: agora é possível ter animações suaves, controladas por rolagem, executadas fora da linha de execução principal, com apenas algumas linhas de código extra. Do que não gosta?!
Para um guia detalhado sobre como criar essas animações, consulte este artigo sobre animações movidas por rolagem.
Conferir transições
A API View Transition facilita a alteração do DOM em uma única etapa, criando uma transição animada entre os dois estados. Elas podem ser transições simples entre visualizações, mas você também pode controlar como as partes individuais da página devem fazer a transição.
As transições de visualização podem ser usadas como uma melhoria progressiva: inclua o código que atualiza o DOM de qualquer método e o encapsule na API de transição de visualização com um substituto para navegadores que não oferecem suporte ao recurso.
function spaNavigate(data) {
// Fallback for browsers that don't support this API:
if (!document.startViewTransition) {
updateTheDOMSomehow(data);
return;
}
// With a transition:
document.startViewTransition(() => updateTheDOMSomehow(data));
}
A transição é controlada via CSS
@keyframes slide-from-right {
from { opacity: 0; transform: translateX(75px); }
}
@keyframes slide-to-left {
to { opacity: 0; transform: translateX(-75px); }
}
::view-transition-old(root) {
animation: 350ms both slide-to-left ease;
}
::view-transition-new(root) {
animation: 350ms both slide-from-right ease;
}
Como demonstrado na demo incrível do Maxi Ferreira, outras interações da página, como a reprodução de vídeo, continuam funcionando enquanto uma transição de visualização está acontecendo.
As transições de visualização funcionam atualmente com apps de página única (SPAs) no Chrome 111. Estamos trabalhando no suporte a apps com várias páginas. Para mais informações, confira nosso guia completo de transições de visualização para guiar você por esse processo.
Conclusão
Fique por dentro das últimas páginas de destino em CSS e HTML aqui em developer.chrome.com e confira os vídeos da I/O para mais páginas da Web.