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

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

Desde o Chromium 69 (3 de setembro de 2018), as propriedades lógicas e os valores têm ajudado 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, atalhos e deslocamentos foram enviados para tornar esses valores e propriedades lógicas um pouco mais fáceis de escrever. Isso leva o Chromium até o Firefox, que é compatível com a abreviação desde a 66. Elas estão prontas no Safari no pré-lançamento técnico.

O texto latino, hebraico e japonês é mostrado em ordem crescente de espaço reservado em um frame do dispositivo. Setas e cores seguem o texto para ajudar a associar as duas direções de bloco e inline.

Fluxo do documento

Se você já conhece as propriedades lógicas, os eixos in-line e de bloco e não quer se atualizar, avance. Caso contrário, aqui está uma breve atualização.

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

Portanto, o lado físico da caixa não é muito útil internacionalmente. É assim que se inicia o processo de compatibilidade com vários idiomas: aprendizado sobre os lados físicos e lógicos do modelo de caixa.

Você já inspecionou o elemento p no Chrome DevTools? Nesse caso, você pode ter notado que os estilos padrão de 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 possa 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 semelhantes a um leitor japonês como da direita e da esquerda. Escrito uma vez, funciona em qualquer lugar.

O fluxo normal ocorre quando a página da Web faz parte dessa multidirecionalidade intencionalmente. Quando o conteúdo da página é atualizado de acordo com mudanças de direção do documento, o layout e os elementos dele são considerados em fluxo. Leia mais sobre "entrada" e "saída" do fluxo no MDN ou nas especificações do módulo de exibição CSS. Embora as propriedades lógicas não precisem estar em fluxo, elas fazem a maior parte do trabalho pesado conforme as mudanças de direção. O fluxo implica direção, quais letras, palavras e conteúdo precisam acompanhar. Isso nos leva a bloquear e alinhar direções lógicas.

A direção do bloco é a direção que os novos blocos de conteúdo seguem, como perguntar a si mesmo: "onde colocar o próximo parágrafo?". É como um "bloco de conteúdo" ou um "bloco de texto". Cada idioma organiza os blocos e os ordena junto com as respectivas block-axis. block-start é o lado em que um parágrafo é posicionado primeiro, enquanto block-end é o lado em que os novos parágrafos fluem.

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

A direção inline é a direção das letras e palavras. Considere a direção que seu braço e sua mão percorrem quando você escreve. Elas estão se deslocando ao longo do inline-axis. inline-start é o lado em que você começa a gravar, enquanto inline-end é o lado em que a gravação termina ou une. No vídeo acima, a inline-axis é de cima para baixo, mas no próximo vídeo a inline-axis flui da direita para a esquerda.

O uso de flow-relative significa que os estilos escritos para um idioma vão ser contextuais e aplicados adequadamente em outros. O conteúdo fluirá de acordo com o idioma para o qual ele está sendo enviado.

Novas abreviações

Algumas das abreviações abaixo não são novos recursos para o navegador, e sim maneiras mais fáceis de escrever estilos, aproveitando a possibilidade de definir valores nas bordas de bloco ou inline de uma só vez. As propriedades lógicas inset-* oferecem novas habilidades, já que não havia maneiras tradicionais de especificar posições absolutas com propriedades lógicas antes dela. Encartes e atalhos fluem (hehe) tão bem juntos, vou falar sobre todos os novos recursos de propriedades lógicas que chegam ao Chromium 87 de uma só vez.

Abreviações de margem

Nenhum recurso novo foi enviado, mas 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 margin: 10px;. Agora, é possível referenciar dois lados complementares usando a abreviação da propriedade lógica.

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

Abreviações de padding

Nenhum recurso novo foi enviado, mas mais atalhos úteis tiveram:
padding-block e padding-inline.


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

E o conjunto sem custo financeiro de abreviações de inline:

Longo
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 da definição de lados com encarte.

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


