web布局15

CSS 網格布局除了提供定義網格和放置網格項目的相關屬性之外,也提供了一些控制對齊方式的屬性。這些控制對齊方式的屬性,和 Flexbox 布局中的對齊屬性 justify-*align-**-items*-content*-self 等是相似的:

img

在網格布局中可以用它們來控制網格項目在內聯軸(Inline Axis)和塊軸(Block Axis)的對齊方式;也可以用來控制網格軌道在內聯軸(Inline Axis)和塊軸(Block Axis)的對齊方式。

接下來,在這節課程中,我將演示網格布局中的對齊方式是如何工作的,你會發現很多屬性和值與 Flexbox 布局中的用法是類似的(Flexbox 布局對齊方式請參閱讀前面課程:《04 | Flexbox 布局中的對齊方式 》)。不過,網格布局是二維的,Flexbox 布局是一維的,所以你也會發現它們有一些小區別。我們就從處理網格對齊時用到的兩條軸線開始吧。

網格布局中的軸線

對于大多數開發者來說,他們都知道 Web 有兩根軸線:水平方向的 x 軸和垂直方向的 y 軸。只不過,在 Flexbox 布局中,不再稱 x 軸和 y 軸了,它由 Flexbox 中的主軸(Main Axis)和側軸(Cross Axis)替代了,并且 Flexbox 的主軸不再絕對的是 x 軸,側軸也不再絕對的是 y 軸,它由 flex-direction 屬性的值來決定:

img

由于網格布局是唯一的二維布局,因此,網格布局中也有兩條軸線,這兩條軸線既不稱為水平的 x 軸和垂直方向的 y 軸,也不像 Flexbox 布局中稱為主軸和側軸。它們有著新命名的兩條軸線,即內聯軸(Inline Axis)和塊軸(Block Axis):

  • 內聯軸(Inline Axis) :主要定義網站的文本流方向,也就是文本的閱讀方式,CSS 的 direction 或 HTML 的 dir 會影響內聯軸的方向。
  • 塊軸(Block Axis) :主要定義網站文檔(元素塊)流,CSS 的書寫模式 writing-mode 會影響塊軸的方向。

即,內聯軸和塊軸會受 CSS 的 directionwriting-mode 和 HTML 的 dir 屬性值的影響,這個有點類似于 Flexbox 布局的主軸和側軸,不是固定不變的:

img

網格布局中的內聯軸(Inline Axis)和塊軸(Block Axis)可以和網格中的行與列相映射,比如書寫模式和閱讀模式是 ltr(Left-To-Right)時,內聯軸也稱為行軸(Row Axis),塊軸也稱為列軸(Column Axis):

img

需要注意的是,雖然內聯軸(Inline Axis)和塊軸(Block Axis)會因 CSS 的書寫模式或文檔的閱讀模式改變,但網格中的行軸和列軸是始終不變的:

img

網格布局中,你就可以沿著這兩條軸線來控制網格項目或網格軌道的對齊方式。

特別聲明,如無特別指出,我們都以書寫模式和閱讀模式是 ltr (Left-To-Right)為例,即可內聯軸對應的是行軸,塊軸對應的是列軸

網格布局中的對齊方式

在 Flexbox 布局中,可以在 Flex 容器的主軸和側軸方向控制 Flex 項目的對齊方式。在 Grid 布局中,將按照內聯軸和塊軸兩個方向來控制 網格軌道網格項目 的對齊方式:

  • 控制“網格項目”沿塊軸方向的對齊屬性有: align-itemsalign-self ,其中 align-items 運用于網格容器上,align-self 運用于網格項目上。
  • 控制“網格項目”沿內聯軸方向的對齊屬性有:justify-itemsjustify-self ,其中 justify-items 運用于網格容器上,justify-self 運用于網格項目上。
  • 控制“網格軌道”沿塊軸方向對齊的屬性有:align-content ,該屬性運用于網格容器上。
  • 控制“網格軌道”沿內聯軸方向對齊的屬性有:justify-content ,該屬性運用于網格容器上。

也可以按下面這樣的方式來劃分:

  • 對齊網格項目justify-itemsjustify-self 沿著內聯軸方向對齊網格項目,而align-itemsalign-self 沿著塊軸方向對齊網格項目,其中 justify-itemsalign-items 被運用于網格容器,而 justify-selfalign-self 被運用于網格項目。
  • 對齊網格軌道align-content 沿著塊聯軸方向對齊網格軌道,justify-content 沿著內聯軸方向對齊網格軌道,它們都被運用于網格容器。

我們先來看網格項目的對齊。

網格項目對齊

控制網格項目的對齊方式的屬性主要有:

  • justify-itemsjustify-self 控制網格項目沿著內聯軸(文本書寫方向的行軸)方向對齊;
  • align-itemsalign-self 控制網格項目沿著塊軸(塊方向的列軸)方向的對齊。

這幾個屬性都可以接受 autonormalstartendcenterstretchbaselinefirst baselinelast baseline 值,但常用的值只有 startendcenterstretch (默認值)。其中 startcenterend 表示相應軸的起點位置,中心位置和終點位置:

img

注意,這幾個屬性都是用來控制網格項目在所處網格區域內的內聯軸或塊軸方向的對齊,如果沒有跨網格單元格,則在對應的網格單元格內的內聯軸或塊軸方向的對齊。

假設你有下面這樣的一個網格:

