在 CSS 网格布局中流畅缩放项目



我使用display: grid在下面创建了一个布局,我使用了旧的padding-top技巧来拥有流畅的方形div,但我想知道是否有更好的方法来做到这一点,无论是使用 CSS 网格还是 Flexbox。布局应按原样显示,而不是使用 JS。

https://codepen.io/anon/pen/GWzavX

.o-container {
margin: 0 auto;
max-width: 1280px;
}
.o-grid {
box-sizing: border-box;
display: grid;
grid-gap: 1rem;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(2, 1fr);
max-width: 100%;
padding: 0 1rem;
width: 100%;
}
.o-grid__content {
box-sizing: border-box;
height: 100%;
padding: 1rem;
position: absolute;
top: 0;
width: 100%;
}
.o-grid__item {
box-shadow: inset 0 0 0 1px red;
position: relative;
}
.o-grid__item--tall {
grid-row: span 2;
}
.o-grid__item--wide {
grid-column: span 2;
padding-top: 50%;
}
<div class="o-container">
<div class="o-grid">
<div class="o-grid__item o-grid__item--wide">
<div class="o-grid__content">
1. 2x1
</div>
</div>
<div class="o-grid__item">
<div class="o-grid__content">
2. 1x1
</div>
</div>
<div class="o-grid__item o-grid__item--tall">
<div class="o-grid__content">
3. 1x2
</div>
</div>
<div class="o-grid__item">
<div class="o-grid__content">
4. 1x1
</div>
</div>
<div class="o-grid__item">
<div class="o-grid__content">
5. 1x1
</div>
</div>
<div class="o-grid__item">
<div class="o-grid__content">
6. 1x1
</div>
</div>
</div>
</div>

我在下面创建了一个布局display: grid,我使用了旧的padding-top技巧来拥有流畅的方形div,但我想知道是否有更好的方法来做到这一点,无论是使用 CSS 网格还是 Flexbox。

事情的真相是,你将不得不找到另一种方法来做到这一点,除非你只为Chrome编码。

在 CSS Grid 中,padding-top技巧在 Firefox 中失败了。规范提供了原因:

6.4. 网格项边距和 填充物

作者应完全避免在网格项的填充或边距中使用百分比,因为他们在不同的 浏览器。

网格项上的百分比边距和填充可以针对 也:

  • 它们自己的轴(左/右百分比根据宽度解析,顶部/底部分辨率相对于高度),或者,
  • 内联轴(左/右/上/下百分比都根据宽度解析)。

用户代理必须选择这两种行为之一。

注意:这种差异很糟糕,但它准确地捕捉了世界的当前状态(实现之间没有共识,也没有 CSSWG内部的共识)。CSSWG的意图是浏览器 将收敛在其中一个行为上,此时规范将是 修改为要求。

这个问题也存在于 Flexbox 中:为什么百分比填充不适用于 Firefox 中的弹性项目?

因此,此时最好的选择可能是视口百分比单位

从规格:

5.1.2. 视口百分比长度:vwvhvminvmax单位

视口百分比长度相对于 初始包含块。当首字母的高度或宽度 包含块被更改,它们相应地缩放。

  • vw 单位- 等于初始包含块宽度的 1%。
  • vh 单位- 等于初始包含高度的 1% 块。
  • vmin 单位- 等于vwvh中的较小者。
  • vmax 单位- 等于vwvh中的较大者。

这是一个粗略的草图:修订后的码笔

尝试将填充替换为

height: calc(25vw - 1.5rem);

或者更好的是,将其应用于所有网格元素,而不仅仅是第一个:

.o-grid__item {
box-shadow: inset 0 0 0 1px red;
position: relative;
height: calc(25vw - 1.5rem); /* allow for the spacing between squares */
}
.o-grid__item--tall {
grid-row: span 2;
height: calc(50vw - 1rem); 
}
.o-grid__item--wide {
grid-column: span 2;
}

没有"干净"的方法来实现元素的设置纵横比,无论是否网格。基于零高度和百分比的填充技巧可能是最常见的解决方案。

这样做的缺点是它锁定了元素的高度,因此如果元素太小,其内容将溢出。

我喜欢一种稍微不同的方法,它使用浮动伪元素来实现相同的结果,但在必要时也允许元素增长以包含溢出:

.o-grid__item--wide::before {
content: "";
float: left;
padding-bottom: 50%;
}
.o-grid__item--wide::after {
clear: left;
content: " ";
display: table;
}

在网格中使用它,您可能希望摆脱grid-template-rows声明。否则,如果一个元素增长到包含溢出,它也将更改所有其他网格行的高度。

最新更新