Criar interfaces adaptáveis ao usuário com consultas de mídia de preferência

1. Antes de começar

211ff61d01be58e.png

Atualmente, os usuários indicaram muitas preferências nos dispositivos. Eles querem que o sistema operacional e os apps se pareçam com os deles. As interfaces adaptáveis são aquelas que estão prontas para usar essas preferências para melhorar a experiência do usuário, fazendo com que ele se sinta mais em casa e com a cara dele. Se feito corretamente, um usuário pode nunca saber que a experiência do usuário está se adaptando ou se adaptou.

Preferências do usuário

A escolha do hardware do dispositivo é uma preferência, o sistema operacional é uma escolha, as cores do app e dos sistemas operacionais são as preferências e os idiomas dos documentos de apps e sistemas operacionais são as preferências. A quantidade de preferências de um usuário parece aumentar. Uma página da Web não pode acessar tudo, e por um bom motivo.

Veja alguns exemplos de preferências do usuário que podem ser usadas pelo CSS:

Confira alguns exemplos de preferências do usuário no CSS em breve:

Consultas de mídia

O CSS e a Web permitem adaptação e capacidade de resposta por meio de consultas de mídia, uma condição declarativa que contém um conjunto de estilos se essa condição for verdadeira. O mais comum é uma condição no tamanho da janela de visualização do dispositivo: se o tamanho for menor que 800 pixels, aqui estão alguns estilos melhores para esse caso.

Adaptável ao usuário

Uma interface não adaptável é aquela que não muda nada quando um usuário a visita, essencialmente oferecendo uma experiência para todos sem capacidade de ajuste. Uma interface adaptável ao usuário pode ter cinco aparências e estilos diferentes para cinco usuários diferentes. A funcionalidade é a mesma, mas a estética é percebida melhor e a usabilidade da interface é mais fácil para os usuários que podem ajustá-la.

Pré-requisitos

O que você vai criar

Neste codelab, você criará um formulário adaptável ao usuário que se adapta ao seguinte:

  • A preferência do esquema de cor do sistema, oferecendo um esquema de cores claras e escuras para os controles do formulário e os elementos de IU ao redor.
  • As preferências de movimento do sistema, oferecendo vários tipos de animações.
  • Janelas de visualização de dispositivos pequenos e grandes para oferecer experiências em dispositivos móveis e computadores
  • Vários tipos de entrada, como teclado, leitor de tela, toque e mouse
  • Qualquer idioma e modo de leitura/gravação

de5d580a5b8d3c3d.png

O que você vai aprender

Neste codelab, você vai aprender sobre recursos modernos da Web para criar um formulário adaptável ao usuário. Você vai aprender como:

  • Criar temas claros e escuros
  • Crie formulários animados e acessíveis
  • Layout de formulários responsivos
  • Use unidades relativas e propriedades lógicas

f142984770700a43.png

Este codelab é focado em interfaces adaptáveis do usuário. Conceitos e blocos de códigos sem relevância não serão abordados. Eles são incluídos somente para você copiar e colar.

O que é necessário

  • Google Chrome 89 ou mais recente ou o navegador de sua preferência

19e9b707348ace4c.png

2. Começar a configuração

Buscar o código

Tudo o que você precisa para este projeto está em um repositório do GitHub. Para começar, abra o código no seu ambiente de desenvolvedor favorito. Como alternativa, você pode bifurcar este Codepen e trabalhar a partir dele.

Recomendado: use o Codepen

  1. Abra uma nova guia do navegador.
  2. Acesse https://codepen.io/argyleink/pen/abBMeeq.
  3. Se não tiver uma conta, crie uma para salvar o trabalho.
  4. Clique em Bifurcar.

Alternativa: trabalhar localmente

Se quiser fazer o download do código e trabalhar localmente, será necessário ter o Node.js versão 12 ou superior e um editor de código configurado e pronto.

Usar o Git

  1. Acesse https://github.com/argyleink/Google-IO-2021-Workshop_User-Adaptive-Interfaces (em inglês).
  2. Clone o repositório em uma pasta.
  3. Observe que a ramificação padrão é beginning.

