CSS 网格 children 设置的纵横比适合 parent
CSS Grid with children with set aspect ratio fit to parent
我需要一个列数和行数固定的网格。每一列和每一行都被完全填满。每个单元格由两部分组成 - 具有固定纵横比的图像(所有单元格都相同)和具有固定高度的标题。我需要网格以适应 parent(类似于 background-size: contain
的工作方式)。到目前为止,我想出了解决方案,它只适合网格以匹配 parent.
的宽度
注意:在这个例子中 parent 的网格是整个屏幕,在实际情况下它可以是独立于屏幕大小的任何大小(所以我们不能使用 vw
和 vh
单位).
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
padding: 15px;
gap: 15px;
}
.grid-child {
background-color: red;
}
.fixed-ratio {
aspect-ratio: 4/3;
background-color: orange;
}
.caption {
background-color: yellow;
}
<div class="grid">
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">1</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">2</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">3</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">4</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">5</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">6</div></div>
</div>
除非我完全误解了您想要实现的目标,只需将 height 100% 添加到 .grid
即可使网格填满屏幕。
调整屏幕将允许单元格(图像)的内容缩放到父级的宽度,同时保持纵横比。
注意
网格子图像无法填充单元格的高度,同时保持 4/3 的纵横比,除非 container/screen 的宽度也是 4/3 的纵横比。
网格子文本无法填充单元格,因为它具有固定的高度。
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
gap: 15px;
height:100%;
}
.grid-child {
background-color: red;
}
.fixed-ratio {
aspect-ratio: 4/3;
background-color: orange;
}
.caption {
background-color: yellow;
}
<div class="grid">
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">1</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">2</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">3</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">4</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">5</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">6</div></div>
</div>
我设法使用一些 Javascript 和 CSS calc 函数的丑陋用法找到了一个解决方案。我欢迎提供相同结果但不使用 JS 的其他解决方案。您可以使用此代码段来比较您自己的结果(请全屏打开代码段并调整大小 window 以查看实际效果)。
document.addEventListener('DOMContentLoaded', () => {
new ResizeObserver(entries => {
for (let entry of entries) {
entry.target.style.setProperty('--parent-width', entry.contentRect.width + 'px');
entry.target.style.setProperty('--parent-height', entry.contentRect.height + 'px');
}
}).observe(document.body);
});
* {
box-sizing: border-box;
}
html {
--columns: 3;
--rows: 2;
--ratio: 4 / 3;
--gap: 15px;
--caption-height: 20px;
}
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.grid {
background-color: red;
padding: calc(var(--gap) / 2);
width: calc(
min(
var(--parent-width),
(((var(--parent-height) - var(--gap)) / var(--rows) - var(--caption-height) - var(--gap)) * (var(--ratio)) + var(--gap)) * var(--columns) + var(--gap)
)
);
height: calc(
min(
var(--parent-height),
(((var(--parent-width) - var(--gap)) / var(--columns) - var(--gap)) / (var(--ratio)) + var(--caption-height) + var(--gap)) * var(--rows) + var(--gap)
)
);
margin: auto;
}
.grid-child {
padding: calc(var(--gap) / 2);
width: calc(100% / var(--columns));
height: calc(100% / var(--rows));
float: left;
}
.fixed-ratio {
background-color: orange;
height: calc(100% - var(--caption-height));
}
.caption {
background-color: yellow;
height: var(--caption-height);
}
<div class="grid">
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">1</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">2</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">3</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">4</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">5</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">6</div></div>
</div>
我需要一个列数和行数固定的网格。每一列和每一行都被完全填满。每个单元格由两部分组成 - 具有固定纵横比的图像(所有单元格都相同)和具有固定高度的标题。我需要网格以适应 parent(类似于 background-size: contain
的工作方式)。到目前为止,我想出了解决方案,它只适合网格以匹配 parent.
注意:在这个例子中 parent 的网格是整个屏幕,在实际情况下它可以是独立于屏幕大小的任何大小(所以我们不能使用 vw
和 vh
单位).
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
padding: 15px;
gap: 15px;
}
.grid-child {
background-color: red;
}
.fixed-ratio {
aspect-ratio: 4/3;
background-color: orange;
}
.caption {
background-color: yellow;
}
<div class="grid">
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">1</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">2</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">3</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">4</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">5</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">6</div></div>
</div>
除非我完全误解了您想要实现的目标,只需将 height 100% 添加到 .grid
即可使网格填满屏幕。
调整屏幕将允许单元格(图像)的内容缩放到父级的宽度,同时保持纵横比。
注意
网格子图像无法填充单元格的高度,同时保持 4/3 的纵横比,除非 container/screen 的宽度也是 4/3 的纵横比。
网格子文本无法填充单元格,因为它具有固定的高度。
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
gap: 15px;
height:100%;
}
.grid-child {
background-color: red;
}
.fixed-ratio {
aspect-ratio: 4/3;
background-color: orange;
}
.caption {
background-color: yellow;
}
<div class="grid">
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">1</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">2</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">3</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">4</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">5</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">6</div></div>
</div>
我设法使用一些 Javascript 和 CSS calc 函数的丑陋用法找到了一个解决方案。我欢迎提供相同结果但不使用 JS 的其他解决方案。您可以使用此代码段来比较您自己的结果(请全屏打开代码段并调整大小 window 以查看实际效果)。
document.addEventListener('DOMContentLoaded', () => {
new ResizeObserver(entries => {
for (let entry of entries) {
entry.target.style.setProperty('--parent-width', entry.contentRect.width + 'px');
entry.target.style.setProperty('--parent-height', entry.contentRect.height + 'px');
}
}).observe(document.body);
});
* {
box-sizing: border-box;
}
html {
--columns: 3;
--rows: 2;
--ratio: 4 / 3;
--gap: 15px;
--caption-height: 20px;
}
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.grid {
background-color: red;
padding: calc(var(--gap) / 2);
width: calc(
min(
var(--parent-width),
(((var(--parent-height) - var(--gap)) / var(--rows) - var(--caption-height) - var(--gap)) * (var(--ratio)) + var(--gap)) * var(--columns) + var(--gap)
)
);
height: calc(
min(
var(--parent-height),
(((var(--parent-width) - var(--gap)) / var(--columns) - var(--gap)) / (var(--ratio)) + var(--caption-height) + var(--gap)) * var(--rows) + var(--gap)
)
);
margin: auto;
}
.grid-child {
padding: calc(var(--gap) / 2);
width: calc(100% / var(--columns));
height: calc(100% / var(--rows));
float: left;
}
.fixed-ratio {
background-color: orange;
height: calc(100% - var(--caption-height));
}
.caption {
background-color: yellow;
height: var(--caption-height);
}
<div class="grid">
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">1</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">2</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">3</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">4</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">5</div></div>
<div class="grid-child"><div class="fixed-ratio"></div><div class="caption">6</div></div>
</div>