SVG圆应该适应CSS网格高度而不重叠

Mic*_*den 9 html css svg aspect-ratio css-grid

在下面的示例中,圆圈适应网格宽度并保持其纵横比。随着容器宽度的缩小,圆圈也随之缩小……

然而,当高度小于宽度时(第二个框),圆圈不会缩小重叠在网格外,而是有没有办法让它在保持纵横比的同时也适应高度?

.container {
	display: grid;
	background-color: greenyellow;
	margin: 5px;
	min-height: 10px;
	min-width: 10px;
}

.portrait {
		max-height: 100px;
		max-width: 200px;
}

.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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

结果应如下所示: 在此处输入图片说明

H. *_*edo 9

在解决这个问题一段时间后,我认为这不是网格布局的问题。

因为你从来没有定义高度/最大高度宽度/最大宽度为您的SVG,被计算的是width:autoheight:auto

注意:我提出了max-height/max-width,因为它们优先于宽度/高度值。


那么,为什么您的横向布局有效而纵向布局无效?因为宽度“优先”于您的高度。

这就是为什么在块布局中,自动高度基于后代的总高度而自动宽度基于包含块的宽度。

来源 - 为什么 width:auto 的行为与 height:auto 不同?

这意味着您的 SVG 正在width从其容器height及其后代中获取 。

在您的示例中,您的 SVG 没有后代,但有一个定义了max-width的父。但这对 SVG 的高度意味着什么?

SVG 正在通过内在比计算它的高度:

如果正确指定了 'svg' 元素上的 'viewBox':

  1. 让 viewbox 成为由 'svg' 元素上的 'viewBox' 属性定义的视图框
  2. 返回 viewbox.width / viewbox.height

来源

你的内在比率是1/1 = 1

所以你强迫你的 height=width


解决方案

解决方案是根据您的父 div 的比例为您的 SVG设置 awidth或 a margin

在您给出的示例中,您的比例为 2:1,因此您的 SVG 应该具有width:50%margin: 0 25%

这意味着如果要设置不同的比例,则必须相应地进行调整(请参阅下面代码中的 Portrait-1-3)。

如果height不是约束,则可以避免为每个比例设置 CSS 规则,因为您可以width为 SVG 和容器定义 a ,让元素调整height以保持纵横比。

如果有人不关心保持纵横比但需要在集合heightwidth容器中包含 SVG,我还添加了最后一个示例。

.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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

请注意,我对 SVG 的使用不是很熟练,这个响应是研究和大量实验的结果!我很乐意收到对我的回复的任何调整和/或更正。