天天看點

如何使用CSS 新文法grid-area來設定網格布局

作者:三維棱鏡prism3dcn

grid-area CSS 屬性是一種簡寫,它通過在一個聲明中設定網格行開始、網格列開始、網格行結束和網格列結束的值來指定網格布局中網格項的位置和大小。

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

.grid-item:nth-child(2) {
  grid-area: 2 / 4 / 4 / 6;

  /* is equivalent to: */
  grid-row-start: 2;
  grid-column-start: 4;
  grid-row-end: 4;
  grid-column-end: 6;
} 
           

由于 CSS Grid 的預設自動放置行為,此示例中的第二個網格項通常放置在網格第一行的第二列中。但是,由于我們聲明了網格面積并将其設定為将網格項的起始邊緣和結束邊緣與我們所需的網格線對齊,是以該項移動到第二行和第四列,并在兩個方向上跨越兩條軌道,以滿足正确的結束網格線。

如何使用CSS 新文法grid-area來設定網格布局

使用網格區域 CSS 屬性設定第二個網格項的位置和大小。

成分屬性

如前所述,網格區域屬性是結合了四個屬性的簡寫s:

grid-column-start

.element { grid-column-start: 3; }

grid-column-end

.element { grid-column-end: 4; }

grid-row-start

.element { grid-row-start: 2; }

grid-row-end

.element { grid-row-end: 3; }

Syntax 文法

grid-area: <grid-line> [ / <grid-line> ]{0,3}           

此屬性最多可以采用四個值,由正斜杠 (/) 分隔。

設定四個值

如果 <grid-line> 設定了

  • 第一個值設定網格行開始屬性。
  • 第二個值設定網格列開始屬性。
  • 第三個值設定網格行結束屬性。
  • 第四個值設定網格列結束屬性。
.grid-item {
  grid-area: 2 / 4 / 3 / 6;

  /* is equivalent to: */
  grid-row-start: 2;
  grid-column-start: 4;
  grid-row-end: 3;
  grid-column-end: 6;
} 
           

設定三個值

  • 第一個值設定網格行開始屬性。
  • 第二個值設定網格列開始屬性。如果值為 <custom-ident>.否則,網格列端設定為 auto。
  • 第三個值設定網格行結束屬性。
/* <custom-ident> */
.grid-item {
  grid-area: 2 / area / 4;
  
  /* is equivalent to */
  grid-row-start: 2;
  grid-column-start: area;
  grid-row-end: 4;
  grid-column-end: area;
}

/* <grid-line> */
.grid-item {
  grid-area: 2 / 4 / 3;

  /* is equivalent to: */
  grid-row-start: 2;
  grid-column-start: 4;
  grid-row-end: 3;
  grid-column-end: auto;
} 
 
           

設定兩個值

  • 第一個值設定網格行開始屬性。如果值為 <custom-ident>.否則,網格行結束設定為自動。
  • 第二個值設定網格列開始屬性。如果值為 <custom-ident>.否則,網格列端設定為 auto。
/* <custom-ident> */
.grid-item {
  grid-area: area / 4;
  
  /* is equivalent to */
  grid-row-start: area;
  grid-column-start: 4;
  grid-row-end: area;
  grid-column-end: auto;
}

/* another <custom-ident> example */
.grid-item {
  grid-area: area / another-area;
  
  /* is equivalent to */
  grid-row-start: area;
  grid-column-start: another-area;
  grid-row-end: area;
  grid-column-end: another-area;
}

/* <grid-line> */
.grid-item {
  grid-area: 2 / 4;

  /* is equivalent to */
  grid-row-start: 2;
  grid-column-start: 4;
  grid-row-end: auto;
  grid-column-end: auto;
} 
 
 
           

設定1個值

/* <custom-ident> */
.grid-item {
  grid-area: area;
  
  /* is equivalent to */
  grid-row-start: area;
  grid-column-start: area;
  grid-row-end: area;
  grid-column-end: area;
}

/* <grid-line> */
.grid-item {
  grid-area: 2;

  /* is equivalent to */
  grid-row-start: 2;
  grid-column-start: auto;
  grid-row-end: auto;
  grid-column-end: auto;
} 
 
           

了解此文法

基于值數量的不同方案 <custom-ident> - 更不用說案例 - 乍一看可能看起來很複雜和奇怪。但如果你仔細想想,這一切都是有道理的。

以以下網格項為例:

.grid-item {
  grid-area: 2 / 4 / 3;
}           

