it-swarm-pt.tech

Por que a largura e a altura de um item flexível afetam a renderização de um item flexível?

Uma imagem em um estilo flexbox que possui um estilo max-height) Parece renderizar diferentemente, dependendo se ele possui seus atributos height e width definidos.

Aquele com os atributos, definido como a largura/altura verdadeira da imagem, é renderizado com sua proporção preservada, mas aqueles sem os atributos respeitam max-height E apareça esmagado.

.flex-parent {
  display: flex;
  max-height: 10vh;
}
<div class="flex-parent">
  <img                          src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg">
  <img width="320" height="240" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg">
</div>

É assim que aparece em Chrome 58 (e aparece da mesma forma no Firefox 54)).

Different rendering of img in flexbox. Without width and height attributes, and with

Por que eles renderizam de maneira diferente? Quais são as regras que governam esse comportamento?

Meu entendimento (obviamente incorreto) é que os atributos de altura e largura substituem a altura e a largura intrínsecas encontradas quando a imagem é carregada e, se os atributos de altura e largura forem iguais às dimensões da imagem, não haverá diferença na renderização uma vez que a imagem foi carregado.

O contexto está criando uma página com imagens responsivas, onde cada imagem

  • pode ter dimensões originais únicas
  • não causa refluxo quando é carregado, ou seja, o espaço correto é reservado na renderização inicial (portanto, usando atributos de altura e largura)
  • pode caber tudo na tela de uma só vez (daí eu mexer com vh no CSS)

A imagem do sapo é de https://en.wikipedia.org/wiki/File:Red_eyed_tree_frog_edit2.jpg

37
Michal Charemza

Uma configuração inicial de um contêiner flexível é align-items: stretch .

Isso significa que os itens flexíveis se expandirão através do eixo transversal do contêiner.

Em um contêiner na direção da linha, como na pergunta, o eixo transversal é vertical.

Isso significa que os itens (imagens, neste caso) cobrirão toda a altura do contêiner.

No entanto, quando um item flexível tem um tamanho cruzado definido, isso substitui o padrão stretch.

Das especificações:

8.3. Alinhamento de eixo transversal: o align-items e align-self propriedades

Os itens flexíveis podem ser alinhados no eixo transversal da linha atual do contêiner flexível, semelhante a justify-content mas na direção perpendicular.

stretch

Se a propriedade de tamanho cruzado do item flexível computar para auto e nenhuma das margens do eixo cruzado for auto, o item flexível será esticado.

Esta é a linguagem principal:

Se a propriedade de tamanho cruzado do item flex computar para auto

E é assim que a especificação define "propriedade de tamanho cruzado":

A largura ou altura de um item flexível, o que estiver na dimensão cruzada, é o item tamanho cruzado. A propriedade de tamanho cruzado corresponde a width ou height que está na dimensão cruzada.

https://www.w3.org/TR/css-flexbox-1/#cross-size-property


Portanto, seu código parece estar sendo reproduzido conforme definido na especificação.

Isto é o que você tem:

.flex-parent {
  display: flex;
  max-height: 10vh;
}
<div class="flex-parent">
  <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg">
  <img width="320" height="240" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg">
</div>

A primeira imagem não possui largura definida (tamanho principal) nem altura (tamanho cruzado), nem no CSS nem no HTML. Seu tamanho cruzado, portanto, calcula para auto.

Esta afirmação:

Se a propriedade de tamanho cruzado do item flex computar para auto

... é verdade e align-items: stretch entra em vigor.

A imagem se expande pela altura do contêiner, que é 10 px.

A segunda imagem , no entanto, possui dimensionamento explícito. O tamanho da cruz é definido no HTML (height="240").

Agora esta declaração:

Se a propriedade de tamanho cruzado do item flex computar para auto

... é falso e align-items: stretch é substituído. O atributo HTML height prevalece.

