學懂grid布局:這篇就夠了(譯)

----前言

上周發過一篇關於flex布局的文章,但發完之後我感覺我並沒有寫很多自己對flex布局的理解,因為原鏈接的作者的輪子實在是太強了,這裡借用知乎大佬牛岱的話來說,當人家已經有足夠好的輪子,你就不要試圖,甚至是通過各種手段,試圖去取代這個輪子的地位。我覺的很正確(偷偷diss某些學校的計算機專業仍然用某本書當做C語言入門,真的是從入門到放棄),所以說花生直接按照原文來翻譯了(真的很棒),若有翻譯錯誤,歡迎指出!!!

grid布局是CSS最強的布局方式,它是一種二維布局,它可以處理,它不同於之前一維的flex布局。在grid布局中,父容器充當一個(Grid Container),子元素充當(Grid Item)。

注意!!長篇警告,但是很賺

1.基本瀏覽器的支持

1-瀏覽器支持

2.grid布局的屬性與屬性值

2.1父容器的屬性與屬性值

2-1-1 display

.container {
display: grid | inline-grid;
}

將元素定義為網格容器,並為其內容建立新的網格格式上下文,對於grid來說,是產生一個塊級的grid容器,而inline-grid就不用我說了吧

2-1-2 grid-template-columns grid-template-rows

.container {
grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
}

這裡track-size(軌道尺寸)的意思我覺的是一條線段的長度吧(就如圖2-1的40px和50px),line-name的意思是你可以給這條線段取個名字,track-size可以用px,%,fr(fraction)也就是分數的意思或者說fr為單位的軌道中占的比例

舉個栗子

.container {
grid-template-columns: 40px 50px auto 50px 40px;
grid-template-rows: 25% 100px auto;
}

2-1

裡面的[1],[2]...是track的名字(line-name) ,你也可以自己命名,如圖2-2

.container {
grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
}

2-2

注意:一條線也可以有多個名字,就比如說下面的例子

.container {
grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];
}

對於Grid布局來說你還可以用計算的方法來布局,你可以用repeat(),讓我們看看下面代碼

.container {
grid-template-columns: repeat(3, 20px [col-start]);
/*上面等同於下面*/
grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start];
}

下面我就說說關於fr的計算

.container {
grid-template-columns: 1fr 1fr 1fr;
/*舉例兩種例子*/
grid-template-columns: 1fr 50px 1fr 1fr;
}

上面那行的代碼表示:每一個軌道占父容器的1/3,假如父容器是900px,就分成了(300px 300px 300px),而下面的就會這樣計算(900-50)/3,然後平均分給每一個軌道,(283.3px 50px 283.3px 283.3px)

2-1-3 grid-template-areas

通過使用grid-area屬性指定子元素具體在父容器的位置.(句號)表示空的單元格(grid-item:就像小學生的網格本裡面的一個個格子),我覺的這個屬性太強了

.container {
grid-template-areas:
"<grid-area-name> | . | none | ..." /*就是每一個子元素的名字*/
"...";
}

舉個栗子

.item-a {
grid-area: header;
}
.item-b {
grid-area: main;
}
.item-c {
grid-area: sidebar;
}
.item-d {
grid-area: footer;
}

.container {
display: grid;
grid-template-columns: 50px 50px 50px 50px;
grid-template-rows: auto;
grid-template-areas:
"header header header header"
"main main . sidebar"
"footer footer footer footer";
}

我覺的光是看上面父容器的grid-template-areas就知道具體的布局是怎樣的吧

2-3

聲明中的每一行都需要相同數量的單元格,而且你可以用任意數量的句號來代表一個空單元格,只要它們之間沒有空格,就代表一個單元格。注意,當使用area時瀏覽器會自動的為每一個區域兩端的線條命名,若網格區域的名稱為foo,則區域的起始行的名稱為foo-start,最後一行為foo-end。這意味著某些行可能有多個名稱。就像圖2-3中父容器的最左邊的那條線被三個子元素共享所以你懂得...

2-1-4 grid-template

這是grid-template-rows,grid-template-columns, 和grid-template-areas簡寫,

.container {
grid-template: none | <grid-template-rows> / <grid-template-columns>;
/*其中none設置後就是後面的兩個的初始值*/
}

舉個例子

.container {
grid-template:
[row1-start] "header header header" 25px [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}
/*等同與下面*/
.container {
grid-template-rows: [row1-start] 25px [row1-end row2-start] 25px [row2-end];
grid-template-columns: auto 50px auto;
grid-template-areas:
"header header header"
"footer footer footer";
}

因為grid-template不會重置隱式網格屬性(grid-auto-columns, grid-auto-rows, and grid-auto-flow),這可能是你在大多數情況下要執行的操作,因此建議使用網格屬性而不是網格模板

2-1-5 grid-column-gap grid-row-gap grid-gap

gap在英文中有間隔、缺口的意思,因此就是每個子元素之間的間隔

.container {
grid-column-gap: <line-size>;
grid-row-gap: <line-size>;
}

舉個栗子

.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-column-gap: 10px;
grid-row-gap: 15px;
/*上面等同下面*/
grid-gap: <grid-row-gap> <grid-column-gap>;
grid-gap: 15px 10px; /*若沒有grid-row-gap,則設置同grid-column-gap相同的值*/
}

2-4

2-1-5 justify-items align-item place-items

這個屬性和flex布局中的align-items有點像,但是還是有點區別,因為是二維布局所以在Grid中多了一個justify-items, align-item的例子和justify-items很像,一個橫軸一個是縱軸