Usar arquivos

  1. Descompacte o arquivo ZIP salvo em uma pasta.

Executar o projeto

Use o diretório do projeto estabelecido em uma das etapas acima e:

  1. Execute npm install para instalar as dependências necessárias para executar o servidor.
  2. Execute npm start para iniciar o servidor na porta 3000.
  3. Abra uma nova guia do navegador.
  4. Acesse http://localhost:3000.

Sobre o HTML

Esta lição abordará os aspectos do HTML usado para dar suporte à interatividade adaptativa do usuário. Este workshop tem um foco específico no CSS. Vale a pena revisar o HTML fornecido se você for iniciante na criação de formulários ou sites. As escolhas de elementos HTML podem ser essenciais quando se trata de acessibilidade e layout.

Quando estiver tudo pronto para começar, você vai transformar esse esqueleto em uma experiência do usuário dinâmica e adaptável.

de5d580a5b8d3c3d.png

3. Interações adaptáveis

Ramificação Git: beginning

Ao final desta seção, o formulário de configurações vai se adaptar a:

  • Gamepad + teclado
  • Mouse + toque
  • Leitor de tela ou tecnologia assistiva semelhante

Atributos do HTML

O HTML fornecido no código-fonte é um ótimo ponto de partida, porque os elementos semânticos para ajudar a agrupar, ordenar e rotular as entradas de formulário já foram escolhidos.

Os formulários geralmente são um ponto de interação fundamental para uma empresa. Por isso, é importante que o formulário se adapte aos muitos tipos de entrada que a Web pode facilitar. Por exemplo, provavelmente é importante ter um formulário que possa ser usado em dispositivos móveis com toque. Nesta seção, antes do layout e do estilo, você garante a usabilidade da entrada adaptável.

Como agrupar entradas

O elemento <fieldset> no HTML serve para agrupar entradas e controles semelhantes. No formulário, você tem dois grupos, um para volume e outro para notificações. Isso é importante para a experiência do usuário, portanto seções inteiras podem ser ignoradas.

Como ordenar elementos

A ordem dos elementos é fornecida em uma ordem lógica. Isso é importante para a experiência do usuário, de modo que a ordem da experiência visual seja a mesma ou semelhante para tecnologias de gamepad, teclado ou leitor de tela.

Interação com o teclado

Os usuários da web se acostumaram a se mover pelos formulários com a tecla Tab. Felizmente, o navegador faz isso se você fornece os elementos HTML esperados. O uso de elementos como <button>, <input>, <h2> e <label> se torna automaticamente destinos de teclado ou leitor de tela.

9fc2218473eee194.gif

O vídeo acima demonstra como a tecla Tab e as setas podem se mover pela interface e fazer alterações. No entanto, o contorno azul fica muito apertado ao redor dos elementos de entrada. Adicione os estilos a seguir para que essa interação tenha um pouco de espaço.

style.css

input {
  outline-offset: 5px;
}

O que tentar

  1. Revise os elementos HTML usados em index.html.
  2. Clique na página de demonstração no seu navegador.
  3. Pressione a tecla tab e as teclas shift+tab para mover o foco do elemento pelo formulário.
  4. Use o teclado para alterar os valores dos controles deslizantes e das caixas de seleção.
  5. Conecte um controle de gamepad Bluetooth e mova o foco do elemento pelo formulário.

Interação com o mouse

Os usuários da web se acostumaram a interagir com formulários usando o mouse. Tente usar o mouse no formulário. Os controles deslizantes e as caixas de seleção funcionam, mas você pode fazer melhor. Essas caixas de seleção são bem pequenas para um clique do mouse.

ab51d0c0ee0d6898.gif

Percebeu como dois recursos de experiência do usuário podem conectar seus rótulos e as entradas deles.

O primeiro recurso é ter opções com as quais interagir, e o rótulo é muito mais fácil de segmentar para um mouse do que um pequeno quadrado.