Duas notas sobre a segunda imagem:

  1. A imagem ignora o max-height limite no contêiner porque uma configuração inicial no CSS é overflow: visible .
  2. Os atributos HTML width e height são mapeados para suas respectivas propriedades CSS. Conseqüentemente, height="240" substitui o height: auto padrão. Veja abaixo as referências das especificações. *

Há dois outros problemas a serem considerados ao renderizar imagens em um contêiner flexível.

  1. O tamanho mínimo padrão dos itens flexíveis. Essa configuração evita que os itens flexíveis encolhem abaixo do tamanho do conteúdo. Leia este post para obter detalhes completos:

  2. Comportamento variável entre os principais navegadores. Firefox, Chrome, Safari, Edge e IE11 nem sempre processam imagens como itens flexíveis da mesma maneira. Leia este post para mais detalhes:


Considerando todos os fatores acima, aqui está minha solução sugerida:

.flex-parent {
  display: flex;
  max-height: 50vh; /* adjusted for demo */
}

.flex-parent {
  min-width: 0;
}

img {
  width: 100%;
  height: auto;
}
<div class="flex-parent">
  <div>
    <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg">
  </div>
  <div>
    <img width="320" height="240" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg">
  </div>
</div>

* Os atributos HTML width e height são mapeados para suas respectivas propriedades CSS. Portanto, quando especificado, eles substituem os padrões de CSS. A partir da especificação HTML5:

10.4.3 Atributos para conteúdo e imagens incorporados

Os atributos width e height em applet, embed, iframe, object ou video elementos e elementos input com um atributo type no estado Botão de imagem e que representam uma imagem ou que o usuário espera que eventualmente representem uma imagem mapear para as propriedades da dimensão width e height no elemento, respectivamente.

10.2 A folha de estilos do agente do usuário CSS e as dicas de apresentação

Quando o texto abaixo diz que um atributo em um elemento é mapeado para a propriedade de dimensão (ou propriedades), significa que, se o elemento tiver um conjunto de atributos, e analisando o valor desse atributo usando regras para analisar valores de dimensão não gera um erro, espera-se que o agente do usuário use a dimensão analisada como o valor de dica de apresentação = para propriedades, com o valor fornecido como um comprimento de pixel se a dimensão for um número inteiro e com o valor fornecido como uma porcentagem se a dimensão for uma porcentagem.

35
Michael_B

Tentei ler o w3c flexbox especificações e tropeçou em this . Diz que

Para cada dimensão, se essa dimensão da caixa de conteúdo do contêiner flexível tiver um tamanho definido, use-o; se essa dimensão do contêiner flexível estiver sendo dimensionada sob uma restrição de conteúdo mínimo ou máximo, o espaço disponível nessa dimensão é essa restrição.

Caso contrário, subtraia a margem, a borda e o preenchimento do contêiner flexível do espaço disponível para o contêiner flexível nessa dimensão e use esse valor que pode resultar em um valor infinito.

Espero que isto ajude.

3
Eggineer

Aqui você escreveu max-height: 10vh, vh não suporta em nenhum navegador, exceto no iOS 6. mais recente. Isso vale para todas as unidades de comprimento relacionadas à janela de exibição. use outros valores em vez de Vh, isso funcionará bem. Leia este blog https://css-tricks.com/the-lengths-of-css/ .

.flex-parent {
  display: flex;
  max-height:  max-content;
}
<div class="flex-parent">
  <img                          src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg">
  <img width="320" height="240" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg">
</div>
2
Pradeep Kumar Das

O problema é onde você define a altura máxima. A propriedade css max-height não é herdada por padrão. Sua declaração css cria uma div que é 10% da altura da janela de visualização. A imagem sem dimensões definidas diminuiu com base nas dimensões principais. A imagem na qual você define as dimensões implícitas sempre será essas dimensões. Dependendo do tamanho da div, ela pode estourar. Se você colocar a propriedade max-height na primeira imagem, ela deverá ser redimensionada, mantendo a proporção da imagem igual.

0
Philip Tinney