<div class="container"><div class="item"></div><!-- 此處省略四個 item --><div class="item"></div>
</div>
.container {display: grid;gap: 1rem;grid-template-columns: repeat(8, 1fr);grid-auto-rows: 80px;grid-auto-columns: 80px;grid-template-areas:"a a a a b b b b""a a a a b b b b""c c c c d d d d""c c c c d d d d";
}.item:nth-child(1) {grid-area: a;
}.item:nth-child(2) {grid-area: b;
}.item:nth-child(3) {grid-area: c;
}.item:nth-child(4) {grid-area: d;
}.item:nth-child(5) {grid-row: 1 / -1;grid-column: span 2;
}

上面的代碼構建了一個四行十列(4 x 10)的隱式網格,并且使用 grid-area 分別將網格項目放置到指定的網格區域:

  • 網格項目一放置在網格區域 a
  • 網格項目二放置在網格區域 b
  • 網格項目三放置在網格區域 c
  • 網格項目四放置在網格區域 d

使用 grid-rowgrid-column 將網格項目五放置指定的區域內(合并四行兩列),相當于放置在 grid-area: 1 / 9 / 5 ``/`` 11 區域內:

img

你可以在網格容器上顯式設置 align-items 屬性的值,比如:

.container {align-items: var(--align-items, stretch);
}

img

正如上圖所示:

  • start 將網格項目和所處網格區域在塊軸的起始位置重疊;
  • end 將網格項目和所處網格區域在塊軸的結束位置重疊;
  • center 將網格項目和所處網格區域在塊軸中心位置重疊(類似垂直居中);
  • stretch 將網格項目拉伸與所處網格區域高度相同,相當于與網格區域的塊軸方向起始、結束位置同時重疊(類似垂直方向的拉伸)。

另外,align-items 取值為 autonormallast baseline 值時,與取值 stretch 值效果等同;baselinefirst baseline 的效果與 start 等同:

img

Demo 地址:https://codepen.io/airen/full/zYavJow

一旦在網格容器上設置了 align-items 的值是 stretch 的其他值之后,所有網格項目的高度(塊軸方向尺寸,block-size)都將會由其內容的高度決定。另外,在網格容器上顯式設置了 align-items 的值,就相當于在所有網格項目上設置了 align-self 的值。比如:

.container {align-items: var(--align-items, stretch);
}/* 等同于 */
.container > * {align-self: var(--align-items, stretch);
}

當然,你也可以在單個網格項目上顯式設置 align-self 的值:

.item:nth-child(1) {align-self: start;
}.item:nth-child(2) {align-self: end;
}.item:nth-child(3) {align-self: center;
}

img

Demo 地址: https://codepen.io/airen/full/VwdvELO

你可以同時顯式設置網格容器的 align-items 和單個網格項目的 align-self 的值,只不過最終由網格項目上的 align-self 值來決定(沒有顯式設置 align-self 的網格項目則由 align-items 決定)。比如:

.container {align-items: var(--align-items, stretch);
}.item:nth-child(1) {align-self: center;
}

上面這個示例,網格項目一在塊軸方向始終是是垂直居中的,因為它顯式設置了 align-self 的值為 center ,其他網格項目在塊軸的對齊方式則由網格容器上的 align-items 屬性的值來決定:

img

Demo 地址: https://codepen.io/airen/full/NWzGOpp

align-itemsalign-self 相似的是,你可以在網格容器上設置 justify-items 屬性和在網格項目上設置 justify-self 屬性,控制網格項目在內聯軸的對齊方式。比如:

.container {justify-items: var(--justify-items, stretch);
}

img

正如上圖所示:

  • start 將網格項目和所處網格區域在內聯軸的起始位置重疊;
  • end 將網格項目和所處網格區域在內聯軸的結束位置重疊;
  • center 將網格項目和所處網格區域在內聯軸中心位置重疊(類似水平居中);
  • stretch 將網格項目拉伸與所處網格區域寬度相同,相當于與網格區域的內聯軸方向起始、結束位置同時重疊(類似水平方向的拉伸)。

同樣的,justify-items 取值是 autonormallast baseline 時與 stretch 值效果等同;baselinefirst baseline 的效果與 start 等同:

img

Demo 地址: https://codepen.io/airen/full/gOKaBvw

align-items 一樣,當你在網格容器上設置了 justify-items 時,就等同于在所有網格項目上設置了 justify-self

.container {justify-items: var(--justify-items, stretch);
}/* 等同于 */
.container > * {justify-self: var(--justify-items, stretch);
}

你也可以根據需要,在網格項目上單獨設置 justify-self 屬性的值,控制單獨網格項目在內聯軸方向的對齊:

.item:nth-child(1) {justify-self: start;
}.item:nth-child(2) {justify-self: center;
}.item:nth-child(3) {justify-self: end;
}

img

Demo 地址: https://codepen.io/airen/full/qBKOJLW

如果在網格容器上設置了 justify-items 屬性的值,并且在網格項目上也顯式設置了 justify-self 屬性的值,那么最終網格項目在內聯軸方向的對齊由 justity-self 屬性的值來決定。比如:

.container {justify-items: var(--justify-items, stretch);
}.item:nth-child(1) {justify-self: center; 
}

img

Demo 地址: https://codepen.io/airen/full/RwJWeOG

你可能已經發現了,當 justify-itemsjustify-self 屬性的值不是默認值 strecth 時,網格項目的寬度(內聯軸方向的尺寸,inline-size)就會發生變化,與 auto 值相似。