O segundo atributo é saber exatamente para qual entrada um rótulo serve. Sem o CSS agora, é muito difícil determinar qual rótulo é para qual caixa de seleção, a menos que você forneça alguns atributos.

Essa conexão explícita também melhora a experiência dos leitores de tela, que serão abordados na próxima seção.

Unassociate:nenhum atributo conectando os elementos

<input type="checkbox">
<label>...</label>

Associado:atributos que conectam os elementos

<input type="checkbox" id="voice-notifications" name="voice-notifications">
<label for="voice-notifications">...</label>

O HTML fornecido já atribuiu todas as entradas e rótulos. Se esse for um conceito novo para você, vale a pena investigar mais.

O que tentar

  1. Passe o cursor sobre um marcador e observe as caixas de seleção destacadas.
  2. Investigue um elemento de rótulo com as Ferramentas para desenvolvedores do Chrome para visualizar a área da superfície clicável que pode marcar a caixa de seleção.

Interação com o leitor de tela

A tecnologia assistiva pode interagir com esse formulário e, com alguns atributos HTML, pode tornar a experiência do usuário mais suave.

28c4a14b892c62d0.gif

Para os usuários que navegam no formulário atual com um leitor de tela no Chrome, há uma parada desnecessária no elemento <picture> (não específico do Chrome). Um usuário com um leitor de tela provavelmente está usando o leitor de tela por causa de uma deficiência visual, então não é útil parar em uma imagem. É possível ocultar elementos dos leitores de tela com um atributo.

index.html

<picture aria-hidden="true">

Agora, os leitores de tela passam sobre o elemento que era puramente visual.

f269a73db943e48e.gif

O elemento do controle deslizante input[type="range"] tem um atributo ARIA especial: aria-labelledby="media-volume". Isso fornece instruções especiais para o leitor de tela usar a fim de aprimorar a experiência do usuário.

O que tentar

  1. Use a tecnologia de leitor de tela do seu sistema operacional para mover o foco pelo formulário.
  2. Faça o download e teste algum software leitor de tela no formulário.

4. Layouts adaptáveis

Ramificação Git: layouts

Ao final desta seção, a página de configurações vai fazer o seguinte:

  • Crie um sistema de espaços com propriedades personalizadas e unidades relativas ao usuário
  • Criar uma grade CSS para alinhamento e espaçamento flexíveis e responsivos
  • Usar propriedades lógicas para layouts internacionalmente adaptáveis
  • Escrever consultas de mídia para adaptar os layouts compactos e espaçosos

f142984770700a43.png

Espaçamento

O segredo para um bom layout é uma paleta limitada de opções de espaçamento. Isso ajuda o conteúdo a encontrar alinhamentos e harmonias naturais.

Propriedades personalizadas

Este workshop se baseia em um conjunto de sete tamanhos de propriedade personalizados.

  • Coloque estes itens na parte superior de style.css:

style.css

:root {
  --space-xxs: .25rem;
  --space-xs:  .5rem;
  --space-sm:  1rem;
  --space-md:  1.5rem;
  --space-lg:  2rem;
  --space-xl:  3rem;
  --space-xxl: 6rem;
}

A nomenclatura está próxima ao texto que as pessoas usariam uns com os outros para descrever o espaço. Você também usa unidades rem exclusivamente para um tamanho legível de unidade inteira que se adapta e considera a preferência do usuário.

Estilos de página

Em seguida, você precisa definir alguns estilos de documento, remover as margens dos elementos e definir a fonte para um bom Sans Serif.

  • Adicione o seguinte a style.css:

style.css

* {
  box-sizing: border-box;
  margin: 0;
}

html {
  block-size: 100%;
}

body {
  min-block-size: 100%;  
  padding-block-start: var(--space-xs);
  padding-block-end: var(--space-xs);
}

É o primeiro uso das propriedades personalizadas de espaçamento. Começamos sua jornada espacial.

Tipografia

A fonte desse layout é adaptável. A palavra-chave system-ui usará o que o sistema operacional do usuário tiver decidido ser a fonte de interface ideal.

