CSS Grid 与图片共存时的布局问题

本文最后更新于:2021年1月27日 上午

场景

在生产中遇到的一个 css 问题,css 不正交的问题一直有人吐槽,吾辈今天总算也是遇到了,实在是不吐不快。

CSS 为什么这么难学?

如下一个简单的二维横向图片列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<style>
* {
padding: 0;
margin: 0;
}
.rows {
height: 500px;
display: grid;
grid-template-rows: repeat(5, 1fr);
}
.cols {
height: 100%;
display: flex;
}
.item {
height: 100%;
}
.item img {
max-height: 100%;
}
</style>
<main class="rows">
<div v-for="items of list" class="cols">
<div v-for="item of items" class="item">
<img :src="item.url" />
</div>
</div>
</main>

<!-- 下面是生成一些测试数据,不需要关心 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/faker.js"></script>
<script>
new Vue({
el: ".rows",
data: {
list: Array(5)
.fill(0)
.map(() =>
Array(faker.random.number({ min: 10, max: 20 }))
.fill(0)
.map(() => {
const getNumber = () =>
faker.random.number({ min: 200, max: 300 });
return [getNumber(), getNumber()];
})
.map(([x, y]) => ({
width: x,
height: y,
url: `https://picsum.photos/seed/picsum/${x}/${y}`,
}))
),
},
});
</script>

但显示的效果却并非预想中那样五等份,而是会超过最大高度 – 被图片撑高了。

1611716016173.png

而在经过一番摸索和讨论后,吾辈找到了这个规范:https://drafts.csswg.org/css-grid/#algo-terms

grid 的 fr 单位实际上是个弹性值,如果内容过大,则会撑开。。。而图片的默认大小就是过大的内容。如果显式声明了最小值,就不受图片尺寸的影响了。

修改 grid-template-rows: repeat(5, 1fr); => grid-template-rows: repeat(5, minmax(0, 1fr)); 就好了。

效果

1611716716541.png

吐槽

发明 CSS 的人就是一个智障,这么多不正交的规则纯靠经验真的太恶心了(不是每个人都了解或者说希望了解那些奇奇怪怪的规范)。