Explorando a propriedade de exibição: os dois valores de exibição
Publicados: 2022-03-10display
CSS, um cavalo de batalha de uma propriedade que não recebe muita atenção. Rachel Andrew dá uma olhada melhor em uma curta série. Um layout flex ou grid começa com você declarando display: flex
ou display: grid
. Esses métodos de layout são valores da propriedade de display
CSS. Nós tendemos a não falar muito sobre essa propriedade por si só, em vez disso nos concentrando nos valores de flex
ou grid
, no entanto, existem algumas coisas interessantes para entender sobre display
e como ele é definido que facilitará muito sua vida à medida que você usa CSS para layout.
Neste artigo, o primeiro de uma pequena série, vou dar uma olhada na maneira como os valores de display
são definidos na especificação do Nível 3. Esta é uma mudança em como definimos a display
em versões anteriores do CSS. Embora possa parecer incomum a princípio para aqueles que fazem CSS há muitos anos, acho que essas mudanças realmente ajudam a explicar o que está acontecendo quando alteramos o valor de display
em um elemento.
Elementos de bloco e em linha
Uma das primeiras coisas que ensinamos às pessoas que são novas em CSS são os conceitos de blocos e elementos inline. Explicaremos que alguns elementos da página são display: block
e possuem certos recursos por causa disso. Eles se estendem na direção em linha, ocupando o máximo de espaço disponível para eles. Eles entram em uma nova linha; podemos dar a eles largura, altura, margem e preenchimento, e essas propriedades afastarão outros elementos da página.
Também sabemos que alguns elementos são display: inline
. Elementos embutidos são como palavras em uma frase; eles não quebram em uma nova linha, mas reservam um caractere de espaço em branco entre eles. Se você adicionar margens e preenchimento, isso será exibido, mas não afastará outros elementos.
O comportamento de elementos de bloco e inline é fundamental para CSS e o fato de que um documento HTML devidamente marcado será legível por padrão. Esse layout é conhecido como "Layout de bloco e embutido" ou "Fluxo normal" porque é assim que os elementos se organizam se não fizermos mais nada com eles.
Valores internos e externos de display
Entendemos os elementos block e inline, mas o que acontece se fizermos um item display: grid
? Isso é algo completamente diferente? Se olharmos para um componente no qual especificamos display: grid
, em termos do elemento pai no layout, ele se comporta como um elemento block level
. O elemento se estenderá e ocupará o máximo de espaço disponível na dimensão em linha, ele começará em uma nova linha. Ele se comporta exatamente como um elemento de block
em termos de como se comporta junto com o restante do layout. Nós não dissemos display: block
, ou dissemos?
Acontece que temos. No Nível 3 da especificação Display, o valor de display
é definido como duas palavras-chave. Essas palavras-chave definem o valor externo de display, que será inline
ou block
e, portanto, definem como o elemento se comporta no layout ao lado de outros elementos. Eles também definem o valor interno do elemento — ou como os filhos diretos desse elemento se comportam.
Isso significa que quando você diz display: grid
, o que você está realmente dizendo é display: block grid
. Você está solicitando um contêiner de grade em nível de bloco. Um elemento que terá todos os atributos do bloco — você pode dar a ele altura e largura, margem e preenchimento, e ele se estenderá para preencher o contêiner. Os filhos desse contêiner, no entanto, receberam o valor interno de grid
para que se tornem itens de grade. Como esses itens de grade se comportam é definido na especificação de grade CSS: a especificação de display
nos dá uma maneira de informar ao navegador que este é o método de layout que queremos usar.
Acho que essa maneira de pensar sobre display
é incrivelmente útil; ele explica diretamente o que estamos fazendo com vários métodos de layout. Se você especificar display: inline flex
, o que você esperaria? Esperançosamente, uma caixa que se comporte como um elemento inline, com filhos que são itens flexíveis.
Há algumas outras coisas bem explicadas pensando na display
dessa nova maneira, e vou dar uma olhada em algumas delas no restante deste artigo.
Estamos sempre voltando ao fluxo normal
Ao pensar sobre essas propriedades de exibição interna e externa, pode ser útil considerar o que acontece se não mexermos com o valor de exibição. Se você escrever algum HTML e visualizá-lo em um navegador, o que você obterá é o Layout de Bloco e Inline ou Fluxo Normal. Os elementos são exibidos como elementos de block
ou inline
.
Veja o Pen Block e o Layout Inline de Rachel Andrew.
O exemplo abaixo contém algumas marcações que eu transformei em um objeto de mídia, fazendo a exibição div
display: flex
(os dois filhos diretos) agora se tornam itens flex, então a imagem agora está em uma linha com o conteúdo. Se você vir no conteúdo, no entanto, há um título e um parágrafo que estão sendo exibidos no fluxo normal novamente. Os filhos diretos do objeto de mídia tornaram-se itens flexíveis; seus filhos retornam ao fluxo normal, a menos que alteremos o valor de display no item flex. O próprio contêiner flex é uma caixa de bloco, como você pode ver pelo fato de a borda se estender até a borda de seu pai.
Veja o Pen Block e o Inline Layout With Flex Component de Rachel Andrew.
Se você trabalha com esse processo, o fato de que os elementos da sua página se apresentam com esse layout de fluxo normal legível, em vez de lutar contra ele e tentar colocar tudo, CSS é muito mais fácil. Também é menos provável que você caia em problemas de acessibilidade, pois está trabalhando com a ordem do documento, que é exatamente o que um leitor de tela ou uma pessoa que está navegando pelo documento está fazendo.
Explicando flow-root
e inline-block
O valor do inline-block
também deve ser familiar para muitos de nós que já fazemos CSS há algum tempo. Esse valor é uma maneira de obter parte do comportamento do bloco em um elemento inline
. Por exemplo, um elemento inline-block
pode ter uma largura e uma altura. Um elemento com display: inline-block
também se comporta de maneira interessante, pois cria um B lock F ormatting C ontent (BFC).