body {
  font-family: system-ui, sans-serif;
}

h1,h2,h3 { 
  font-weight: 500;
}

small {
  line-height: 1.5;
}

Os estilos de h1, h2 e h3 são pequenos e estilísticos. No entanto, o elemento small precisa do line-height extra para quando o texto for ajustado. Está muito aglomerado.

Propriedades lógicas

Observe que padding em body está usando propriedades lógicas (block-start, block-end) para especificar o lado. As propriedades lógicas serão usadas extensivamente no restante do codelab. Eles também, como uma unidade rem, adaptam-se a um usuário. Esse layout pode ser traduzido para outro idioma e definido para a escrita natural e as direções do documento com que o usuário está acostumado no idioma nativo. As propriedades lógicas permitem isso com apenas uma definição de espaço, direção ou alinhamento.

ce5190e22d97156e.png

Grid e flexbox já são relativos a fluxo, o que significa que os estilos escritos para uma linguagem serão contextuais e aplicados adequadamente para outras. Direção adaptável fluxos de conteúdo em relação à direção do documento.

Com as propriedades lógicas, você pode alcançar mais usuários com menos estilos para escrever.

Layouts de grade CSS

A propriedade CSS grid é uma ferramenta de layout eficiente com muitos recursos para lidar com tarefas complexas. Você criará alguns layouts de grade simples e um layout complexo. Você também trabalhará de fora para dentro, de layouts macro a micro layouts. Suas propriedades personalizadas de espaçamento se tornarão essenciais não apenas como padding ou valores de margem, mas também tamanhos de colunas, raios de borda e muito mais.

Esta é uma captura de tela do Chrome DevTools sobrepondo cada layout de grade CSS ao mesmo tempo:

84e57c54d0633793.png

  1. Continue adicionando cada um dos seguintes estilos ao style.css:

<main>

main {
  display: grid;
  gap: var(--space-xl);
  place-content: center;
  padding: var(--space-sm);
}

Por padrão, a grade coloca cada elemento filho em sua própria linha, o que a torna ótima para empilhar elementos. Ele também tem a vantagem extra de usar gap. Anteriormente, você definiu margin: 0 em todos os elementos com o seletor *, que agora é importante ao usar gap para o espaçamento. A lacuna não é apenas um local único para gerenciar espaço em um contêiner, mas seu fluxo relativo.

&lt;form&gt;

form {
  max-width: 89vw;
  display: grid;
  gap: var(--space-xl) var(--space-xxl);
  align-items: flex-start;
  grid-template-columns: 
    repeat(auto-fit, minmax(min(10ch, 100%), 35ch));
}

Esse é o layout de grade mais complicado do design, mas considera o aspecto responsivo mais empolgante:

  • A max-width está fornecendo um valor para o algoritmo de layout usar ao decidir o tamanho dele.
  • gap está usando propriedades personalizadas e transmitindo um row-gap diferente do column-gap.
  • align-items está definido como flex-start para não esticar a altura dos itens.
  • grid-template-columns tem uma sintaxe complexa, mas a meta é sucinta. mantenha as colunas com largura de 35ch, nunca menos que 10ch e coloque tudo em colunas se houver espaço. Caso contrário, as linhas são válidas.
  1. Teste o redimensionamento do navegador. Observe como o formulário é recolhido para linhas em uma pequena janela de visualização, mas fluxo em novas colunas se houver espaço, adaptando-se sem consultas de mídia. Essa estratégia de estilos responsivos livres de consulta de mídia é particularmente útil para componentes ou layouts centrados em conteúdo.

<section>

section {
  display: grid;
  gap: var(--space-md);
}

Cada seção precisa ser uma grade de linhas com espaço médio entre os elementos filhos.

header {
  display: grid;
  gap: var(--space-xxs);
}

Cada cabeçalho precisa ser uma grade de linhas com um espaço extra extra muito pequeno entre os elementos filhos.

<fieldset>

fieldset {
  padding: 0;
  display: grid;
  gap: 1px;
  border-radius: var(--space-sm);
  overflow: hidden;
}