.container {
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
place-items: <align-items> / <justify-items>;/*如果第二個值沒有設置就等同於第一個值*/
}

栗子

.container {
justify-items: start;
}

2-5

end和center看過之前的flex布局講解想必大家都知道了吧

.container {
justify-items: stretch;
}

2-6

2-1-6 justify-content align-content place-content

是不是感覺很熟悉,沒錯就和flex中的布局方式相同的,給個圖片就知道了

.container {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
place-content: <align-content> / <justify-content>;/*如果第二個值沒有設置就等同於第一個值*/
}

就舉一個栗子哈~

.container {
justify-content: start;
}

2-7

align-content和justify-content同理,一個是橫軸一個是縱軸,這個屬性和flex的justify-content是相同道理的,如果不懂可以去看我之前的flex文章。

2-1-7 grid-auto-columns grid-auto-rows

當grid-item多餘網格中的單元格或grid-item放置在顯示網格之外,將創建隱式track

舉個栗子

.container {
grid-auto-columns: <track-size> ...;
grid-auto-rows: <track-size> ...;
}
/*--------------------------------*/
/*圖2-8是下面的栗子*/
.container {
grid-template-columns: 60px 60px;
grid-template-rows: 90px 90px
}

2-8

/*這兩個屬性會在子元素的屬性中介紹*/
.item-a {
grid-column: 1 / 2; /*在縱軸上,item-a處於第一條線和第二條線之間*/
grid-row: 2 / 3; /*在橫軸上,item-a處於第二條線和第三條線之間*/
}
.item-b {
grid-column: 5 / 6;/*如上同*/
grid-row: 2 / 3;
}

2-9

grid-column和grid-row還是很好理解的,就是子元素處在父元素上的位置,由上圖可知縱軸的第五條線和第六條線是不存在的,隱式track就會創建兩個0線來填充此間隔,我們用grid-template-columns和grid-template-rows就可以指定隱式軌道的寬度

.container {
grid-auto-columns: 60px;
}

2-10

2-1-7 grid-auto-flow

還記得我上篇文章提過的流布局嗎,假如你沒有明確子元素放置在網格上的網格項,則會根據自動放置演算法來放置,也就可以通過自動的流來布局

.container {
grid-auto-flow: row | column | row dense | column dense
}

  • row(默認):就是正常的流,從左到右的順序
  • column: 你們知道css還有writing-mode這個屬性嗎 設置為writing-mode: horizontal-tb;流向就為從上到下了,此處同理是如此
  • dense: 讓稍後出現較小的子元素嘗試填充網格中較早的洞,可能會導致子元素的可視順序錯亂,所以不仔細討論

舉個栗子

<section class="container">
<div class="item-a">item-a</div>
<div class="item-b">item-b</div>
<div class="item-c">item-c</div>
<div class="item-d">item-d</div>
<div class="item-e">item-e</div>
</section>

設置父容器

.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: row;
}

只指定兩個子元素的位置

.item-a {
grid-column: 1;
grid-row: 1 / 3;
}
.item-e {
grid-column: 5;
grid-row: 1 / 3;
}

2-11

當設置父容器中grid-auto-flow: column

2-12

2-1-7 grid

是grid-template-rows,grid-template-columns,grid-template-areas,grid-auto-flow的簡寫 詳細的可以看MDN官網

以上就是Grid中父容器的屬性與屬性值啦!!相信各位小夥伴們看的也很累,我敲的也累哇!

2.2子元素的屬性與屬性值

首先注意float,display: inline-block,display: table-cell,vertical-alignandcolumn-*對子元素沒有影響

2-2-1 grid-column-start grid-column-end grid-row-start grid-row-end

.item {
grid-column-start: <number> | <name> | span <number> | span <name> | auto
grid-column-end: <number> | <name> | span <number> | span <name> | auto
grid-row-start: <number> | <name> | span <number> | span <name> | auto
grid-row-end: <number> | <name> | span <number> | span <name> | auto
}

相信大家接觸過前面的grid-start和grid-end已經有了足夠多的了解了吧!!

.item-a {
grid-column-start: 2;
grid-column-end: five;
grid-row-start: row1-start
grid-row-end: 3;
}

2-13

2-2-2 grid-area

.item {
grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
}

為子元素指定名稱,以便可以使用grid-template-areas,或者可以作為grid-row-start + grid-column-start+grid-row-end+grid-column-end的簡寫

.item-d {
grid-area: header
}
/*或者*/

2-14

2-2-3 justify-self align-self place-self

.item {
/*stretch都是默認填充容器的*/
justify-self: start | end | center | stretch;
align-self: start | end | center | stretch;
place-self: <align-self> / <justify-self>;/*和前面一樣第二個沒有設置值同第一個,*/
}

這個就和flex布局中的align-self很像了,就如前面的justify-content一樣

.item-a {
justify-self: start;
align-self: start;
place-self: center;
place-self: center stretch;
}

2-15 justify-self: start;

2-16 align-self: stretch;

2-17 place-self: center;

2-18 place-self: center stretch;

以上就是本期的所有翻譯了,寫了一下午,相信大家看到這裡也很累,但是我相信你們肯定有所收穫,相信大家也對flex布局和grid布局有了一個清晰的認識了,是不是覺的很強大,如果對兼容性沒有要求的話,可以考慮用用喲~,真的能夠提高生產力,如果覺的不錯,請點個贊喲~~

參考鏈接

https://css-tricks.com/snippets/css/complete-guide-grid/?

css-tricks.com

chris.house?

chris.house圖標
推薦閱讀:

TAG:CSS | HTMLCSS | CSS布局 |