在網格布局中,justify-itemsalign-items 還可能簡寫成 place-itemsjustify-selfalign-self 可以簡寫成 place-self ,即:

place-items: <align-items>  <justify-items>
place-self:  <align-self>  <justify-self>

place-itemsplace-self 只取一個值時,表示兩個屬性的值相同,否則第一個值用于 align-* ,第二個值則用于 justif-* ,比如:

.container {place-items: center end;/* 等同于 */align-items: center;justify-items: end;
}.item:nth-child(1) {place-self: center end;/* 等同于 */align-self: center;justify-self: end;
}

注意,justify-items justify-self 兩屬性不能運用于 Flexbox 布局,主要是因為 Flexbox 布局是一個一維布局,在單個軸上有很多個元素(Flex 項目),無法單獨對齊其中某一個元素(Flex 項目)

不知道你是否已經發現了,在 Web 布局中,又多了兩種實現水平居中的布局技術。在網格布局中,你可以使用下面這兩種技術,讓某個元素(Grid 項目)水平垂直居中在另一個元素(網格區域)中:

<div class="container"><div class="item">我要水平垂直居中</div>
</div>
.container {display: grid;place-items: center;/* 等同于 */align-items: center;justify-items: center;
}.item {grid-area: 1 / 1 / -1 / -1;
}

img

Demo 地址: https://codepen.io/airen/full/YzvyRGN

上面這個示例效果,你還可以在網格項目上使用 place-self 來替代網格容器上的 place-items

.container {display: grid;
}.item {grid-area: 1 / 1 / -1 / -1;place-self: center;/* 等同于 */align-self: center;justify-self: center;
}

img

Demo 地址:https://codepen.io/airen/full/qBKbwKp

再次強調一下,justify-itemsalign-itemsjustify-selfalign-self 都是用來控制網格項目自身所處網格區域的內聯軸和塊軸方向的對齊,如果網格項目沒有明確放置,將按自動放置的算法來計算網格區域,一般就是網格單元格,因為網格單元格也是一個網格區域,網格中默認的最小網格區域:

.container {display: grid;grid-template-columns: repeat(3, 1fr);grid-auto-rows: 120px;gap: 1rem;/* 設置所有網格項目在內聯軸和塊軸方向的對齊 */place-items: var(--align-items, stretch)  var(--justify-items, stretch)
}/* 只設置網格項目一在內聯軸和塊軸方向的對齊 */
.item:nth-child(1) {place-self: var(--align-self, stretch)  var(--justify-self, stretch)
}

img

Demo 地址:https://codepen.io/airen/full/xxzwQpV

用下面這張圖來總結網格項目在內聯軸和塊軸上對齊方式的效果:

img

網格軌道對齊

CSS Grid 布局中的對齊方式和 Flexbox 布局中的對齊方式最大的不同之處是:

在網格布局中,除了可以控制網格項目在內聯軸和塊軸的方向對齊之外,還可以控制網格軌道在內聯軸和塊軸方向的對齊

在網格布局中,所有網格軌道尺寸所占據的空間可能會小于網格容器空間:

  • 內聯軸方向 :所有列網格軌道的尺寸總和小于網格容器內聯軸方向的尺寸(inline-size),即在 grid-template-columns (或 grid-auto-columns)定義的列軌道尺寸總和小于網格容器的寬度;
  • 塊軸方向 :所有行網格軌道的尺寸總和小于網格容器塊軸方向的尺寸(block-size),即在 grid-tempalte-rows (或 grid-auto-rows)定義的行軌道尺寸總和小于網格容器高度。

這樣你就可以分別在網格容器的:

  • 內聯軸方向justify-content 控制列網格軌道在內聯軸方向的對齊方式,即控制網格列的對齊;
  • 塊軸方向align-content 控制行網格軌道在塊軸方向的對齊方式,即控制網格行的對齊。

它們(justify-contentalign-content 屬性)可設置的值是:normalstartendcenterstretchspace-aroundspace-betweenspace-evenlybaselinefirst baselinelast baseline

同樣的,我們使用下面這個示例來向大家展示 justify-contentalign-content 取不同值的效果會是什么?

假設你有一個 500px x 500px 的網格容器,即網格容器的內聯軸方向的尺寸(inline-size)和塊軸方向尺寸(block-size)都是 500px 。使用 grid-template-columnsgrid-template-rows 定義了一個三行三列(3 x 3 )的網格,并且網格軌道尺寸都是 100px ,同時網格軌道之間有 10px 的間距:

.container {inline-size: 500px;block-size: 500px;display: grid;gap: 10px;grid-template-columns: repeat(3, 100px);grid-template-rows: repeat(3, 100px);
}

img

可以像 Flexbox 布局中的 justify-contentalign-content 一樣,將剩余空間分配到網格軌道之間。

在網格容器上將 align-content 設置不同值:

.container {align-content: var(--align-content, start);
}

img

Demo 地址:https://codepen.io/airen/full/MWXKjVj

你會發現,在這個示例中,align-content 取值為 normalstretchbaselinefirst baselinelast baseline 的效果與 start 是等同的。事實上,algin-content 取值 stretch 時會對網格軌道進行拉伸,但并不是所有情景都是如此,它對網格軌道尺寸的設置是有一定要求的。有關于這方面,我們將放到后面與 justify-content 統一闡述。

img

雖然說 align-content 是用來控制網格行軌道在網格容器塊軸方向的對齊方式,但從另一個角度來說,也是將網格容器的剩余空間分配給網格軌道之間。比如:

align-content 取值為 center 時,網格容器的剩余空間將一分為二,第一行網格軌道在塊軸的起始位置與網格容器塊軸方向超始位置的距離等于最后一行網格軌道在塊軸的結束位置與網格容器塊軸方向結束位置的距離:

img

如果網格容器只有一行行網格軌道時,可以實現垂直居中的效果

align-content 取值為 space-around 時,分配給相鄰兩行網格道之間的網格容器的剩余空間,是第一行網格軌道塊軸起始位置距網格容器塊軸方向起始位置之間距離的兩倍,也是最后一行網格軌道塊軸結束位置距網格容器塊軸方向結束位置之間距離的兩倍。

img

align-content 取值 space-evenly 的效果和 space-around 有點相似,只不過,分配給相鄰兩行網格軌道之間的網格容器的剩余空間,和第一行網格軌道塊軸方向起始位置與網格容器塊軸方向起始位置之間的距離相等,也和最后一行網格軌道塊軸方向結束位置與網格容器塊軸方向結束位置之間的距離相等:

img

align-content 取值為 space-between 會令行網格軌道在網格容器塊軸方向兩端對齊,即網格容器的剩余空間會平均分配到相鄰兩行行網格軌道之間:

img

需要注意的是,當行網格軌道的尺寸是 fr 值時,align-content 取任何值的效果都和其默認值 start 等同。比如:

.container {grid-template-rows: 1fr 100px 100px;/* 或 */grid-template-rows: minmax(100px, 1fr) 100px 100px;/* 或 */grid-auto-rows: 1fr;
}

img

Demo 地址: https://codepen.io/airen/full/poKgeMR

也就是說,當網格容器沒有剩余空間時,align-content 各值的效果都相同,即等同于 align-content start (默認值效果)

既然網格容器有剩余空間,也就有可能會有不足空間出現,比如將示例中的行網格軌道尺寸設置為:

.container {grid-template-rows: 70% 120px 120px; 
}

網格項目溢出網格容器:

img

Demo 地址: https://codepen.io/airen/full/dyKGWYa

網格項目溢出網格容器時,align-content 取值不同時,溢出方向也有所差異:

  • start ,網格項目在網格容器塊軸方向結束位置溢出;
  • end ,網格項目在網格容器塊軸方向起始位置溢出;
  • center ,網格項目在網格容器塊軸兩個方向溢出;
  • stretchstart 等同;
  • space-aroundcenter 等同;
  • space-betweenstart 等同;
  • space-evenlycenter 等同。

img

在網格容器上顯式設置 align-content 值時,還有可能會造成網格區域變大。比如下面這個示例,網格項目一合并了兩行兩列。當 align-content 取值 space-aroundsapce-evenlyspace-between 時,行網格軌道之間的間距就會產生變化,這樣對于合并多行的網格項目一來說,尺寸(塊軸方向尺寸,block-size)也會產生相應變化:

.container {inline-size: 500px;block-size: 500px;display: grid;gap: 10px;grid-template-columns: repeat(3, 100px);grid-template-rows: repeat(3, 100px);
}.item:nth-child(1) {grid-row: 1 / span 2;grid-column: 1 / span 2;
}

img

Demo 地址:https://codepen.io/airen/full/OJEMmxN

上面看到的都是行網格軌道在網格容器塊軸方向的對齊方式(分配網格容器塊軸方向剩余空間)。接下來在前面的示例基礎上,將 align-content 換成 justify-content

.container {justify-content: var(--justify-content, start);
}

不難發現,justify-content 取值和 align-content 值效果是相同的,唯一不同的是, justify-content 是用來控制列網格軌道在網格容器的內聯軸方向的對齊方式,即 分配網格容器內聯軸方向的剩余空間

img

Demo 地址:https://codepen.io/airen/full/eYKJWer

justify-content 取值為 centerspace-aroundspace-evenlyspace-between 分配網格容器內聯軸方向剩余空間如下:

img

注意,如果網格只有一列,****justify-content 取值 center 可以實現水平居中效果

如果 grid-tempalte-columnsgrid-auto-columns 設置列網格軌道尺寸時,設置了 fr 單位值,那么 justify-content 取任何值的效果都與默認值 start 等同:

.container {grid-template-columns: minmax(100px, 1fr) 100px 100px;
}

img

Demo 地址: https://codepen.io/airen/full/yLEeXOR

網格項目在內聯軸方向溢出網格容器時,justify-content 取值不同,溢出方向也有所差異:

  • start ,網格項目在網格容器內聯軸方向結束位置溢出;
  • end ,網格項目在網格容器內聯軸方向起始位置溢出;
  • center ,網格項目在網格容器內聯軸兩個方向溢出;
  • stretchstart 等同;
  • space-aroundcenter 等同;
  • space-betweenstart 等同;
  • space-evenlycenter 等同。
.container {grid-template-columns: 70% 120px 120px;
}

img

Demo 地址:https://codepen.io/airen/full/oNybwWx

justify-contentalign-content 一樣,取值為 space-aroundspace-evenlyspace-between 會影響網格區域內聯尺寸方向的尺寸(inline-size),即寬度會變大:

img

Demo 地址: https://codepen.io/airen/full/YzvwQrN

剛才有提到過,align-contentjustify-content 在我們演示的示例中取值為 stretch 的效果和 start 是一樣的。這主要是因為示例中的網格軌道尺寸是一個固定值,你可以嘗試將示例中的 grid-template-columnsgrid-template-rows 中的值調整為 auto 100px auto ,即有些軌道尺寸由內容來決定:

.container {grid-template-columns: auto 100px auto;grid-template-rows: auto 100px auto;justify-content: stretch;align-content: stretch;
}

那么,

  • justify-content 取值為 stretch 時,設置內在尺寸的列網格軌道在內聯軸方向會被拉伸,網格項目會沿著網格容器的內聯軸方向填滿(整個網格容器內聯軸方向可用空間);
  • align-content 取值為 stretch 時,設置內在尺寸的行網格軌道在塊軸方向被拉伸,網格項目會沿著網格容器塊軸方向填滿(整個網格容器塊軸方向可用空間)。

img

Demo 地址: https://codepen.io/airen/full/GRGoEwQ

另外,當網格項目因合并網格單元格創建了一個隱式網格,并且隱式網格軌道尺寸為 auto 時,justify-cotentalign-content 取值為 stretch 時,同樣會對網格項目進行拉伸:

.container {inline-size: 500px;block-size: 500px;display: grid;gap: 10px;grid-template-columns: repeat(3, 100px);grid-template-rows: repeat(3, 100px);grid-auto-flow: dense;justify-content: stretch;align-content: stretch;
}.item:nth-child(1) {grid-row: 1 / span 2;grid-column: 1 / span 2;
}.item:nth-child(5) {grid-column: 3 / span 2;
}

img

Demo 地址: https://codepen.io/airen/full/GRGoEwQ

在使用的時候,你還可以將 justify-contentalign-content 簡寫成 place-content ,即:

place-content: <align-content> <justify-content>

place-content 只有一個值時,表示 align-contentjustify-content 值相同,如果有兩個值時,第一個值是 align-content ,第二個則是 justify-content

.container {place-content: center end;/* 等同 */align-content: center;justify-content: end;place-content: center;/* 等同 */align-content: center;justify-content: center;
}

這樣一來, Web 中又多了一種實現水平垂直居中的布局效果,即 place-content 屬性的值設置為 center 。不過,使用 place-content 實現水平垂直居中,它有一個條件限制,網格容器中只有一個網格軌道,即 需要在網格容器中水平垂直居中的元素,它既是行網格軌道,也是列網格軌道

<div class="container"><div class="item">我需要水平垂直居中</div>
</div>
.container {display: grid;place-content: center;
}

img

Demo 地址:https://codepen.io/airen/full/XWYmypr

用下圖簡單地總結一下,網格容器上設置 justify-contentalign-content 屬性的值,網格軌道的對齊方式如下:

img

Demo 地址: https://codepen.io/airen/full/RwJrXrQ

網格布局中,你可以同時使用多個對齊屬性來控制網格中的對齊(網格項目或網格軌道),比如:

.container {justify-content: space-evenly;justify-items: center;align-content: space-evenly;align-items: center;/* 等同于 */place-content: space-evenly;place-items: center;
}

正如你所看到的,由于可用于網格布局中的對齊屬性很多種,如果你對網格布局中的對齊屬性不是很了解的話,往往設置了對齊屬性,卻達不到預期的效果。這里有一個小技巧,你在網格布局中使用網格對齊相關的屬性時,你需要做確認:

  • 你是要對網格軌道設置對齊嗎?如果是,使用 place-content 屬性;如果希望只控制網格軌道沿著網格容器塊軸方向的對齊,則使用 align-content;如果希望只控制網格軌道沿著內聯軸方向的對齊,則使用 justify-content
  • 你是要對所有網格項目設置對齊嗎?如果是,使用 place-items 屬性;如果希望只控制網格項目沿著網格區域塊軸方向對齊,則使用 align-items ;如果希望只控制網格項目沿著網格區域內聯軸方向對齊,則使用 justify-items
  • 你是要對單個網格項目設置對齊嗎?如果是,使用 place-self 屬性;如果只希望控制單個網格項目沿著網格區域塊軸方向對齊,則使用 align-self ;如果只希望控制單個網格項目沿著網格區域內聯軸方向對齊,則使用 justify-self

比如下面這樣的一個示列:

<div class="container"><div class="item"></div><!-- 這里省略七個 item --><div class="item"></div></div>
.container {inline-size: 100%;max-width: 50vw;margin: 0 auto;aspect-ratio: 1;display: grid;gap: 1rem;grid-template-columns: repeat(2, 120px auto);grid-auto-rows: 120px auto;grid-auto-flow: dense;
}.item:nth-child(1) {grid-row: span 2;grid-column: span 2;
}

使用上面的代碼,構建了一個像下面這樣的網格,其中網格項目一合并了兩行兩列:

img

目前為止,并沒有顯式地設置任何與對齊有關的屬性。事實上,它相當于在網格容器上顯式設置了 place-items 的值為 stretch ,即:

.container {place-items: var(--align-items, stretch)  var(--justify-items, stretch);
}

因為網格項目的 place-items (即 align-itemsjustify-items)的默認值是 stretch 。它也相當于在所有網格項目上設置了 place-self 的值為 stretch

.container > * {place-self: var(--align-self, stretch) var(--justify-self, stretch);
}

當你在網格容器 .container 顯式設置 place-items 的值不是 stretch (非默認值)時,那么所有網格項目的對齊方式都會得到改變:

img