在這裡,省略了grid-column-end(因為這是一個三值文法),grid-column-start設定為 4。grid-column-end 屬性不能也為 4,因為網格項的起始邊緣和結束邊緣将指向同一行。浏覽器不會将起始邊緣與 4 對齊,并将網格項跨越一列作為預設行為。這就是為什麼當一條邊沒有值時,它會設定為自動——以防它的另一條邊指向帶有數值的網格線。

現在,如果将網格列開始值設定為名稱怎麼辦?例如,用 x 代替 4:

.grid-item {
  grid-area: 2 / x / 3;
}           

X 值可以是網格線或網格區域的名稱。如果有一條名為 x 的網格線,則網格列端也設定為 x,但由于網格項的兩個列邊緣都指向同一網格線 — x — 浏覽器的預設行為再次是充當好像網格列結束設定為自動并且網格項跨越一列。

另一方面,如果存在一個名為 x 的網格區域,則 grid-column-start 設定為該網格區域的起始邊緣,而 grid-column-end 設定為其結束邊緣。

當你在代碼中看到它時,更容易了解所有這些:

.grid-item {
  grid-area: 2 / x / 3;

  /* is equivalent to */
  grid-row-start: 2;
  grid-column-start: x-start;
  grid-row-end: 3;
  grid-column-end: x-end;
} 
           

/* Keyword value */
grid-area: auto;

/* <custom-ident> value */
grid-area: my-area;
grid-area: main-start / sidebar-start;
grid-area: main-start / sidebar-start / footer-start / main-end;
grid-area: line1 / line2 / line3 / line4;

/* <integer> + <custom-ident> values */
grid-area: 3;
grid-area: 2 / -3;
grid-area: main 2;
grid-area: 2 a / 4 b / 2 x;

/* span + <integer> + <custom-ident> values */
grid-area: span 3;
grid-area: 1 / 3 / span 2 / 5;
grid-area: 1 / span myline;
grid-area: 2 / span gridline 3;

/* Global values */
grid-area: inherit;
grid-area: initial; /* same as `auto` */
grid-area: revert;
grid-area: revert-layer;
grid-area: unset;           

auto

這是預設值。它訓示預設範圍 (1) 和自動放置行為,這意味着網格項将自動放置在下一個可用的空網格單元格中。

<custom-ident>

此文法允許您使用整數來引用編号的網格線,或使用字元串來引用命名網格線或命名網格區域。換句話說,可以通過網格項邊緣的數字索引或名稱來指定網格線。

按行号定位項目

每個網格軌道之前和之後都有兩條網格線,從數字 1 開始,自動為其配置設定一個數字索引。

如何使用CSS 新文法grid-area來設定網格布局

示範行和列網格軌道的索引。

在本文的第一個示例中,我們使用此文法通過索引(2 和 4)引用第二行和第四行網格線,以将網格項的開始邊緣和結束邊緣與第二行和第三行的開始邊緣和結束邊緣對齊。此外,我們參考第四列和第六列網格線,将網格項的開始和結束邊緣與第四列和第五列的開始和結束邊緣對齊。

.grid-item:nth-child(2) {
  grid-area: 2 / 4 / 4 / 6;
}           

請注意,您也可以使用負數來指代網格線,但它從網格的結束邊緣開始計數。以下代碼指向上一示例中的相同網格線,但計數相反:

.grid-item:nth-child(2) {
  grid-column: -4 / -4 / -2 / -2; /* same as: grid-area: 2 / 4 / 4 / 6; */
}           

請注意,負整數已配置設定給我們的網格:

如何使用CSS 新文法grid-area來設定網格布局

使用網格區域 CSS 屬性将第二個網格項放入第二行和第三行以及第四列和第五列。

按行名定位元素

您可以使用網格模闆列和網格模闆行基于線條的放置網格屬性為網格線指定自定義名稱,以按其名稱引用該線。

讓我們回到我們的示例,并像這樣命名列和行軌道行:

.grid {
  display: grid;
  grid-template-rows: 100px [row2] 100px 100px [row4] 100px;
  grid-template-columns: 1fr 1fr 1fr [fourth] 1fr 1fr [second-to-last] 1fr;
}           

我們可以通過自定義名稱(row2、row4、第四和倒數第二)來引用第三行和第五行,而不是它們的索引值(分别為 2、4、4 和 6):

.grid-item:nth-child(2) {
  grid-area: row2 / fourth / row4 / second-to-last; /* same as index numbers 2 / 4 / 4 / 6 */
}           

<custom-ident> 請注意,不能采用 span 值。 span 是網格放置屬性的保留關鍵字(例如 grid-column: 1 / span 2)。