Longo longo
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 encarte é uma abreviação dos lados físicos e funciona como margem e preenchimento.

Novos recursos

Por mais empolgante que seja a abreviação de lados físicos, há ainda mais de recursos lógicos trazidos por outras abreviações de inset. Essas abreviações trazem conveniência para a criação do desenvolvedor, por serem mais curtas, mas também aumentam o alcance potencial para o layout, por serem relativas a fluxos.

Longo longo
position: absolute;
top: 10px;
bottom: 10px;
Abreviação lógica
position: absolute;
inset-block: 10px;


Longo longo
position: absolute;
left: 10px;
right: 20px;
Abreviação lógica
position: absolute;
inset-inline: 10px 20px;

Uma leitura extra e uma lista completa de atalhos e caracteres longos do encarte estão disponíveis no MDN.

Abreviações nas bordas

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


Longo longo
border-top-color: hotpink;
border-bottom-color: hotpink;
Abreviação lógica
border-block-color: hotpink;
/* or */
border-block-color: hotpink hotpink;


Longo longo
border-left-style: dashed;
border-right-style: dashed;
Abreviação lógica
border-inline-style: dashed;
/* or */
border-inline-style: dashed dashed;


Longo longo
border-left-width: 1px;
border-right-width: 1px;
Abreviação lógica
border-inline-width: 1px;
/* or */
border-inline-width: 1px 1px;

Leia mais e uma lista completa de atalhos e caracteres longos de borda (link em inglês) 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 processar diferentes direções de escrita e documento.

Ou experimente!

Você não precisa fazer muito para tornar um cartão responsivo internacionalmente com um <figure> e algumas propriedades lógicas. Se você quer saber como todo esse CSS internacional considerável funciona em conjunto, espero que esta seja uma introdução pequena e significativa.

Polyfilling e compatibilidade entre navegadores

As ferramentas Cascade ou de build são opções viáveis para usar navegadores antigos e novos, devidamente espaçados com propriedades lógicas atualizadas. Para substitutos da Cascade, siga uma propriedade física com uma lógica, e o navegador 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 escrito à mão que usa o pseudosseletor :lang() para segmentar idiomas específicos, ajusta o espaçamento físico adequadamente e, no final, oferece 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 você fornece ou não substitutos de propriedade física:

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

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

Sass, PostCSS, Emotion e outras empresas têm ofertas de bundler e/ou tempo de criação automatizadas que têm uma ampla variedade de substitutos ou soluções. Confira cada um deles para ver qual deles corresponde ao seu conjunto de ferramentas e à estratégia geral do site.

A seguir

Mais CSS vai oferecer propriedades lógicas, isso ainda não é feito. No entanto, ainda falta um grande conjunto de atalhos, e uma solução ainda está pendente neste problema do GitHub (link em inglês). Há uma solução temporária em um rascunho. E se você quiser definir o estilo de todos os lados lógicos de uma caixa com uma abreviação?

Forma abreviada 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;

No rascunho atual da proposta, você precisa escrever logical em todos os atalhos para aplicar o equivalente lógico, o que não soa muito DRY para alguns.

Há outras propostas para mudar no nível do bloco ou da página, mas isso pode vazar usos lógicos para estilos ainda presumindo 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 e dê sua opinião. Queremos saber sua opinião.

Quer aprender ou estudar mais propriedades lógicas? Confira uma referência detalhada, guias e exemplos, no MDN 🤓

Feedback

  • Para propor mudanças na sintaxe CSS de abreviações relativas a fluxo, primeiro verifique os problemas existentes no repositório csswg-rascunhos. Se nenhum dos problemas atuais corresponder à sua proposta, crie um novo.
  • Para informar bugs na implementação de abreviações relativas ao fluxo no Chromium, primeiro verifique os problemas existentes no Rastreador de bugs do Chromium. Se nenhum dos problemas atuais corresponder ao seu bug, crie um novo.