這個時候,要是你在單個網格項目上(比如網格項目一)顯式設置了 place-self 的值為 stretch ,你會發現網格項目一在合并的網格區域的塊軸和內聯軸方向都會被拉伸,填滿整個網格區域。即使是網格容器上顯式設置了 place-items 的值為 center stretch

.container {place-items: center stretch;
}.item:nth-child(1) {place-self: stretch;
}

img

單個設置 place-self 的權重要大于在網格容器上設置的 place-items。正如你所看到的,網格項目一最終以自身 place-self 的值來控制對齊方式:

img

需要注意的是,place-content 的默認值是 start ,但這并不意味著網格容器默認就是 place-content 取值 start 的效果。就拿上面這個示例來說,在網格容器上設置 place-content 屬性值為 start 前后的效果是不一樣的:

img

也就是說,如果網格容器上未顯式設置 place-content 時,并不會以默認的 place-content: start 來控制網格軌道的對齊

換句話說,只要在網格容器上顯式設置了 place-content 屬性(或它的子屬性 align-contentjustify-content)的值,就會改變設置值為 auto 的軌道尺寸,也會改變網格軌道之間的間距,但它不會改變網格項目的對齊方式。

你也可以簡單的這么理解:

  • place-content 改變網格的對齊方式和網格軌道之間的間距,但不會改變網格項目在網格區域的對齊方式;
  • place-itemsplace-self 會改變網格項目在網格區域的對齊方式,同時也會改變網格項目的尺寸,但不會改變網格軌道之間的間距;
  • place-items 用于網格容器,會改變所有網格項目;place-self 用于網格項目,只會改變設置了該值的網格項目。

img

Demo 地址:codepen.io

網格項目的 margin:auto

通過前面課程的學習,你已經知道了在 Flex 項目中設置 margin 屬性的值為 auto 時,可以達到 Flex 項目對齊的效果:

img

網格布局中,在網格項目上設置 margin 的值為 auto 時也能達到相似的效果。比如:

img

Demo 地址: https://codepen.io/airen/full/YzvqKgz

正如你所看到的,在網格布局中,你可以在網格項目上顯式設置 margin: auto 實現水平垂直居中的效果:

.container {display: grid;
}.item {grid-area: 1 / 1 / -1 / -1;margin: auto;
}

img

Demo 地址: https://codepen.io/airen/full/xxzVxoV

除了在網格項目上顯式設置 margin 的值為 auto 之外,也可以將其設置為 <length-percentage> 值,用來控制網格項目之間的間距。不過,它和網格容器上的 gap 屬性還是有所區別的:

  • gap 是用來設置網格軌道之間的間距;
  • margin 是用來設置網格項目外側邊緣和網格區域邊緣之間的間距。

img

你會發現,網格項目上設置 margin 值時,網格項目會向里收縮!另外,網格布局中網格項目或網格軌道的對齊都是沿著網格容器的塊軸方向或內聯軸方向,所以使用 margin 值為 auto 達到對齊效果時,更建議采用相應的邏輯屬性,比如:

  • magin-inline-start 替代 margin-left ,相當于在網格項目上設置 justify-self: end
  • margin-inline-end 替代 margin-right ,相當于在網格項目上設置 justify-self: start
  • margin-block-start 替代 margin-top ,相當于在網格項目上設置 align-self: end
  • margin-block-end 替代 margin-bottom ,相當于在網格項目上設置 align-self: start

你也可以設置:

  • margin-inline 的值為 auto 實現水平居中,等同于 justify-self: center
  • margin-block 的值為 auto 實現垂直居中,等同于 align-self: center

小結

網格布局中的對齊和 Flexbox 布局中的對齊有點相似,只不過網格布局中主要分為三種使用情景:

  • place-content (它的子屬性 align-contentjustify-content)控制網格軌道在網格容器的塊軸和內聯軸方向的對齊;
  • place-items (它的子屬性 align-itemsjustify-items )控制所有網格項目在網格區域的塊軸和內聯軸方向的對齊;
  • place-self (它的子屬性 align-selfjustify-self )控制單個網格項目在網格區域的塊軸和內聯軸方向的對齊。

它的 Flexbox 布局的 align-contentjustify-contentalig``n-items 以及 align-self 還是有所差異的:

對齊屬性Flexbox 布局中的對齊Grid 布局中的對齊備注
align-contentFlex行在 Flexbox 容器側軸方向的對齊行網格軌道在網格容器的塊軸方向的對齊Flex 行是指 Flexbox 容器上顯式設置 flex-wrap 的值為 wrapwrap-reverse 產生斷行。每個 Flex 行都有主軸和側軸方向
justify-contentFlex 項目在 Flex 容器主軸方向的對齊列網格軌道在網格容器的內聯軸方向的對齊
place-contentplace-content: <align-contetn> <justify-content>
align-itemsFlex 項目在 Flex 容器側軸方向的對齊所有網格項目在網格區域的塊軸方向的對齊
justify-items所有網格項目在網格區域的內聯軸方向的對齊Flexbox 布局中不支持 justify-items
place-itemsplace-items: <align-items> <justify-items>
align-self單個 Flex 項目在 Flex 容器側軸方向的對齊單個網格項目在網格區域的塊軸方向的對齊
justify-self單個網格項目在網格區域的內聯軸方向的對齊Flexbox 布局中不支持 justify-self
place-selfplace-self: <align-self> <justify-self>

不管是 Flexbox 布局中的對齊還是網格布局中的對齊,它們都受 CSS 的書寫模式或閱讀模式的影響!