Um BFC faz algumas coisas úteis em termos de layout, por exemplo, contém floats. Para ler sobre os contextos de formatação de bloco com mais detalhes, consulte meu artigo anterior “Entendendo o layout CSS e o contexto de formatação de bloco”. Portanto, dizer display: inline-block
fornece uma caixa inline que também estabelece um BFC.
Como você descobrirá (se você ler o artigo mencionado acima sobre o Contexto de Formatação de Blocos), há um valor mais recente de display que também cria explicitamente um BFC. Este é o valor de flow-root
. Esse valor cria um BFC em um bloco, em vez de um elemento embutido.
-
display: inline-block
fornece um BFC em uma caixa inline. -
display: flow-root
fornece um BFC em uma caixa de bloco.
Agora você provavelmente está pensando que isso é um pouco confuso: por que temos duas palavras-chave completamente diferentes aqui e o que aconteceu com a sintaxe de dois valores sobre a qual estávamos falando antes? Isso leva à próxima coisa que preciso explicar sobre display
, ou seja, o fato de que o CSS tem um histórico com o qual precisamos lidar em termos da propriedade display
.
Valores legados de exibição
A especificação CSS2 detalhou os seguintes valores para a propriedade display
:
-
inline
-
block
-
inline-block
-
list-item
-
none
-
table
-
inline-table
Também foram definidas as várias propriedades internas da tabela, como table-cell
quais não estamos lidando neste artigo.
Em seguida, adicionamos a esses alguns valores para exibição, para oferecer suporte ao layout flexível e de grade:
-
grid
-
inline-grid
-
flex
-
inline-flex
Nota : A especificação também define ruby
e inline-ruby
para suportar Ruby Text sobre o qual você pode ler na especificação Ruby.
Todos esses são valores únicos para a propriedade display
, definidos antes da atualização da especificação para explicar o layout CSS dessa maneira. Algo muito importante sobre CSS é o fato de não sairmos por aí quebrando a web; não podemos simplesmente mudar as coisas . Não podemos decidir de repente que todos devem usar essa nova sintaxe de dois valores e, portanto, todos os sites já construídos que usaram a sintaxe de valor único serão interrompidos, a menos que um desenvolvedor volte e a conserte!
Enquanto pensa sobre este problema, você pode apreciar esta lista de erros no design de CSS que são menos erros em muitos casos como coisas que foram projetadas sem uma bola de cristal para ver no futuro! No entanto, o fato é que não podemos quebrar a web, e é por isso que temos essa situação em que agora os navegadores suportam um conjunto de valores únicos para exibição e a especificação está mudando para dois valores para exibição.
A maneira de contornar isso é especificar valores herdados e curtos para exibição, que incluem todos esses valores únicos. Isso significa que um mapeamento pode ser definido entre valores únicos e novos valores de duas palavras-chave. O que nos dá a seguinte tabela de valores:
Valor unico | Valores de duas palavras-chave | Descrição |
---|---|---|
block | block flow | Caixa de bloco com fluxo normal interno |
flow-root | block flow-root | Caixa de bloco definindo um BFC |
inline | inline flow | Caixa em linha com fluxo normal interno |
inline-block | inline flow-root | Caixa embutida definindo um BFC |
list-item | block flow list-item | Caixa de bloco com caixa de marcação interna e adicional de fluxo normal |
flex | block flex | Caixa de bloco com layout flexível interno |
inline-flex | inline flex | Caixa em linha com layout flexível interno |
grid | block grid | Caixa de bloco com layout de grade interna |
inline-grid | inline grid | Caixa em linha com layout de grade interna |
table | block table | Caixa de bloco com layout de mesa interna |
inline-table | inline table | Caixa em linha com layout de mesa interna |
Para explicar como isso funciona, podemos pensar em um contêiner de grade. No mundo de dois valores, criaríamos um contêiner de grade em nível de bloco com:
.container { display: block grid; }
No entanto, a palavra-chave legada significa que o seguinte faz a mesma coisa:
.container { display: grid; }
Se, em vez disso, quiséssemos um contêiner de grade embutido, no mundo de dois valores, usaríamos:
.container { display: inline grid; }
E se estiver usando os valores legados:
.container { display: inline-grid; }
Agora podemos voltar para onde essa conversa começou e ver display: inline-block
. Observando a tabela, você pode ver que isso é definido no mundo de dois valores como display: inline flow-root
. Ele agora corresponde a display: flow-root
que em um mundo de dois valores seria display: block flow-root
. Um pouco de arrumação e esclarecimento de como essas coisas são definidas. Uma refatoração de CSS, se quiser.
Suporte do navegador para a sintaxe de dois valores
Até agora, os navegadores não suportam a sintaxe de dois valores para a propriedade display
. O bug de implementação do Firefox pode ser encontrado aqui. A implementação — quando acontece — envolveria essencialmente o alias dos valores legados para as versões de dois valores. É provável que leve um bom tempo, portanto, antes que você possa realmente usar essas versões de dois valores em seu código. No entanto, esse realmente não é o ponto deste artigo. Em vez disso, acho que olhar para os valores de exibição à luz do modelo de dois valores ajuda a explicar muito do que está acontecendo.
Quando você define o layout em uma caixa em CSS, você está definindo o que acontece com essa caixa em termos de como ela se comporta em relação a todas as outras caixas no layout . Você também está definindo como os filhos dessa caixa se comportam. Você pode pensar dessa maneira muito antes de declarar explicitamente os valores como duas coisas separadas, pois as palavras-chave herdadas são mapeadas para esses valores e isso ajudará você a entender o que acontece quando você altera o valor de display
.