Esse layout é responsável por criar uma aparência semelhante a um cartão e agrupar as entradas. overflow: hidden e gap: 1px ficam claros quando você adiciona cor na próxima seção.

.fieldset-item

.fieldset-item {
  display: grid;
  grid-template-columns: var(--space-lg) 1fr;
  gap: var(--space-md);
  padding: var(--space-sm) var(--space-md);
}

Esse layout é responsável por centralizar o ícone e a caixa de seleção com os rótulos e controles associados. A primeira coluna do modelo de grade, var(--space-lg), cria uma coluna mais larga que o ícone, de modo que um elemento filho precisa ser centralizado.

Esse layout demonstra quantas decisões de design já foram tomadas nas propriedades personalizadas. Padding, lacunas e uma coluna foram todos dimensionados dentro da harmonia do sistema usando valores que você já definiu.

.fieldset-item <picture>

.fieldset-item > picture {
  block-size: var(--space-xl);
  inline-size: var(--space-xl);
  clip-path: circle(50%);
  display: inline-grid;
  place-content: center;
}

Esse layout é responsável pelas configurações, pelo tamanho do círculo do ícone, pela criação de uma forma circular e pela centralização de uma imagem dentro dela.

<imagem> e alinhamento de [caixa de seleção]

.fieldset-item > :is(picture, input[type="checkbox"]) {
  place-self: center;
}

Esse layout isola a centralização dos elementos de imagem e caixa de seleção usando o pseudosseletor :is.

  1. Substitua o seletor picture > svg por .fieldset-item svg da seguinte maneira:

.fieldset-item <svg> (link em inglês)

.fieldset-item svg {
  block-size: var(--space-md);
}

Isso define o tamanho do ícone SVG como um valor do sistema de tamanhos.

.sm-stack

.sm-stack {
  display: grid;
  gap: var(--space-xs);
}

Essa classe de utilitário destina-se aos elementos de rótulo da caixa de seleção para espaçar o texto auxiliar da caixa de seleção.

input[type=&quot;checkbox&quot;]

input[type="checkbox"] {
  inline-size: var(--space-sm);
  block-size: var(--space-sm);
}

Esses estilos aumentam o tamanho de uma caixa de seleção usando valores do nosso conjunto de espaçamento.

O que tentar

  1. Abra as Ferramentas para desenvolvedores do Chrome e encontre os selos de grade no HTML no painel Elements. Clique neles para ativar as ferramentas de depuração.
  2. Abra as Ferramentas para desenvolvedores do Chrome e passe o cursor sobre uma lacuna no painel Estilos.
  3. Abra as Ferramentas para desenvolvedores do Chrome, acesse o painel Estilos e mude de Estilos para Layouts. Alterne as configurações e ative os layouts para explorar essa área.

Consultas de mídia

O CSS a seguir adapta os estilos com base no tamanho e na orientação da janela de visualização com a intenção de ajustar o espaçamento ou a organização para ser ideal de acordo com o contexto da janela de visualização.

<main>

@media (min-width: 540px) {
  main {
    padding: var(--space-lg);
  }
}

@media (min-width: 800px) {
  main {
    padding: var(--space-xl);
  }
}

Essas duas consultas de mídia fornecem mais padding à main, à medida que mais espaço da janela de visualização fica disponível. Isso significa que ele começa com um padding pequeno e compacto, mas se torna cada vez mais espaçoso à medida que há mais espaço disponível.

&lt;form&gt;

form {
  --repeat: auto-fit;
  grid-template-columns: 
    repeat(var(--repeat), minmax(min(10ch, 100%), 35ch));
}

@media (orientation: landscape) and (min-width: 640px) {
  form {
    --repeat: 2;
  }
}

O formulário era responsivo ao tamanho da janela de visualização que já estava usando auto-fit. No entanto, ao testar em um dispositivo móvel, virar um dispositivo para o modo paisagem não coloca os dois grupos de formulários lado a lado. Adapte-se a esse contexto de paisagem com uma consulta de mídia orientation e uma verificação de largura da janela de visualização. Agora, se o dispositivo estiver no modo paisagem e com pelo menos 640 pixels de largura, force duas colunas mudando a propriedade personalizada --repeat para um número em vez da palavra-chave auto-fit.

