你以为网格格线告一个段落後,我会开始讲网格单元吗?当然不是啊,我们网格容器都还没讲完呢。剩下一点小东西稍微交代一下就可以了。
放心雷没有很多。
前一篇提到隐性格线,在容器中,也有两个样式设定是 专门 给隐性轨道使用的。
样式 | 预设值 |
---|---|
grid-auto-rows |
auto |
grid-auto-columns |
auto |
由於两个设定的可使用数值都一样,我直接拿出来外面讲比较快,
%
fr
min-content
max-content
auto
minmax()
fit-content()
以上这几种都是给隐性轨道使用,我快速举个例子,
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: 1fr;
grid-auto-rows: 300px;
}
<div class="grid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<!-- 实际上只设定了一列,但这边是第二列资料 -->
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
</div>
同样的道理 grid-auto-columns
也是一样的操作方式,具体案例我就不再写一次了。
回到 Grid 容器轨道上,我们知道轨道除了可以设定常见的单位尺寸外,现在又多了 fr
可以使用。然而,在 Grid 容器当中,我们还有这些方法可以操作,
CSS 关键字/运算方法 | 说明 |
---|---|
min-content |
设定在轨道中所有最小内容单元的尺寸中,取最大的尺寸 |
max-content |
设定在轨道中所有最大内容单元的尺寸中,取最大的尺寸 |
fit-content(limit) |
接收一个限制数值 limit ,并套入公式 max(minimum, min(limit, max-content)) ,其中 minimum 代表了轨道中的最小尺寸,通常会使用 auto 关键字,但多数情况下会符合 min-content 的尺寸。 |
minmax(min, max) |
定义一组最小、最大值的区间来当作尺寸,他是一个弹性的范围。如果两个数值写反了,会直接取用最小值。 |
其中 min-content
, max-content
在实务上比较难以看出效果,针对官方所提出的演算法则来看,其实也看不太出端倪。我举一个稍微复杂一点的设定,然後我们来看看运作逻辑。
grid-template-columns: 200px 1fr max-content minmax(min-content, 100px);
假设我们的 Grid 容器有这样的栏设定,那麽计算顺序为,
200px
宽。1fr
的尺寸。100px
当作最大值来做范围运算。从最小尺寸中取一个最大值 到底是什麽神逻辑?
我用实际案例解释给你看,首先我们先设计一个第一栏使用 min-content
的容器,
.grid-container {
display: grid;
grid-template-columns: min-content repeat(2, 1fr);
grid-template-rows: repeat(3, 1fr);
width: 100%;
height: 500px;
}
他是一个 3x3
的容器,其他两个栏位都使用弹性空间,列的部分也全部使用弹性空间。然後我们针对第一栏的部分来放一些资料,也就是我们的 1
, 4
, 7
这三个地方要放一点特别的资料进去。
<div class="grid-container">
<div class="grid-item">
<p>放一点特别的资料进去</p>
</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">
<p>放一点特别的资料进去</p>
</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
<div class="grid-item">
<p>放一点特别的资料进去</p>
</div>
<div class="grid-item">8</div>
<div class="grid-item">9</div>
</div>
会後他会变成这样,
你的 Grid 单元内容超出 height: 500px
的设定了,对,这算是 min-content
的一个特别的地方,他所谓的 最小内容 是利用文字特性来做计算的。所以,当你使用了这项设定,那们请确保你的文字内容真的是你想要呈现的方式。
另外,你的容器若没有特定尺寸,基本上 Grid 单元还是以填满整个 Grid 容器为目标去填满的。所以如果不指定尺寸,基本上不会有上面 Grid 单元超出容器的状况。
接着,我们来加一点料进去,刚刚有说了,他是取用 在轨道中所有最小内容单元的尺寸中,取最大的尺寸 来用,那麽如果我们放了一个比较困难的文字进去,
<div class="grid-container">
<div class="grid-item">
<p>放一点特别的资料进去</p>
<p>Internationalization and localization</p>
</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">
<p>放一点特别的资料进去</p>
</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
<div class="grid-item">
<p>放一点特别的资料进去</p>
</div>
<div class="grid-item">8</div>
<div class="grid-item">9</div>
</div>
那麽他的结果大家可以猜到了吗?
那这样跟
max-content
到底有什麽差别?
别急,我们把 Grid 容器换成 max-content
再来看看到底发生什麽事情,
.grid-container {
display: grid;
grid-template-columns: max-content repeat(2, 1fr);
grid-template-rows: repeat(3, 1fr);
}
其他的内容我们都不更动,我们来看看 max-content
怎麽呈现我们的结果,
这样可以稍微理解 min-contetn
与 max-content
之间的差异了吧。当然,这种演算方式并无法避开区块元件的占用尺寸问题。换句话说,
当 Grid 单元中有区块元件(Box Module)并指定尺寸,且超出了
min-content
的计算尺寸,那麽,这个地方的min-content
结果就会跟max-content
没什麽太大区别。就如同上面所描述的,所谓min-content
是 在轨道中所有最小内容单元的尺寸中,取最大的尺寸 来使用,所以区块元件占用,又超出计算尺寸,就会被当成是min-content
的最终结果。
举个例子给大家看看,这次就不附上图片了,请大家自行想像一下。
<div class="grid-container">
<div class="grid-item">
<p>放一点特别的资料进去</p>
</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">
<p>放一点特别的资料进去</p>
<img src="...">
</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
<div class="grid-item">
<p>放一点特别的资料进去</p>
</div>
<div class="grid-item">8</div>
<div class="grid-item">9</div>
</div>
.grid-container {
display: grid;
grid-template-columns: min-content repeat(2, 1fr);
grid-template-rows: repeat(3, 1fr);
}
.grid-item img {
display: block;
width: 300px;
height: 300px;
object-fit: cover;
}
在这种状况,无论你是使用 min-content
或 max-content
,你的第一个栏尺寸基本上就是 300px
,除非你的内文计算尺寸能超过,否则这个 300px
就会是最小(也可能是最大)尺寸。
fit-content(limit)
其实我们把他拆解出来会比较容易理解,
max(minimum, min(limit, max-content))
其中 max-content
上面有解释过了,我们只要专注在 limit
与 minimum
这两个地方就好。首先,limit
是你传进去的数值,所以如果我们这样写,fit-content(300px)
那他就等同於,
fit-content(300px) = max(minimum, min(300px, max-content))
问题来了,那个 minimum
是什麽呢?在多数情况下,他是使用 auto
这个关键词来让装置自动决定运算尺寸,通常,在最常见的情况下,他会是 min-content
的数值。会不会有意外?我不能跟你保证永远不会。因为在 auto
的定义里面,还是有一些猫腻。
总归一句,这边的 minimum
所使用的 auto
会采用的是取最小值的部分,而在 Grid 自动取得最小值(如 min-content
的演算法)所使用的大方向有这三种顺序,
0
所以,我们刚刚在解释 min-content
的范例中,我们放了一张图片,那张图片对於 Grid 单元就属於转换内容的尺寸,符合第 2 点的演算方式。所以你会取得该单元的 min-content
就是内容占有的尺寸。
如果你不写 fit-content()
的话,是可以避开 min-content
的问题。就是把他拆成上面的公式就好了,如果你真的想要使用,又不想踩到 min-content
可能会发生的状况的话。
总结一句话,所谓的 fit-content()
的意思是,
类似
min-content
但如果比min-content
还大就取比较大的。
然後如果掉入min-content
的问题,就等於max-content
。
minmax(min, max)
我们在 Part 7 提到 1fr
其实会等於 minmax(auto, 1fr)
大家还记得吗?
如果忘了可以回去 Part 7 的文章 重看一次。
然後这边的 auto
一样会有刚刚 fit-content()
的问题,就不再赘述。这个 CSS 运算方法其实很容易理解,他就只是一个取出一个范围尺寸,然後依照这个范围尺寸变动栏或者是列的尺寸。对於需要弹性应用,但又不想过大(或过小)的网格单元来说很方便。
需要注意的点就是,
minmax(min, min)
第二点很重要所以说三次!
容器单元指定超出此范围的尺寸不干扰网格系统
举例来说,
.grid-container {
display: grid;
grid-template-columns: repeat(3, minmax(300px, 1fr);
grid-template-rows: repeat(3, 1fr);
}
.grid-item:first-child {
width: 1200px;
}
最终你会得到这样的结果,
所以,当你在 Grid 容器中使用 minmax()
时,请特别注意你的 Grid 单元尺寸的状况,否则他是不会排在位置上的,另外,如果你的 1fr
有与 minmax()
混用的情况,请也特别留意 Grid 单元尺寸,因为在这个时候所谓的 剩余空间 可能跟你想像的不太一样。
官方对於此有一份演算法说明,
我觉得比较诧异的是,官方对於容器单元流向,仅说明是 针对 隐性轨道的网格单元,但是实际上是整个容器都受用,无论你是不是隐性轨道。但,其实这样说起来也是合理的,你总不可能一般轨道是一种流向,然後隐性轨道是另外一种流向吧。
控制容器单元流向只有一个样式,
样式 | 可用值 | 预设值 |
---|---|---|
grid-auto-flow |
[row, column] , dense |
row |
row
跟 column
就很单纯,可以想成对於栏或列的 Grid 单元 优先 摆放流向。以预设值 row
来说,他就是由左至右(非 RTL 文本模式),由上到下的状况来排列。而换成 column
则是由上到下,由左至右,这种方式跟 Flexbox 在交换主要轴、交叉轴的情况很相似。
至於 dense
这个关键字,则是可以单独,或搭配 row
, column
使用的,例如,
.grid-container {
display: grid;
grid-auto-flow: dense;
/* 或是 */
grid-auto-flow: row dense;
}
所谓的 dense
的演算方式是采用密集(紧凑)排列法,当你的 Grid 单元尺寸不同时,预设的排社方式是遇到空间不足就会往下(row
方向)或往右(column
方向)继续排列,这个时候,在某些区域就会出现空白的区块,举例来说,
.grid-container {
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(3, 1fr);
grid-auto-flow: row dense;
}
.grid-item:nth-of-type(1),
.grid-item:nth-of-type(2) {
grid-column: auto / span 2;
}
此时当你使用 dense
的时候,他就会变成,
这种紧凑排版很类似以前流行过的 Masonry Layout,也就是我之前写过的 瀑布流难题,这个基本上在 Grid 上面可以得到一个还算不错的解法。
最後我们来聊填满这件事情,大家前面应该看了非常多 repeat()
的使用,对,最後我们来聊一下关於 repeat()
这件事情。他的目的就是重复你所设定的轨道,除了重复次数以外,他还有两个特殊关键字可以使用。
重复目标 | 使用方式 |
---|---|
网格轨道 | repeat(次数, <轨道尺寸> 或加上 <格线名称>) |
固定尺寸 | repeat(次数, <固定尺寸> 或加上 <格线名称>) |
auto-fill |
repeat(auto-fill, <固定尺寸> 或加上 <格线名称>) |
auto-fit |
repeat(auto-fit, <固定尺寸> 或加上 <格线名称>) |
轨道尺寸 与 固定尺寸 仅差在轨道尺寸可以使用 fit-content()
而固定尺寸至多能使用 minmax()
,这是两者唯一差别。所以以下写法基本上都是合法的,
.grid-container {
grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(3, 100px);
grid-template-columns: repeat(3, [foo] 100px [boo]);
grid-template-columns: repeat(3, minmax(auto, 1fr));
grid-template-columns: repeat(3, minmax(100px, 300px));
grid-template-columns: repeat(3, minmax(auto, 1fr));
grid-template-columns: repeat(3, fit-content(100px));
grid-template-columns: repeat(auto-fit, 100px);
grid-template-columns: repeat(auto-fill, minmax(auto, 200px));
}
关於 auto-fill
与 auto-fit
两者的差异,在於是否 填满 容器。我们直接用图片来解释会比较容易理解,
两者的差异在於,
auto-fill
会尽可能在网格容器中填满所设定的网格轨道auto-fit
网格轨道则是仅满足需要用到的网格单元共同点是,你的 Grid 容器随时都有可能产生剩余空间。
其实网格容器还是有一些小地方可以讲,但那个实在太冷门,我留到最後再提好了。
目录与小节:
[CSS] Flex/Grid Layout Modules, part 1
部落格同步放送:
[CSS] Flex/Grid Layout Modules, part 9
<<: 从零开始学3D游戏开发:模型基础 Part.1 从零开始
>>: [Day13] Tableau 轻松学 - Rows 与 Columns
前言 走过了资料分析、演算法选择後, 我们得知了有些可以改善模型的方向: 解决资料不平衡(Done)...
昨天的进度 defmodule Game do defstruct rounds: [], host...
今日文章目录 需求说明 事前准备 遇到问题 参考资料 需求说明 下拉选单:选择番茄钟时间(分钟) ...
有些学生提到还要多一个 clear div 来清除会把 HTML 弄脏, 这里老师也分享一个是使用 ...
GNU Debugger,简称 GDB,是 GNU 软件系统中的除错器,由於其具有可移植的优点,在现...