通過grid areas來定位元素

使用 grid-template-areas 屬性定義網格區域時,将根據區域的名稱免費獲得隐式行名稱。例如,名稱為 content 的網格區域在其前面生成一個名為 content-start 的行,在其之後生成一個名為 content-end 的行。您可以參考這些行來設定網格項的位置。

.grid-item:nth-child(2) {
  grid-area: content-start / content-start / content-end / content-end;
}           

或者,您可以引用區域的名稱,将項目定位在名為 area 的内容的開始行和結束行:

.grid-item:nth-child(2) {
  grid-area: content;
}           

如下是完整例子

<body>
  <header></header>
  <main></main>
  <aside></aside>
  <footer></footer>
</body>           
body {
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: min-content 1fr min-content;
  grid-template-areas:
    "header header header"
    "content content sidebar"
    "footer footer footer";
}

header {
  grid-area: header;
}

main {
  grid-area: content;
}

aside {
  grid-area: sidebar;
}

footer {
  grid-area: footer;
}           

這将設定網格元素在網格中的位置,我們希望它們在網格中的位置.

如何使用CSS 新文法grid-area來設定網格布局

使用網格區域 CSS 屬性按名稱将網格項放入網格區域中。

<integer> && <custom-ident>?

這種文法風格允許您在存在重複名稱時按網格線定位網格項。如果存在同名的網格線,則此文法有助于指定要引用的網格線。

.grid {
  display: grid;
  grid-template-columns: [a] 1fr [b] 1fr [b] 1fr [b] 1fr [b];
  grid-template-rows: [x] 1fr [y] 1fr [y] 1fr [y] 1fr [y];

  /*
    Using repeat() function also gives you repeated named grid line, for example:
    grid-template-columns: repeat(3, [b] 1fr);
  */
}           

假設您想在行軌道中選擇第三行,但該行與第二、第四和最後一個網格線同名 — 它們都稱為 y。由于名為 y 的第二行是第三條網格線,是以可以使用 2 選擇它作為起點。在以下示例中,相同的計數方式适用于網格面積的其他值:

.grid-item:nth-child(2) {
  grid-area: 2 y / 3 b / 4 y / 4 b;

  /* This is equivalent to: */
  grid-row-start: 2 y;
  grid-column-start: 3 b;
  grid-row-end: 4 y;
  grid-column-end: 4 b;
} 
           
如何使用CSS 新文法grid-area來設定網格布局

請注意,值的順序無關緊要。我們也可以像這樣編寫前面的代碼:

.grid-item:nth-child(2) {
  grid-area: y 2 / b 3 / y 4 / b 4;
}           

與前面的文法一樣,您也可以使用負整數來計算從網格結束邊緣開始的網格線。在我們的示例中,如果我們想引用相同的行,我們可以從網格的結束邊緣開始計數并像這樣寫:

.grid-item:nth-child(2) {
  grid-area: -3 y / -2 b / -1 y / -1 b;
}           

請注意,整數值不能為零。

span && [ <integer> || <custom-ident> ]

此文法允許網格項跨越網格軌道。可以通過三種不同的方式指定它。

請注意,如果未在此文法中的任何位置指定整數,則預設值為 1。

span <integer>

使用 span 關鍵字後跟整數表示網格項從特定網格線跨越的軌道數。例如,如果我們希望網格項跨越三個行軌道和兩個列軌道朝向其起始邊緣,我們可以應用以下值:

.grid-item:nth-child(2) {
  grid-area: span 3 / span 2;

  /* This is equivalent to */
  grid-row-start: span 3;
  grid-column-start: span 2;
  grid-row-end: auto;
  grid-column-end: auto;
} 
           
如何使用CSS 新文法grid-area來設定網格布局

網格項使用網格區域 CSS 屬性跨越兩列和三行。

span <custom-ident>

還可以将 span 關鍵字與網格線的名稱組合在一起,以使網格項擴充,直到到達指定的網格線。

.grid-item:nth-child(3) {
  grid-area: auto / 3 / auto / span lastline;
}           

由于網格項的起始線是已知的 (3),我們可以跨越該項,直到它到達名為 lastline 的列網格線。

如何使用CSS 新文法grid-area來設定網格布局

網格項跨越網格,直到它使用網格區域 CSS 屬性到達名為 lastline 的指定網格線。

span <custom-ident> <integer>

