在流体 CSS 网格布局中保持元素的纵横比

Maintain aspect ratio of elements within a fluid CSS grid layout

我在 4 列 CSS 网格布局中有一个 div 元素列表。 div 元素设置为 100% 宽度,padding-top 为 100% 以保持纵横比为 1:1。这是一种常见的技术,如下所示:

这在 Firefox 中有效,但在 Chrome 中无效。在 Chrome 中,元素不占用网格容器内的任何 space。这是什么原因?

ul {
  border: 2px solid red;
  display: grid;
  grid-gap: 5%;
  grid-template-columns: auto auto auto auto;
  list-style-type: none;
}

div {
  background-color: green;
  padding-top: 100%;
  width: 100%;
}
<ul>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
</ul>

https://jsfiddle.net/ab0asum3/

如果您打开 Chome DevTools 并检查 divs,您会看到浏览器将它们的高度计算为 0px。 我不能确切地说出是哪个怪癖或您在这里违反了哪个标准,但是如果嵌套的 divs 没有高度,它们将不会在 parent lis 上传递任何东西,您也不会有显示任何内容。

原因是Chrome计算嵌套div零高度,这反过来意味着parent li 将具有 零高度 。这就是你的原因。

似乎有 2 个问题:

  • auto 不是 grid-template-columns 的有效值 - 使用类似 1fr
  • 的值
  • 当没有为 lidiv
  • 定义明确的高度时,对 grid-gap 使用百分比值

您需要为行间距使用像素值。

ul {
  border: 2px solid red;
  display: grid;
  grid-gap: 10px 5%;
  grid-template-columns: repeat(4, 1fr);
  list-style-type: none;
  padding: 0;
  margin: 0;
}

div {
  background-color: green;
  padding-top: 100%;
  width: 100%;
}
<ul>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
</ul>

您应该使用 1fr instead auto 来调整列的大小:

ul {
  border: 2px solid red;
  display: grid;
  grid-gap: 5%;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  list-style-type: none;
}

li:nth-child(4n)~li {
  /* eventually for the gap missing in chrome */
  margin-top: 5%
}

div {
  background-color: green;
  padding-top: 100%;
  width: 100%;
}
<ul>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
  <li>
    <div></div>
  </li>
</ul>


注意:对于 square technic,与 flex 不同,它可以由 grid child 制成,它可以让您用内容填充 div 并将其居中示例 https://jsfiddle.net/ab0asum3/4/

/* change --grid-aspect-ratio to your aspect ratio*/
:root {
  --grid-aspect-ratio: 16/9;
}

/* Consider using div element for grid */
ul {
  border: 2px solid red;
  display: grid;
  grid-gap: 10px;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  list-style-type: none;
}
/* Consider using div element for grid-cell */
li {
  /* set relative position */
  position: relative;
  background-color: lime;
}

li:before {
  content: "";
  display: inline-block;
  padding-bottom: calc( 100% / (var(--grid-aspect-ratio)));
}
/* wrap your content in <div class="grid-cell-inner"> */
.grid-cell-inner {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>
  

网格最好使用div个元素。 请注意,您必须为网格单元格内容使用一些内部元素,并将其位置设置为绝对位置以保持相同的纵横比。 不要使用 % 作为网格间隙,如果它是相对于视口的,你可以使用 vw/vh 单位。