.fieldset-item

@media (min-width: 540px) {
  .fieldset-item {
    grid-template-columns: var(--space-xxl) 1fr;
    gap: var(--space-xs);
    padding: var(--space-md) var(--space-xl) var(--space-md) 0;
  }
}

Essa consulta de mídia é outra expansão de espaçamento quando há mais espaço da janela de visualização disponível. O modelo de grade expande a primeira coluna usando uma propriedade personalizada maior (var(--space-xxl)) no modelo. O padding também é otimizado para propriedades personalizadas maiores.

O que tentar

  1. Abra e contraia seu navegador e observe o ajuste do espaço.
  2. Visualizar em um dispositivo móvel
  3. Visualizar em um dispositivo móvel no modo paisagem

5. Cor adaptável

Ramificação Git: colors

Ao final desta seção, o formulário de configurações vai fazer o seguinte:

  • Adaptar às preferências de cores claras e escuras
  • Ter um esquema de cores derivado de um hexadecimal da marca
  • Ter cores acessíveis

19e9b707348ace4c.png

HSL

Na próxima seção, você vai criar um sistema de cores com HSL para ajudar a criar temas claro e escuro. Ela é baseada neste conceito fundamental do CSS: calc().

HSL significa matiz, saturação e brilho. A tonalidade é um ângulo, como um ponto em um relógio, enquanto a saturação e a luminosidade são porcentagens. A calc() faz operações matemáticas em porcentagens e ângulos. Você pode realizar cálculos de luminosidade e saturação nessas porcentagens no CSS. Combine cálculos de canal de cor com propriedades personalizadas para ter um esquema de cores moderno e dinâmico, em que as variantes são calculadas a partir de uma cor de base, ajudando você a evitar o gerenciamento de algumas cores no código.

5300e908c0c33d7.png

Propriedades personalizadas

Nesta seção, você vai criar um conjunto de propriedades personalizadas para usar com seus estilos. Semelhante ao conjunto de espaçamento criado anteriormente na tag :root, você adicionará cores.

Suponha que a cor da marca do seu app seja #0af. Sua primeira tarefa é converter esse valor de cor hexadecimal em um valor de cor HSL: hsl(200 100% 50%). Essa conversão revela os canais de cor da sua marca em HSL, em que você pode usar calc() para calcular várias cores de marca de suporte.

Cada um dos blocos de código abaixo nesta seção precisa ser adicionado ao mesmo seletor :root.

Brand channels

:root {
  --hue: 200;
  --saturation: 100%;
  --lightness: 50%;
}

Os três canais HSL foram extraídos e colocados em suas propriedades personalizadas.

  1. Use as três propriedades como estão e recrie a cor da marca.

Marca

:root {
  --brand: hsl(
    var(--hue) 
    calc(var(--saturation) / 2)
    var(--lightness) 
  );
}

Como o esquema de cores é escuro por padrão, é recomendado diminuir a saturação das cores para uso em superfícies escuras. Caso contrário, elas podem vibrar ao olho ou ficar inacessíveis. Para diminuir a saturação da cor da marca, use a tonalidade e o brilho como estão, mas corte a saturação pela metade com um pouco de divisão: calc(var(--saturation) / 2). Agora, a cor da marca está adequada no tema, mas não saturada para uso.

Texto

:root {
  --text1: hsl(var(--hue) 15% 85%);
  --text2: hsl(var(--hue) 15% 65%);
}

Para o texto de leitura no tema escuro, você usa a tonalidade da marca como base, mas cria cores quase brancas a partir dela. Muitos usuários vão achar que o texto é branco, mas na verdade é azul muito claro. Manter as cores é uma ótima maneira de criar harmonia de design. --text1 é 85% branco e --text2 é 65% branco, e ambos têm muito pouca saturação.

  1. Depois de adicionar o código ao seu projeto, abra as Ferramentas para desenvolvedores do Chrome e tente alterar esses valores de canal. Saiba como o HSL e os canais dele interagem entre si. Talvez você queira mais ou menos saturação.

