Depois de mexer algum tempo com esse problema, percebi que isso não é um problema com o layout da grade.
Como você nunca define altura / altura máxima ou largura / largura máxima para o seu SVG, o que está sendo calculado é width:auto
eheight:auto
Nota: Eu trago max-height / max-width, pois eles teriam prioridade sobre os valores de largura / altura .
Agora, por que o layout da paisagem funciona e o retrato não funciona? Porque a largura está "priorizando" sua altura.
E é por isso que, no layout do bloco, uma altura automática é baseada na altura total dos descendentes e uma largura automática é baseada na largura do bloco que o contém.
Fonte - Por que width: auto se comporta de maneira diferente de height: auto?
Isso significa que seu SVG está retirando o width
contêiner e os height
descendentes.
No seu exemplo, seu SVG não tem descendentes, mas tem um pai com uma largura máxima definida . Mas o que isso significa para a altura do SVG ?
O SVG está calculando sua altura através da razão intrísica:
Se a 'viewBox' no elemento 'svg' estiver especificada corretamente:
- deixe viewbox ser a viewbox definida pelo atributo 'viewBox' no elemento 'svg'
- retornar viewbox.width / viewbox.height
Fonte
E sua proporção intrísica é 1/1 = 1
Então você está forçando sua height=width
As soluções)
A solução está configurando a width
ou a margin
para o seu SVG, dependendo da proporção da sua div principal.
No exemplo que você deu, você tem uma proporção de 2: 1, então seu SVG deve ter width:50%
ou margin: 0 25%
.
Isso significa que, se você deseja definir uma proporção diferente, deve ajustar em conformidade (veja retrato-1-3 no código abaixo).
A definição de uma regra CSS para cada proporção pode ser evitada se height
não houver uma restrição, pois você pode definir a width
para o SVG e o contêiner, permitindo que os elementos ajustem height
para manter a proporção.
Também adicionei o exemplo final, se alguém não se preocupa em manter a proporção, mas precisa conter o SVG em um conjunto height
e em um width
contêiner.
.container {
display: grid;
background-color: greenyellow;
margin: 5px;
min-height: 10px;
min-width: 10px;
}
.portrait {
max-height: 100px;
max-width: 200px;
}
/* Add 25% margin left and right to center the image OR set the image width to 50% */
.portrait>.aspect-ratio {
margin: 0 25%;
/*
or
width:50%;
*/
}
.landscape {
max-height: 200px;
max-width: 100px;
}
.aspect-ratio {
grid-column: 1;
grid-row: 1;
background-color: deeppink;
border-radius: 50%;
align-self: center;
justify-self: center;
}
/* Set fixed max-height and max-width rule (33% proportion) */
.portrait-1-3 {
max-height: 100px;
max-width: 300px;
}
/* Align image with the new proportion */
.portrait-1-3>.aspect-ratio {
margin: 0 33.33%;
/*
or
width:33.3%;
*/
}
/* Removed max-height and let the container adjust the height according to the max-width rule and the proportion set */
.portrait-any-height {
max-width: 400px;
}
/* Height will be adjusted through the width/margin defined here, so 10% width will correspond to 40px of height (10%*400px)*(aspect ratio=1)*/
.portrait-any-height>.aspect-ratio {
width:10%;
}
/* Set fixed max-height and max-width rule (proportion doesn't matter) */
.portrait-squeezed {
max-height: 100px;
max-width: 300px;
}
/* Make sure SVG complies with the the given max with and height (squeezing your svg) */
.portrait-squeezed>.aspect-ratio {
max-height: inherit;
max-width: inherit;
}
<div class="container landscape">
<svg class="aspect-ratio" viewBox="0 0 1 1"></svg>
</div>
<div class="container portrait">
<svg class="aspect-ratio" viewBox="0 0 1 1"></svg>
</div>
<div class="container portrait-1-3">
<svg class="aspect-ratio" viewBox="0 0 1 1"></svg>
</div>
<div class="container portrait-any-height">
<svg class="aspect-ratio" viewBox="0 0 1 1"></svg>
</div>
<div class="container portrait-squeezed">
<svg class="aspect-ratio" viewBox="0 0 1 1"></svg>
</div>
Note que eu não sou muito proficiente trabalhando com SVGs e essa resposta é resultado de pesquisas e muita experimentação! Ficaria feliz em receber quaisquer ajustes e / ou correções na minha resposta.