另外,網格布局中的網格項目上,也可以顯式設置 margin 的值來達到單個網格項目對齊,這個和 Flexbox 布局中的 Flex 項目設置 margin: auto 是等同的:

屬性:值Flexbox 布局Grid 布局
margin-left: auto如果 Flexbox 容器中只有一個 Flex 項目時,等同于在 Flex 容器上設置 justify-content 的值為 flex-endend等同于在網格項目上設置 justify-self: end如果 Grid 容器中只有一個 Grid 項目時,等同于在網格容器上設置 justify-items: endjustify-content: end
margin-right: auto如果 Flexbox 容器中只有一個 Flex 項目時,等同于在 Flex 容器上設置 justify-content 的值為 flex-startstart等同于在網格項目上設置 justify-self: start 如果 Grid 容器中只有一個 Grid 項目時,等同于在網格容器上設置 justify-items: startjustify-content: start
margin-top: auto等同于在 Flex 項目上設置 align-self: endalign-self: flex-end 如果 Flexbox 容器中只有一個 Flex 項目時,等同于在 Flexbox 容器上設置 align-items 的值為 endflex-end等同于在 Grid 項目上設置 align-self: end 如果 Grid 容器中只有一個 Grid 項目時,等同于在 Grid 容器上設置 align-items: endalign-content: end
margin-bottom: auto等同于在 Flex 項目上設置 align-self: startalign-self: flex-start 如果 Flexbox 容器中只有一個 Flex 項目時,等同于在 Flexbox 容器上設置 align-items 的值為 startflex-start等同于在 Grid 項目上設置 align-self: start 如果 Grid 容器中只有一個 Grid 項目時,等同于在 Grid 容器上設置 align-items: startalign-content: start

不管是在 Flexbox 布局中還是 Grid 布局中,在 Flex 項目或 Grid 項目上設置:

  • magin-inline: auto 可以實現水平居中;
  • margin-block: auto 可以實現垂直居中。

需要注意的是,因為 Flexbox 布局是一種一維布局,所以在 Flexbox 布局中沒有 justify-itemsjustify-self 兩個屬性!

到這里,小冊分了兩節課分別介紹了 Flexbox 和 Grid 布局中的對齊。兩個布局模塊中都有相同的屬性以及值,但所起的作用是略有差異的,但也有互通的。因此,在 CSS 規范中,將它們都納入了 CSS Box Alignment 模塊中。不過,在我們小冊中不做展開性的闡述。因此,有關于對齊的部分我們就介紹到這里了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86116.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86116.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86116.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

leetcode 291. Word Pattern II和290. Word Pattern

