Melhorias lógicas de layout com abreviações relativas ao fluxo

Novas abreviações de propriedades lógicas e novas propriedades de encarte para o Chromium.

Desde o Chromium 69 (3 de setembro de 2018), as propriedades lógicas e os valores ajudaram os desenvolvedores a manter o controle dos layouts internacionais usando estilos de direção e dimensão lógicos, em vez de físicos. No Chromium 87, abreviações e deslocamentos foram enviados para facilitar a escrita dessas propriedades e valores lógicos. Isso captura o Chromium até o Firefox, que tem suporte para as abreviações desde a versão 66. O Safari já tem esse recurso na visualização técnica.

Latim, hebraico e japonês são mostrados renderizando texto de marcador de posição em um frame do dispositivo. Setas e cores seguem o texto para ajudar a associar as duas direções de bloco e inline.

Fluxo de documentos

Se você já conhece as propriedades lógicas, os eixos inline e de bloco e não quer uma atualização, pule para frente. Caso contrário, confira um breve resumo.

No inglês, as letras e as palavras fluem da esquerda para a direita, enquanto os parágrafos são empilhados de cima para baixo. No chinês tradicional, as letras e palavras são lidas de cima para baixo, e os parágrafos são empilhados da direita para a esquerda. Apenas nesses dois casos, se escrevermos CSS que coloca "margin top" em um parágrafo, vamos apenas espaçar adequadamente um estilo de idioma. Se a página for traduzida do inglês para o chinês tradicional, a margem pode não fazer sentido no novo modo de escrita vertical.

Portanto, o lado físico da caixa não é muito útil internacionalmente. Assim começa o processo de oferecer suporte a vários idiomas, aprendendo sobre os lados físico e lógico do modelo de caixa.

Você já inspecionou o elemento p no Chrome DevTools? Se sim, você pode ter notado que os estilos padrão do User Agent não são físicos, mas lógicos.

p {
  margin-block-start: 1em;
  margin-block-end: 1em;
  margin-inline-start: 0px;
  margin-inline-end: 0px;
}

CSS da folha de estilo do user agent do Chromium

A margem não está na parte superior ou inferior, como um leitor de inglês pode acreditar. São block-start e block-end. Essas propriedades lógicas são semelhantes às partes de cima e de baixo de um leitor de inglês, mas também de um leitor japonês como direita e esquerda. Escrito uma vez, funciona em qualquer lugar.

O fluxo normal é quando a página da Web faz parte dessa multidirecionalidade intencionalmente. Quando o conteúdo da página é atualizado de acordo com as mudanças de direção do documento, o layout e os elementos dele são considerados em fluxo. Leia mais sobre o fluxo "em" e "fora" no MDN ou na especificação do módulo de exibição do CSS. Embora as propriedades lógicas não sejam necessárias para o fluxo, elas fazem a maior parte do trabalho pesado para você, conforme a direcionalidade muda. O fluxo implica direção, que letras, palavras e conteúdo precisam percorrer. Isso nos leva a bloquear e inserir direções lógicas.

A direção do bloco é a direção que novos blocos de conteúdo seguem, como perguntar a si mesmo, "onde colocar o próximo parágrafo?". Pense nisso como um "bloco de conteúdo" ou "bloco de texto". Cada idioma organiza os blocos e os ordena de acordo com o respectivo block-axis. block-start é o lado em que um parágrafo é colocado pela primeira vez, enquanto block-end é o lado para onde os novos parágrafos fluem.

Na escrita tradicional japonesa, por exemplo, a direção do bloco flui da direita para a esquerda:

A direção inline é a direção que as letras e palavras seguem. Considere a direção que seu braço e sua mão percorrem quando você escreve. Elas estão se movendo ao longo do inline-axis. inline-start é o lado em que você começa a escrever, enquanto inline-end é o lado em que a escrita termina ou é concluída. No vídeo acima, a inline-axis é de cima para baixo, mas neste outro vídeo, a inline-axis flui da direita para a esquerda.