Superfície

:root {
  --surface1: hsl(var(--hue) 10% 10%);
  --surface2: hsl(var(--hue) 10% 15%);
  --surface3: hsl(var(--hue) 5% 20%);
  --surface4: hsl(var(--hue) 5% 25%);
}

O texto é muito claro porque as superfícies ficam escuras no modo escuro. Nas cores do texto que usavam valores de alto brilho (85% ou mais), as superfícies usam valores mais baixos (30% ou menos). Manter um intervalo saudável entre as faixas de claridade entre a superfície e o texto ajuda a garantir cores acessíveis para os usuários lerem.

  1. Observe como as cores começam no cinza mais escuro, com 10% de claridade e 10% de saturação, e diminuem à medida que ficam mais claras. Cada nova superfície é 5% mais leve que a anterior. A saturação também diminui um pouco nas superfícies mais claras. Tente colocar todas as superfícies em 10% de saturação. Você gosta mais ou menos?

Tema claro

Com um conjunto íntegro de cores de texto e superfície especificando o tema escuro, é hora de se adaptar a uma preferência pelo tema claro atualizando as propriedades personalizadas de cores em uma consulta de mídia prefers-color-scheme.

Você vai usar a mesma técnica para manter uma grande diferença nos valores de iluminação entre as superfícies e as cores do texto para manter um bom contraste das cores.

Brand

@media (prefers-color-scheme: light) {
  :root {
    --brand: hsl(
      var(--hue) 
      var(--saturation)
      var(--lightness) 
    );
  }
}

O primeiro é a cor da marca. É necessário restaurar a saturação total.

Texto

@media (prefers-color-scheme: light) {
  :root {
    --text1: hsl(
      var(--hue) 
      var(--saturation)
      10% 
    );

    --text2: hsl(
      var(--hue) 
      calc(var(--saturation) / 2)
      30%
    );
  }
}

Semelhante a como o tema escuro tinha cores de texto muito claras, no tema claro as cores do texto são azul muito escuro. Ver 10% e 30% como valores de claridade para a cor HSL indica que essas cores são escuras.

Surface

@media (prefers-color-scheme: light) {
  :root {
    --surface1: hsl(var(--hue) 20% 90%);
    --surface2: hsl(var(--hue) 10% 99%);
    --surface3: hsl(var(--hue) 10% 96%);
    --surface4: hsl(var(--hue) 10% 85%);
  }
}

Essas cores de superfície são as primeiras a quebrar padrões. O que poderia ter parecido bastante razoável e linear até agora está corrompido. O bom é que você pode brincar com as combinações de cores de tema claro HSL aqui mesmo no código e ajustar a luminosidade e a saturação para criar um bom esquema de cores claras que não fique muito legal ou azul.

Usar o sistema de cores

Agora que as cores estão definidas, é hora de usá-las. Você tem uma cor de marca de destaque, duas cores de texto e quatro cores de superfície.

  • Para as seções de código a seguir, encontre o seletor correspondente e adicione a cor CSS ao bloco de código existente.

<body>

body {
  background: var(--surface1);
  color: var(--text1);
}

As cores primárias da página são a primeira superfície e as cores do texto que você fez, o que também atinge o máximo de contraste padrão. A alternância entre claro e escuro já pode começar a ser testada!

&lt;fieldset&gt;

fieldset {
  border: 1px solid var(--surface4);
  background: var(--surface4);
}

Esse é o elemento semelhante a um cartão do seu design. A borda e o intervalo de 1 pixel são da mesma cor e representam a superfície atrás de cada .fieldset-item. Isso cria uma boa harmonia visual e é fácil de manter.

.fieldset-item

.fieldset-item {
  background: var(--surface3);
}

Cada entrada de formulário está em sua própria superfície. Esperamos que você esteja vendo como elas se juntam e como as variações de iluminação estão se sobrepondo.