目錄 291. Word Pattern II 290. Word Pattern 291. Word Pattern II 回溯法哈希表 class Solution {unordered_map<char,string> hashmap;unordered_set<string> wordset; public:bool wordPatternMatch(string pattern, string s) {return backtrack(pattern,…

大模型的開發應用(十三):基于RAG的法律助手項目(上):總體流程簡易實現

RAG法律助手項目&#xff08;上&#xff09;&#xff1a;總體流程簡易實現 1 項目介紹1.1 方案選型1.2 知識文檔 2 文檔解析3 知識庫構建3.1 構建知識節點3.2 嵌入向量初始化3.2 向量存儲 4 查詢4.1 初始化大模型4.2 模型響應4.2 本文程序存在的問題 完整代碼 1 項目介紹 本項…

覆蓋遷移工具選型、增量同步策略與數據一致性校驗

1 引言 在當今數據驅動的時代&#xff0c;數據遷移已成為系統迭代、數據庫升級、云遷移和架構演進中的關鍵環節。根據Gartner的調研&#xff0c;超過70%的企業級數據遷移項目因工具選擇不當或同步策略缺陷而延期或失敗。數據遷移不僅僅是簡單的數據搬運&#xff0c;而是涉及數…

`docker run -it --rm` 筆記250624

docker run -it --rm 筆記250624 docker run -it --rm 是一個強大且常用的 Docker 命令組合&#xff0c;特別適合交互式開發和調試場景。以下是詳細解析和使用指南&#xff1a; 參數解析 參數作用典型場景-i保持 STDIN 打開&#xff08;交互模式&#xff09;需要輸入命令的交…

解鎖阿里云AnalyticDB:數據倉庫的革新利器

AnalyticDB&#xff1a;云數據倉庫新勢力 在數字化浪潮中&#xff0c;數據已成為企業的核心資產&#xff0c;而云數據倉庫作為數據管理與分析的關鍵基礎設施&#xff0c;正扮演著愈發重要的角色。阿里云 AnalyticDB 作為云數據倉庫領域的佼佼者&#xff0c;以其卓越的性能、創…

【PX30 Qt 5.15 交叉編譯環境搭建完整指南】

PX30 Qt 5.15 交叉編譯環境搭建完整指南 (Ubuntu 20.04 → PX30 aarch64) &#x1f3af; 項目概覽 本指南詳細記錄了在Ubuntu 20.04上搭建針對Rockchip PX30的Qt 5.15.2交叉編譯環境的完整過程&#xff0c;包括實際操作步驟、遇到的問題及解決方案。 目標平臺: Rockchip PX3…

深入理解讀寫鎖 ReadWriteLock

在高性能并發編程中&#xff0c;如何有效地管理共享資源的訪問是核心挑戰之一。傳統的排他鎖&#xff08;如ReentrantLock&#xff09;在讀多寫少的場景下&#xff0c;性能瓶頸尤為突出&#xff0c;因為它不允許并發讀取。Java并發包&#xff08;java.util.concurrent.locks&am…

Unity Addressable使用之檢測更新流程

補充知識 關鍵文件說明 Addressable打包后會生成多種文件&#xff0c;主要包括 .hash、.json 和 .bundle 文件&#xff0c;它們各自有不同的作用。 .hash 文件&#xff08;哈希文件&#xff09; 作用&#xff1a; 用于 版本對比&#xff0c;檢查資源是否有更新。存儲的是 資…

Elasticsearch 中實現推薦搜索(方案設想)

1. 存儲商品數據的數據類型 為了支持推薦搜索&#xff0c;商品數據通常需要包含以下字段&#xff1a; 商品索引結構 PUT /products {"mappings": {"properties": {"product_id": {"type": "keyword" // 商品 ID},"…

Aerotech系列(4)Aerotech.A3200名空間

IconTypeDescriptionAxisMask Represents a selection of axes Controller Represents a controller Allows configuring and c

React Router 是怎么實現靈活導航的?

&#x1f399; 歡迎來到《前端達人 React播客書單》第 21 期。 視頻版&#xff08;播客風格更精彩&#xff09; 今天我們不講 Hook&#xff0c;來拆解前端開發中另一個高頻組件&#xff1a;React Router 的進階導航模式。 你可能用過 <Link> 或 <Route>&#xff0…

Modbus TCP轉Profibus DP網關與JF - 600MT 稱重變送器輕松實現數據互換

Modbus TCP轉Profibus DP網關與JF - 600MT 稱重變送器輕松實現數據互換 在工業自動化領域&#xff0c;不同設備之間的通信與數據交互至關重要。Modbus TCP轉Profibus DP網關作為連接不同協議設備的關鍵橋梁&#xff0c;發揮著不可或缺的作用。本文將以JF - 600MT稱重變送器與3…

聊聊 SQL 注入那些事兒

相信大家對于學校們糟糕的網絡環境和運維手段都早有體會&#xff0c;在此就不多做吐槽了。今天我們來聊一聊SQL注入相關的內容。 何謂SQL注入&#xff1f; SQL注入是一種非常常見的數據庫攻擊手段&#xff0c;SQL注入漏洞也是網絡世界中最普遍的漏洞之一。大家也許都聽過某某學…

多傳感器融合

目錄 多傳感器融合 多傳感器融合的方向 傳感器融合方案介紹 LOAM LIO-SAM LVI-SAM 多線激光雷達性質 什么是運動畸變 兩步優化的幀間里程記 IMU 器件介紹及選型建議 IMU 標定方法簡介 視覺里程計 VS 激光里程計 LVI-SAM 激光視覺融合思路簡介 多傳感器融合工程實踐經驗與技巧 多…

Auto-GPT vs ReAct:兩種智能體思路對決

目錄 Auto-GPT vs ReAct&#xff1a;兩種智能體思路對決 &#x1f9e0; 一、智能體的演化背景 &#x1f9e9; 二、Auto-GPT&#xff1a;自循環的執行體 &#x1f50d; 三、ReAct&#xff1a;推理 行動的交錯協同 ?? 四、對比總結 &#x1f6e0; 五、你該選誰&#xff…

本地部署大模型性能測試,DeepSeek-R1-0528-Qwen-8B 依然是我的不二之選

大家好&#xff0c;我是 ai 學習的老章 介紹一個大模型并發性能測試工具 看一下我高頻使用的&#xff0c;在2*4090顯卡上部署的 DeepSeek-R1-0528-Qwen-8B 性能如何 _我_特別喜歡的三個DeepSeek版本 DeepSeek-R1-0528 蒸餾 Qwen3:8B 大模型&#xff0c;雙 4090 本地部署&am…

華為云Flexus+DeepSeek征文|華為云 Dify 高可用部署教程:CCE 容器集群一鍵構建企業級智能應用

前言 在數字化轉型加速的企業級應用場景中&#xff0c;構建高可用智能平臺已成為業務創新的核心驅動力。本文深度解析基于華為云CCE容器服務的Dify智能應用部署實踐&#xff0c;揭示如何通過云原生架構與AI技術的深度融合&#xff0c;實現企業知識管理、智能客服等場景的敏捷落…

Linux 多進程間通信(IPC)詳解

在 Linux 系統中,多進程通信(Inter-Process Communication, IPC) 是實現多個進程之間數據交換和同步的重要機制。由于每個進程擁有獨立的地址空間,因此需要借助特定的系統機制來實現信息共享。 ?? Linux 下常見的 6 種進程間通信方式 管道(Pipe)命名管道(FIFO)消息隊…

服務器數據恢復——異常斷電導致服務器故障的數據恢復案例

服務器數據恢復環境&#xff1a; 某服務器上有一組由12塊硬盤組建的raid5磁盤陣列。 機房供電不穩定導致機房中該服務器非正常斷電&#xff0c;重啟服務器后管理員發現服務器無法正常使用。 意外斷電可能會導致服務器上的raid模塊損壞。 服務器數據恢復過程&#xff1a; 1、將故…

微信小程序中 rpx與px的區別

在微信小程序中的rpx比px方便的多 <!--pages/welcome/welcome.wxml--> <!--rpx替換px--> <image style"width:200rpx;height: 200rpx"src"/images/avatar/3.png"></image> <text>你好&#xff0c;凍梨</text> <but…