现在终於可以开始讲 Grid 单元的事情了,虽然可以讲的事情可能不多,绝大部分会围绕在造成容器影响的地方,当然基本的东西还是会先带一下。
只是说讲完之後到底能不能满 30 天呢 XD
首先,他跟 Flexbox 一样,如果内容单元是包含在 Grid 容器里面的话,他本身是宣告成 Grid 格式的文本(Grid formatting context),他并不会因为你把他宣告成 Box Module 而转换成你所知道的区块元件(Block formatting context),在 Grid 容器内的元件,基本上都会被自动指定为 display: block
这样的样式。
同时,在一个 Grid 容器宣告为 display: grid
或 display: inline-grid
当下,其内容所包含的元件会全部被区块化(blockification),也就是现在说的 Grid 单元。
有趣的地方在於,一个合法的 Grid 容器(其内容包含 Grid 单元),在改变区块样式时(例如:display: none
),其 Grid 单元产生(DOMTree 渲染)的区块化还是会发生,说的比较白话一点就是,他还是会把 Grid 单元区块化动作完成之後,外层的 Grid 容器才会做 display: none
的动作。
但是,
如果 Grid 单元设定为 display:contents
则不在此列。关於这个设定我在整个 Grid 单元讲完之後再来讲这个特别的东西。其实我以前有约略讲过,有兴趣的人可以自己去看看 [CSS] 关於 Grid Layout 的使用姿势。
另外,在相连的 Grid 单元如果宣告为非区块元件时,由於已经区块化了,所以基本上他还是会属於区块元件,他会阻断匿名区块元件的产生(anonymous block box)。举例来说,如果把 Grid 单元使用 display: table-cell
的设定,那麽他们最终会被转换成 display: block
,并不会建立成匿名表格单元(anonymous table box)。
关於匿名区块这边就不多说了,有兴趣的我看最後有没有时间再来聊聊。
有兴趣可以看这里 2.4. Layout-Internal Display Types: the table-* and ruby-* keywords
Grid 单元有三种尺寸的面向,
尺寸规则 | 说明 |
---|---|
normal |
如果 Grid 是被替换的元件(replaced element),那麽这个 Grid 单元将会依据自然尺寸(natural size)来显示。若该单元有定义尺寸,则使用定义尺寸,若都没有,则使用 stretch 当作 Grid 单元尺寸。 |
stretch |
预设当作 Grid 单元尺寸,会填满整个 Grid 格线系统可使用空间。但,若同轴向有其他 Grid 单元指定了尺寸,会破坏原本 Grid 填满的比例。 |
其他 | 使用 fit-content 当作预设尺寸。 |
何谓 自然尺寸?举例来说,你这个单元是 <img>
元件的话,这个元件尺寸将会被定义为 src
属性所指定的图片尺寸。详细的说明可以看看 w3c 的叙述 CSS Images Module Level 3, natural size。
Grid 单元定义尺寸的方式,是使用对齐样式来做设定。对,讲来讲去都会回到对齐模组这件事情,我也是觉得很神奇。
基本上单元可以使用这些设定值来对齐,然後只有 stretch
跟尺寸有关,
样式 | 可用值 | 预设值 |
---|---|---|
justify-self |
auto , normal , stretch , <baseline-position> <overflow-position>? , [ <self-position>, left, right ] |
auto |
align-self |
auto , normal , stretch , <baseline-position> , <overflow-position>? <self-position> |
auto |
place-self |
<'align-self'> <'justify-self'>? |
auto |
说在前面的,关於 auto
, normal
, stretch
基本上在没有任何设定的情况,也不是被替换元件的话,基本上没有差异。以下稍微说明一下各种设定数值的作法,
auto
基本上跟着 Grid 容器的设定,对应的数值就是 justify-items
, align-items
与 place-items
这三个。normal
跟 auto
基本上一样,但为何要分两个?stretch
依照 Grid 网格格线比例填满,但 margin
任何一个轴方向都不可为 auto
,且还是会受到 min-width
, min-height
, max-width
, max-heigth
限制。<baseline-position>
可以使用 baseline
, first baseline
, last baseline
三种关键字。<overflow-position>
可以使用 safe
, unsafe
关键字。<self-position>
可以使用 center
, start
, end
, self-start
, self-end
关键字。图片就是一个很常见的可替换元件,
.grid-containter {
display: grid;
grid-template: repeat(3, 300px) / repeat(3, 300px);
gap: 10px;
}
.grid-item:first-child {
// 不做任何设定
}
<div class="grid-container">
<img class="grid-item" src="..." alt="我是图片">
<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>
最终你会得到这个画面,
当你把 <img>
设定尺寸後,基本上他就会变成 有定义尺寸 的区块元件。但是呢,区块单元的尺寸跟你所定义的轨道尺寸基本上是两件事情,所以无论他是自然尺寸,还是有定义尺寸,该超出轨道的地方一样都会超出去。
换句话说,除非上述的例子,你的 <img>
使用了 width: 100%
这种相对尺寸,这个时候才会填满整个栏轨道(宽度的部分),但是,因为自然尺寸比例的关系,这种时候就会换列轨道超出范围了。
所以,并不太建议将 Grid 单元使用可替换元件,尺寸的问题你可能会一直处於无解的状况。
一般来说无尺寸设定在目前的装置上,是指 row
方向,也就是 grid-template-rows
的样式设定。为何说他有魔性呢?我们举个例子来说,首先,我们先给来一个空的 Grid 容器,
.grid-containter {
display: grid;
grid-template: repeat(3, 1fr) / repeat(3, 1fr);
gap: 10px;
}
<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>
这个时候你会得到像是这样的结果,
接下来,我们把 5 号的 Grid 容器指定一个 高度 的尺寸,
.grid-item:nth-of-type(5) {
height: 200px;
}
根据常识判断,我们这个 3x3
的容器,应该会变成第二列的高度为 200px
,然後其他列的尺寸应该会保持原本的 fit-content
的相关尺寸,对吧?
对吧?
不对!
为什麽?
根据官方轨道尺寸演算法 Track Sizing Algorithm 当中的第四点,
当你的剩余空间是无定义长度,换句话说以 row
的角度来看,他可以是 无限大 的情况下,必须根据以下法则来计算尺寸,
fr
来均分所有的轨道尺寸。fr
的尺寸。所以,我们把 5 号的 Grid 容器指定一个 高度 为 200px
的话,那麽 Grid 单元当中的最大贡献尺寸就是 200px
,所以对於 grid-template-rows
来说,他的 max-content
就会被当作 1fr
来使用。
我们先撇除那些对於会超出 Grid 轨道尺寸的东西,来讲讲 Grid 单元对齐这件事情。虽然我还是觉得,把 stretch
放在对齐模组里面实在是很奇怪,但好多年来都这样了好像也不能怎麽样(笑)。
先决条件,请不要把
margin
的任何方向设定为auto
。
首先,我们从空的容器来看,
.grid-containter {
display: grid;
grid-template: repeat(3, 400px) / repeat(3, 400px);
gap: 10px;
}
<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>
接着我们一样把第 5 号的 Grid 单元作一些设定,
.grid-item:nth-of-type(5) {
align-self: end;
justify-self: end;
}
那麽我们就会得到这样的结果,
你会发现我指定了 Grid 单元的尺寸,然後再把他做一个对齐的动作。这个时候聪明的你应该就会发现,其实 Grid 单元跟整个 Grid 轨道根本没有什麽太大的关系。
是的,Grid 轨道是轨道,Grid 单元是单元,没有直接的关系。
这也就是为什麽 Grid 单元尺寸超出轨道限制时,他就是很单纯的 超过轨道 了,而不会发生任何奇怪的事情的原因。
底下我们用一个简单的示意图来解释上面一堆关键字,
在这些关键字当中,self-*
的关键字主要会跟 writing mode 有关。由於我们平常所面对的系统都是 LTR(由左至右书写),所以当你遇到 RTL 的文本时,你使用 start
跟 self-start
就会出现差异。
我们可以用 direction: rtl
来模拟这种状况,
所以对於直式书写的设定也是一样的道理。这个就是对於 Grid 单元的对齐方式,这边之所以不提 stretch
的原因是,他本身就是将整个 Grid 单元填满轨道,所以既然已经 填满轨道 了,那麽就没有对齐的问题。
只要记得一件事情,
除了
stretch
以外,Grid 轨道尺寸不等於 Grid 单元尺寸。
剩下的我们明天再继续。
目录与小节:
[CSS] Flex/Grid Layout Modules, part 1
部落格同步放送:
[CSS] Flex/Grid Layout Modules, part 11
>>: [FGL] 服务简单收 - IMPORT 3 利用http与XML套件取 Web资源
可以先把下面的范例载下来,并执行app.py: https://github.com/wilsons...
图片来源 今天开始来分享在开赛前几篇的目标设定中Q1设定中一直提到的Go Smart Award,...
今天迈入第14天了,耶~~~今天的内容我也是很喜欢,尤其是自己调整背景颜色的实作,真的觉得非常有趣~...
Security https://wolkesau.medium.com/security-b198...
PyAutoGUI 一个可以用来控制键盘和滑鼠的套件 键盘控制 press(key) 按下再放开某键...