我先问一个问题,如果我有一个
3x3
的 Excel 方块,请问我有几条格线?
Grid 容器中的格线是整个排版定位中的灵魂,但,他没有 Excel 那麽单纯。
Grid 容器的灵魂就是网格格线,我们在宣告一个 Grid 容器的时候,每个方块就会产生相对应的格线,而这些格线当中还会有先前提及的隐性格线(implicit grid)的设计。
我们从 Grid 容器先看起,首先我们定义一个 3x3
的 Grid 容器,
.grid-container {
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(3, 1fr);
}
当然,如果你很明确的定义你的容器,那麽他就会给你很明确的网格格线。如果你没有、或缺少定义网格区块的话,那麽就会落入隐性格线的设定里面。我们这边暂且先不谈,後面会继续提及隐性格线的相关事宜。
首先,既然格线有数字,那麽那些数字代表了什麽意思?
-start
与 -end
结尾这麽一来,我如果要做一个 Grid 单元像是这样,
.grid-item {
grid-row-start: 1;
grid-row-end: 3;
grid-column-start: 2;
grid-column-end: 4;
}
我还没介绍网格单元的基础,这边请先当作你知道这件事情(欸)。
接着我们再回来看 Grid 容器设定,由於格线可以命名,所以我们可以这样写,
.grid-container {
display: grid;
grid-template-rows: [first] 1fr [second] 1fr [boo] 1fr [last];
grid-template-columns: repeat(3, [foo] 1fr [boo]);
}
由於我中间混合了 repeat()
的写法,所以他会有一点点不一样,
虽然说格线有了名字,但原本的数字还是可以使用的。既然有名字,那麽我们的 Grid 单元就能使用名字来决定要使用的区域,
.grid-item {
grid-row-start: second;
grid-row-end: last;
grid-column-start: foo 2;
grid-column-end: boo -1;
}
好的,关於 <命名格线> <数字>
的结构请先当作你知道这件事情(灿笑)。
由於我使用了 repeat()
的关系,所以你会发现同一条格线会有两个名字,在格线的命名上这样是合法的,也就是说一条格线可以有好几种名字,如果你不觉得烦的话可以这样做没关系。
以下是奇怪的例子请不要乱用,
.grid-container {
display: grid;
grid-template-rows: [hello world please begin here] 1fr [second] 1fr [boo] 1fr [last];
grid-template-columns: repeat(3, [foo boo too] 1fr [xoo]);
}
这件事情其实是一种辅助的设计,当你的 Grid 容器设定并没有办法满足一些使用状况的时候,Grid 的渲染引擎会加上这种隐性格线来当作辅助,目的是用以确保整个网格系统的完整性。简单来说,就是当你的网格元件超出了容器设定时,就会产生出隐性网格轨道,然後网格轨道就会带着网格格线出现。
官方的说明再贴一次,虽然不一定看得懂。
至於,哪些状况会产生隐性网格轨道(隐性格线)呢?
合理的说法是,
所谓的 超出 了网格容器的设计,代表的就是在设定上的资料量,超过了原有网格容器可容纳的网格单元数量。就像是 3x3
的方格,你硬要放入 4x4
的资料的意思一样。网格系统为了确保网格轨道的正确性,就会增加轨道来放入这些资料,这些 被增加 的轨道,就是所谓的隐性网格轨道(Implicit Grid Tracks),而这些轨道的产生就会带来了隐性网格格线(Implicit Grid Line)。
但是,
实际上(现实面)的状况是,
虽然说这些隐性格线目的是为了确保 Grid 容器的完整性,但是,我觉得更多的部分应该是要 防止人类随意乱写样式造成的错误。我们可以来看看这些例子,
.grid-container {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(2, 100px);
}
<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 class="grid-item">7</div>
<div class="grid-item">8</div>
<div class="grid-item">9</div>
</div>
在没有定义 grid-template-rows
的情况下,所有的列(row)的产生都算在隐性轨道头上。
尔或者是指定了一个奇怪的网格轨道,迳而产生了隐性网格轨道,造成後面网格呈现出现不同的流向,
.grid-container {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
}
.grid-item:first-child {
grid-column: 1 / 5;
grid-row: 1 / 2;
}
<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 class="grid-item">7</div>
<div class="grid-item">8</div>
<div class="grid-item">9</div>
</div>
这种情况是最可怕的,由於隐性轨道跟一般网格轨道的功能是一样的,所以,当你原本设想的网格容器 3x3
的区域,如果因为设定错误,他就会变成 4x3
的网格容器。是的,网格系统很贴心的帮你把你要的区域给画出来了。
惊不惊喜,意不意外。
另外,在容器使用 grid-template-areas
的设定方式时,由於指定名称与其网格单元名称的配对不合(或没有配对),也会产生隐性格线,而且,在更复杂的网格单元设定时,更容易会造成不必要的隐性格线产生。
这边必须要先提及,grid-template-areas
有一个 附加特性,
所有命名区块的位置,都会产生 4 条隐性命名格线,也就是栏(row)的方向两条,列(column)的方向两条。
我们先看范例,後面再来讲解到底为什麽。这个时候,我们还是请一只猫来切版,
.grid-container {
display: grid;
grid-template-areas:
"nav nav nav"
"sidebar main main"
"sidebar main main";
width: 500px;
height: 500px;
}
.nav {
grid-area: nav;
}
.sidebar {
grid-area: sidebarrrrr;
}
.main {
grid-area: main;
}
<div class="grid-container">
<nav class="grid-item nav">1</nav>
<aside class="grid-item sidebar">2</aside>
<main class="grid-item main">3</main>
</div>
最终的结果会是这样,
命名网格最可怕的地方在於,你的整个 Grid 容器尺寸不变,然後会依照比例 均分 这些网格格线所划分出来的区域,无论你是不是隐性网格格线都一视同仁。
之所以名字打错会造成这个问题,主要还是命名网格单元设定的 附加特性 有关。以上述的例子来看,我们单纯看栏(column)的部分就好,毕竟是正方形转过去就可以通了。
首先是 nav nav nav
,在栏方向有两条线,名称分别是,
[nav-start]
,[nav-end]
在列方面也会有两条线,名称跟栏一样。其他的区块也分别都会有四组网格格线,如同我刚刚所描述的。那麽,我们再来看看那个不存在於命名区域设定的网格单元 sidebarrrrr
,
首先,他一样会有四条线,
栏方向
[sidebarrrrr-start]
,[sidebarrrrr-end]
列方向[sidebarrrrr-start]
,[sidebarrrrr-end]
上面的计算结果,我们发现网格格线的计算数字被标记到了 6
,原本只有 4
而已,原因是,你一个隐性命名网格单元,每个方向都会产生 2
条线,然而,他并不会将 上一个 网格单元的最後一条线做合并的动作,换句话说,
无论是一般命名网格单元还是隐性命名单元,他的网格格线都是独立的。
所以我们从栏方向来看 sidebarrr
这个单元,就很容易理解为何变成 6
。因为对於 nav nav nav
这个命名区块来说,他的网格格线为 [nav-start]
, [nav-end]
,但由於隐性命名单元的发生,所以,单就 nav nav nav
这个区块来看,他的网格格线就变成了,
[nav-start]
,[nav-end]
,[sidebarrrrr-start]
,[sidebarrrrr-end]
由於 [nav-start]
等同於 网格格线数字 1
,而 [nav-end]
为 4
,所以後面增加的隐性命名区块网格格线,就变成了 5
跟 6
了。
当然,你不要打错名字就好了。
另外,如果在命名 Grid 单元上,使用了错误的网格区域设定,虽然不一定会造成隐性网格区域的产生,但一样会打坏原本网格单元摆放的逻辑。
前面有提到了格线可以取名字,但是不建议你的名字当中有 -start
或 -end
结尾。原因在於,在 Grid 格线系统中,他会使用 -start
与 -end
这两个关键字来组合你的网格名称,用以找到确切的网格格线位置。
又是一个小贴心,然後雷死你不偿命的。
我们举一个实际的例子来看,
.grid-container {
display: grid;
grid-template-columns: [first] 100px [foo foo-start] 100px [foo-end] 100px [last];
grid-template-rows: repeat(2, 100px);
}
.grid-item:first-child {
grid-column-start: first;
grid-column-end: foo;
grid-row: 1 / 2;
}
聪明如你,一定会觉得,阿不就是把第一个 .grid-item
放在第一格 100x100
的地方,这有什麽好困难的?
来,我们来看实际的结果,
惊不惊喜,意不意外。
我雷死你这小王八蛋!
这是网格格线一个不知道是不是因为隐性命名网格区域会用到 -start
, -end
的关系,索性将这两个字也纳入了一般命名网格格线的规则里。为什麽?我上面之所以把 grid-column
分开来设定的原因,就恰巧可以解释这件事情。
grid-column-start
如果使用命名格线,他会去找看看有没有叫做 <我格线>-start
的命名格线,如果找不到才会先去找格线名字相同的,例如 <我格线>
。grid-column-end
跟上面的逻辑一样逻辑同上,只是後面改成 <我格线>-end
。grid-row-start
, grid-row-end
逻辑同上。grid-column
, grid-row
这两个缩写的逻辑也同上。所以,我上面的例子是这样命名的,
grid-template-columns: [first] 100px [foo foo-start] 100px [foo-end] 100px [last];
依据网格格线的规则,他会先去找 [foo-end]
,所以就会有上面图片中的效果。
为什麽不是先找
foo
而是先找foo-end
?
w3c 官方说的,不爽你可以去他 Github 发 PR(欸
Line-based Placement
First attempt to match the grid area’s edge to a named grid area: if there is a grid line whose line name is -start (for grid--start) / -end (for grid--end), contributes the first such line to the grid item’s placement.
所以说,没事请不要乱用 -start
或 -end
来命名你的格线,他会 优先配对。
另外,如果使用了不存在的格线名称,那麽你的格线系统就会多一个尺寸为 0
的轨道,然後多一条线出来。跟刚才的命名单元一次多两条不一样。这个部分一样会破坏 Grid 原本摆放单元的位置,举例来说,
.grid-container {
display: grid;
grid-template-columns: [first] 100px [foo] 100px [boo] 100px [last];
grid-template-rows: repeat(3, 100px);
}
.grid-item:first-child {
grid-column-start: first;
grid-column-end: qoo;
grid-row: 1 / 2;
}
总括来看,其实我并没有特别觉得网格系统很贴心,而这些真的只是为了维持网格展示能正常的一些补救(防呆防蠢不防雷)的作法。
对於不明就里的人来说,被雷到应该只是刚好。
其实讲下来,应该跟格雷的阴影差不多。格线如果你都很规矩的操作,基本上不太容易出乱子。
目录与小节:
[CSS] Flex/Grid Layout Modules, part 1
部落格同步放送:
[CSS] Flex/Grid Layout Modules, part 8
<<: [Day05] swift & kotlin 入门篇!(3) 基础语法-字串
今天我们藉着昨天的 第一个 Dapp 来稍微修改一下,改成一个投票系统。 首先我们先来尝试撰写这个投...
https://riich.me/blogs/view/13255/updated-amazon-a...
react-native-vector-icons 是在看 React Native 所看到的 这...
对於资料、数据分析,已经有一点心得,但多半都停留在断断续续,不够紮实也不够完整,虽然可以弄出一个系统...
前言 本文说明如何进行下单作业。 程序实作 # 设定交易标的 # 以台股上市股票:长荣 contra...