Ser flow-relative significa que os estilos escritos para um idioma serão aplicados de forma contextual e adequada em outros idiomas. O conteúdo será exibido de acordo com o idioma para o qual ele está sendo entregue.

Novas abreviações

Algumas das abreviações a seguir não são novos recursos do navegador, mas sim maneiras mais fáceis de escrever estilos aproveitando a capacidade de definir valores em bordas de bloco ou inline de uma só vez. As propriedades lógicas inset-* têm novas habilidades, já que não havia maneiras de especificar posições absolutas com propriedades lógicas antes delas. As inserções e abreviações fluem (hehe) muito bem juntas, então vou falar sobre todos os novos recursos de propriedades lógicas que chegam ao Chromium 87 de uma só vez.

Abreviaturas de margem

Nenhum novo recurso foi enviado, apenas alguns atalhos muito úteis foram:
margin-block e margin-inline.

Longo
margin-block-start: 2ch;
margin-block-end: 2ch;
Nova abreviação
margin-block: 2ch;
/* or */
margin-block: 2ch 2ch;

Não existe uma forma abreviada de "superior e inferior" ou "esquerda e direita"... até agora! Você provavelmente faz referência aos quatro lados usando a abreviação de margin: 10px;. Agora, é possível referenciar facilmente dois lados complementares usando a abreviação da propriedade lógica.

Longhand
margin-inline-start: 4ch;
margin-inline-end: 2ch;
Nova abreviação
margin-inline: 4ch 2ch;

Abreviações de padding

Não foram lançadas novas habilidades, mas mais abreviações super úteis foram:
padding-block e padding-inline.


Longhand
padding-block-start: 2ch;
padding-block-end: 2ch;
Nova abreviação
padding-block: 2ch;
/* or */
padding-block: 2ch 2ch;

E o conjunto de abreviações complementares inline:

Longhand
padding-inline-start: 4ch;
padding-inline-end: 2ch;
Nova abreviação
padding-inline: 4ch 2ch;

Encarte e abreviações

As propriedades físicas top, right, bottom e left podem ser gravadas como valores para a propriedade inset. Qualquer valor de position pode se beneficiar ao definir lados com inseto.

.cover {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  inset: 0;
}


Escrita longa física
position: absolute;
top: 1px;
right: 2px;
bottom: 3px;
left: 4px;
Nova abreviação física
position: absolute;
inset: 1px 2px 3px 4px;

Isso deve parecer conveniente imediatamente. O termo "inset" é uma abreviação para os lados físicos e funciona da mesma forma que margem e padding.

Novos recursos

Por mais interessante que seja a abreviação de lados físicos, há ainda mais recursos lógicos trazidos por outras abreviações de inset. Essas abreviações trazem conveniência para a criação de conteúdo por desenvolvedores (elas são mais curtas para digitar), mas também aumentam o alcance potencial do layout porque são relativas ao fluxo.

Mão longa física
position: absolute;
top: 10px;
bottom: 10px;
Abreviação lógica
position: absolute;
inset-block: 10px;


Escrita longa física
position: absolute;
left: 10px;
right: 20px;
Abreviação lógica
position: absolute;
inset-inline: 10px 20px;

Mais informações e uma lista completa de abreviações e escrita manual estão disponíveis no MDN.

Abreviações de borda

A borda, além das propriedades aninhadas color, style e width, também têm novas abreviações lógicas.


Escrita longa física
border-top-color: hotpink;
border-bottom-color: hotpink;
Abreviação lógica
border-block-color: hotpink;
/* or */
border-block-color: hotpink hotpink;


Escrita longa física
border-left-style: dashed;
border-right-style: dashed;
Abreviação lógica
border-inline-style: dashed;
/* or */
border-inline-style: dashed dashed;


Escrita longa física
border-left-width: 1px;
border-right-width: 1px;
Abreviação lógica
border-inline-width: 1px;
/* or */
border-inline-width: 1px 1px;

Mais informações e uma lista completa de abreviações e de mão longa de borda estão disponíveis no MDN.