如果指定的網格線名稱配置設定給多個網格線 - 換句話說,如果我們重複命名的網格線 - 我們需要說出我們想要定位的網格線。為此,我們可以在值中添加一個整數,指定我們引用的網格線。

以以下網格為例:

.grid-container {
  display: grid;
  grid-template-columns: [y] 1fr [x] 1fr [x] 1fr [y] 1fr [x] 1fr [x];
}

.grid-item:nth-child(3) {
  grid-area: 2 / 2 / 4 / span x 2;
}           

我們将網格項的起始行設定為第二列行。然後我們希望它向前跨度,直到它到達名為 x 的網格線。由于我們希望它是第二條x網格線,是以我們最終得到span x 2。

是以,我們的網格項從第二行開始,如下圖所示。它命中的第一行是第一行 x,後跟 y,最後,它命中所需的第二行,名為 x。

如何使用CSS 新文法grid-area來設定網格布局

S使用 grid-area 屬性将網格項的位置從第二列行調整到第二個 x 命名行。

當您希望使用網格項的名稱将網格項跨越到網格線時,此文法非常有用。但請注意,使用此方法有多個同名的網格線,是以我們添加一個整數來表示我們想要該網格線的 N。

請參閱網格行開始、網格行結束、網格列開始和網格列結束,以擷取每個構成屬性的詳細資訊和文法示例。

例子

讓我們通過幾個例子來示範如何使用網格區域在網格上放置項目。

建立多層橫幅

假設此圖形是由您的設計團隊交給您的:

如何使用CSS 新文法grid-area來設定網格布局

他們還提供了另一個版本來向您展示它是在網格上設計的:

如何使用CSS 新文法grid-area來設定網格布局

讓我們首先設定我們的 HTML:

<figure>
  <img class="back" src="back.jpg" alt="Please">
  <img class="middle" src="middle.jpg" alt="fill your alt">
  <img class="front" src="front.jpg" alt="properly">
  <figcaption>Freedom is the oxygen of the soul...</figcaption>
</figure>           

設計中有十四列九行。我們可以這樣寫出來:

figure {
  display: grid;
  grid-template-columns: repeat(14, 50px);
  grid-template-rows: repeat(9, 50px);
}           

我們需要将所有這些子<img>元素放入其右側網格區域中。為此,我們使用網格區域屬性:

.back {
  grid-area: 1 / 3 / -2 / -1;
}

.middle {
  grid-area: 2 / 1 / 7 / 9;
}

.front {
  grid-area: 4 / 4 / -1 / -3;
}

figcaption {
  grid-area: -3 / -4 / -1 / -1;
}           

您可以在下圖中看到結果:

如何使用CSS 新文法grid-area來設定網格布局

檢視示範以了解有關此示例的更多詳細資訊:

堆疊網格項

在網格上定位項目時,我們可以将它們堆疊或重疊在一起。這使我們能夠有時使用 CSS 網格作為絕對定位的替代方案。例如,我們可以在不使用位置屬性的情況下将标題層放在圖像頂部,如下所示:

<figure>
  <img src="image.png" alt="how dare you leave alt empty?">
  <figcaption>The caption of our image</figcaption>
</figure>           
figure {
  display: grid;
}

img,
figcaption {
  grid-area: 1 / 1 / -1 / -1;
}           

預設情況下,網格項按源順序堆疊,但您可以使用 z-index 屬性控制其級别。在下面的示例中,我們重疊了一些項目,我們使用 z-index 屬性将第二個項目帶到堆棧上下文中的最進階别:

.item:nth-child(2) {
  grid-area: 2 / 2 / 4 / 4;
  z-index: 1;
}           
如何使用CSS 新文法grid-area來設定網格布局

使用 z-index 屬性将第二個網格項置于堆棧頂部。

可通路性

使用網格放置屬性時需要注意的一點是重新排列項目引起的問題。更改項目的位置時,隻有網格項目的可視順序會更改,并且該順序可能與原始文檔順序不同。對于在鍵盤上按 Tab 鍵浏覽文檔或收聽按與 HTML 相同的順序讀取内容的螢幕閱讀器的人來說,這可能會導緻非常糟糕的體驗。

是以,當元素的 HTML 順序很重要時,請避免更改網格項的順序。例如,它可能适用于随機圖像庫,但可能不适用于表單輸入。

但是,在撰寫本文時,有一項解決此問題的建議,有望在未來解決這一問題。

.grid {
  grid-template-columns: 
  grid-template-rows: 
}
.item:nth-child(3) {
  grid-area: 
}           
如何使用CSS 新文法grid-area來設定網格布局

繼續閱讀