.fieldset-item > imagem

.fieldset-item > picture {
  background: var(--surface4);
}

Essa é uma opção estilística para mostrar a forma circular ao redor do ícone. O motivo fica claro quando você adiciona interações na próxima seção.

.fieldset-item svg (link em inglês)

.fieldset-item svg {
  fill: var(--text2);
}

Os ícones no formulário são definidos para usar o texto alternativo --text2. Designs em que ícones preenchidos são um pouco mais claros do que texto evita que eles pareçam pesados demais.

.fieldset-item:focus-these svg (link em inglês)

.fieldset-item:focus-within svg {
  fill: var(--brand);
}

Esse seletor corresponde ao elemento do contêiner de entrada quando uma das entradas internas está recebendo uma interação e direciona o SVG para destacá-lo com o acento da sua marca. Isso fornece um bom feedback de UX do formulário, em que a interação com as entradas destaca a iconografia relevante.

&lt;small&gt;

small {
  color: var(--text2);
}

O texto é pequeno. Ele deve ser ligeiramente suave em comparação aos cabeçalhos e parágrafos (conteúdo principal).

Controles de formulário escuro

:root {
  color-scheme: dark light;
}

Esse belo toque final informa ao navegador que a página é compatível com temas claros e escuros. O navegador nos recompensa com controles de forma escura.

6. Animação adaptável

Ramificação Git: animations

Ao final desta seção, a página de configurações vai fazer o seguinte:

  • Adaptar às preferências de movimento do usuário
  • Responda à interação do usuário

b23792cdf4cc20d2.gif

Movimento reduzido versus sem movimento

A preferência do usuário encontrada no sistema operacional para movimento não oferece o valor de nenhuma animação. A opção é reduzir o movimento. Animações de crossfade, transições de cor e muito mais ainda são desejáveis para usuários que preferem movimento reduzido.

Nesta página de configurações, não há muito movimento em termos de movimento pela tela. O movimento é mais relacionado a escala, como se o elemento estivesse viajando em direção ao usuário. Ajustar seu código CSS para acomodar o movimento reduzido é tão simples que você reduz as transições de dimensionamento.

Estilos de interação

&lt;fieldset&gt;

fieldset {
  transition: box-shadow .3s ease;
}

fieldset:focus-within {
  box-shadow: 0 5px 20px -10px hsl(0 0% 0% / 50%);
}

Quando um usuário interage com as entradas de um dos elementos de aparência de cartão <fieldset>, isso adiciona um efeito de Lifting. A interface está empurrando um elemento para a frente, ajudando o usuário a se concentrar enquanto o grupo de formulários contextuais é trazido em direção ao usuário.

.fieldset-item

.fieldset-item {
  transition: background .2s ease;
}

.fieldset-item:focus-within {
  background: var(--surface2);
}

Quando o usuário interage com uma entrada, o plano de fundo da camada de itens específica muda para uma cor de superfície destacada, outro recurso de interface de suporte para ajudar a chamar a atenção do usuário e sinalizar que a entrada está sendo recebida. As transições de cores não precisam ser reduzidas na maioria dos casos.

.fieldset-item > imagem

@media (prefers-reduced-motion: no-preference) {
  .fieldset-item > picture {
    clip-path: circle(40%);
    transition: clip-path .3s ease;
  }

  .fieldset-item:focus-within picture {
    clip-path: circle(50%);
  }
}

Confira uma animação clip-path que você vai usar apenas se o usuário não tiver preferências quando se trata de movimento reduzido. O primeiro seletor e os estilos restringem o caminho do clipe circular em 10% e definem alguns parâmetros de transição. O segundo seletor e estilo espera que os usuários interajam com uma entrada e, em seguida, amplie o círculo do ícone. Um efeito sutil, mas interessante quando está tudo bem.

7. Parabéns

Ramificação Git: complete

Parabéns, você criou uma interface adaptável ao usuário.

Agora você sabe as principais etapas necessárias para criar interfaces que se adaptam a vários cenários e configurações de usuário.