Exemplo de propriedade lógica <figure>

Vamos reunir tudo em um pequeno exemplo. As propriedades lógicas podem definir o layout de uma imagem com uma legenda para lidar com diferentes direções de escrita e documento.

Ou teste!

Não é preciso fazer muito para tornar um card responsivo internacionalmente com um <figure> e algumas propriedades lógicas. Espero que esta seja uma pequena introdução significativa para saber como todo esse CSS relevante para o mundo funciona juntos.

Polipreenchimento e suporte a vários navegadores

As ferramentas de build ou de cascata são opções viáveis para ter navegadores antigos e novos semelhantes, com espaçamento adequado e propriedades lógicas atualizadas. Para fallbacks de cascata, siga uma propriedade física com uma lógica, e o navegador vai usar a "última" propriedade encontrada durante a resolução de estilo.

p {
  /* for unsupporting browsers */
  margin-top: 1ch;
  margin-bottom: 2ch;

  /* for supporting browsers to use */
  /* and unsupporting browsers to ignore and go 🤷‍♂️ */
  margin-block: 1ch 2ch;
}

No entanto, essa não é uma solução completa para todos. Confira um substituto manual que usa o pseudoseletor :lang() para segmentar idiomas específicos, ajustar o espaçamento físico deles de maneira adequada e, no final, oferecer o espaçamento lógico para navegadores compatíveis:

/* physical side styles */
p {
  margin-top: 1ch;
  margin-bottom: 2ch;
}

/* adjusted physical side styles per language */
:lang(ja) {
  p {
    /* zero out styles not useful for traditional Japanese */
    margin-top: 0;
    margin-bottom: 0;

    /* add appropriate styles for traditional Japanese */
    margin-right: 1ch;
    margin-left: 2ch;
  }
}

/* add selectors and adjust for languages all supported */
:lang(he) {…}
:lang(mn) {…}

/* Logical Sides */
/* Then, for supporting browsers to use */
/* and unsupporting browsers to ignore #TheCascade */
p {
  /* remove any potential physical cruft.. */
  margin: 0;
  /* explicitly set logical value */
  margin-block: 1ch 2ch;
}

Também é possível usar @supports para determinar se é necessário fornecer substitutos de propriedades físicas ou não:

p {
  margin-top: 1ch;
  margin-bottom: 2ch;
}

@supports (margin-block: 0) {
  p {
    margin-block: 1ch 2ch;
  }
}

Sass, PostCSS, Emotion e outros têm ofertas automatizadas de bundler e/ou build com uma ampla variedade de soluções ou substitutos. Verifique cada uma para ver qual corresponde ao seu conjunto de ferramentas e à estratégia geral do site.

A seguir

O CSS vai oferecer mais propriedades lógicas, ainda não acabou! No entanto, há um grande conjunto de abreviações ausentes, e uma resolução ainda está pendente nesta questão do GitHub. Há uma solução temporária em um rascunho. E se você quiser estilizar todos os lados lógicos de uma caixa com uma abreviação?

Abreviação física
margin: 1px 2px 3px 4px;
margin: 1px 2px;
margin: 2px;
Abreviação lógica
margin: logical 1px 2px 3px 4px;
margin: logical 1px 2px;
margin: logical 2px;

O rascunho da proposta atual significa que você precisa escrever logical em cada abreviação para aplicar o equivalente lógico, o que não parece muito DRY para alguns.

Há outras propostas de mudança no nível do bloco ou da página, mas que podem vazar usos lógicos para estilos que ainda presumim lados físicos.

html {
  flow-mode: physical;
  /* or */
  flow-mode: logical;
  /* now all margin/padding/etc references are logical */
}

/* hopefully no 3rd/1st party code is hard coded to top/left/etc ..? */

Essa é difícil! Dê seu voto, expresse sua opinião. Queremos ouvir você.

Quer saber mais sobre propriedades lógicas? Aqui está uma referência detalhada, com guias e exemplos, no MDN 🤓

Feedback