Chào các bạn, đây là bài thứ 2 trong series CSS Grid. Ở phần này, chúng ta cùng tìm hiểu chi tiết về phần tử grid container.
Nội dung series bài viết CSS Grid:
- Tổng quan về CSS Grid
- CSS Grid: Container
- CSS Grid: Items
Trước khi bắt đầu tìm hiểu, mình sẽ nhắc lại một chút về định nghĩa của grid container.
Grid Container là gì?
Đây là phần tử cha được áp dụng thuộc tính display: grid
hoặc display: inline-grid
. Phần tử container
chính là phần tử sẽ chứa các item sẽ được layout trong ví dụ bên dưới.
<div class="container">
<div class="item item-0"></div>
<div class="item item-1"></div>
<div class="item item-2"></div>
</div>
Thuộc tính của grid container
Phần này chúng ta sẽ tìm hiểu chi tiết về các thuộc tính của 1 grid container và cách dùng.
display
Thuộc tính quy định phần tử là grid container.
Giá trị hợp lệ:
- grid: tạo 1 block grid.
- inline-grid: tạo 1 block inline grid.
.container {
display: grid | inline-grid;
}
grid-template-columns / grid-template-rows
Thuộc tính này định nghĩa số cột và hàng trong lưới. Giá trị của thuộc tính sẽ quy định kích thước của grid track, khoảng cách giữa các track chính là grid line.
Giá trị hợp lệ:
- <track-size>: giá trị kích thước, phần trăm, bạn cũng có thể dùng fraction unit (fr).
- <line-name>: bạn có đặt tên tự chọn cho line.
.container {
grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
}
Ví dụ bên dưới mô tả rõ hơn về các giá trị dùng trong grid-template. Ở phần column sẽ chia làm 5 cột, với giá trị các cột từ trái sang phải là: 40px, 50px, auto, 50px, 40px. Giá trị auto
sẽ là giá trị width còn lại sau khi khai báo các giá trị các cột: tổng width - (40px + 50px + 50px + 40px)
.
.container {
grid-template-columns: 40px 50px auto 50px 40px;
grid-template-rows: 25% 100px auto;
}
Tương tự với template-row có 3 hàng, hàng đầu tiên sẽ có giá trị 25%
chiều cao của container
, tiếp theo 100px và phần còn lại. Các item khi khai báo sẽ theo thứ tự từ trái sang phải, từ trên xuống dưới nhé mọi người.
Ngoài ra, các bạn cũng có thể đặt tên cho grid line theo cú pháp bên dưới. Tên của grid line sẽ được đặt trong dấu ngoặc vuông []
.
.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];
}
Ở trong ví dụ sau, cột grid line thứ 2 có 2 tên là row1-end
và row2-start
:
.container {
grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];
}
Nếu template của bạn có nhiều cột/hàng liên tiếp có giá trị giống nhau thì bạn có thể dùng hàm repeat()
để khai báo.
.container {
grid-template-columns: repeat(3, 20px [col-start]);
}
Giá trị template ở ví dụ trên sẽ tương ứng với:
.container {
grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start];
}
Các bạn cũng có thể dùng đơn vị fr
để tùy biến trong thiết kế responsive. Ví dụ nếu chúng ta cần chia làm 3 cột với kích thước bằng nhau, và bằng 1/3 kích thước width của grid container.
.container {
grid-template-columns: 1fr 1fr 1fr;
}
Giá trị của đơn vị fr
sẽ được tính toán sau khi loại trừ đi các giá trị tuyệt đối được khai báo. Trong ví dụ bên dưới, giá trị của cột thứ 2 là 150px, các cột còn lại sẽ có giá trị tính bằng (tổng width - 150px) / 3
.
.container {
grid-template-columns: 1fr 150px 1fr 1fr;
}
grid-template-areas
Thuộc tính này dùng để định nghĩa một mẫu, bằng các sử dụng các tên được khai báo (mang tính gợi nhớ).
Giá trị hợp lệ:
- <grid-area-name>: tên tự đặt của grid-area.
- . : đánh dấu một grid cell rỗng
- none: không đặt tên cho grid area.
.container {
grid-template-areas:
"<grid-area-name> | . | none | ..."
"...";
}
Ví dụ:
.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";
}
Trong đoạn code trên sẽ tạo 1 grid với 4 cột và 3 hàng. Hàng đầu tiên tên là header
chiếm 4 cell. Hàng thứ 2 main
sẽ chiếm 2 cell, 1 cell rỗng và 1 cell sidebar
. Hàng cuối cùng footer
có 4 cell. Các bạn xem hình mô tả ở dưới.
Mỗi một hàng khi khai báo sẽ phải có số cột bằng nhau. Bạn có thể dùng nhiều dấu chấm để định nghĩa 1 cell rỗng, miễn là không có khoảng trắng giữa những dấu .
.
grid-template
Đây là thuộc tính kết hợp grid-template-rows
, grid-template-columns
, và grid-template-areas
vào lần khai báo duy nhất.
Giá trị hợp lệ:
none
: reset tất cả giá trị của 3 thuộc tính về giá trị khởi tạo.<grid-template-rows> / <grid-template-columns>
: Khai báo giá trị tương ứng chogrid-template-rows
vàgrid-template-columns
, giá trị củagrid-template-areas
sẽ được set vềnone
.
.container {
grid-template: none | <grid-template-rows> / <grid-template-columns>;
}
Ngoài ra, bạn cũng có thể khai báo phức tạp hơn một chút với đoạn code sau:
.container {
grid-template:
[row1-start] "header header header" 25px [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}
Đoạn ví dụ trên sẽ tương ứng với:
.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-column-gap / grid-row-gap
2 thuộc tính này sẽ định nghĩa giá trị grid line của hàng và cột.
Giá trị hợp lệ:
- <line-size>: giá trị kích thước của grid line.
.container {
grid-column-gap: <line-size>;
grid-row-gap: <line-size>;
}
Trong ví dụ mẫu bên dưới, chúng ta sẽ có 3 cột: 100px
, 50px
, và 100px
với khoảng cách mỗi cột là 10px
; 3 hàng: 80px
, auto
, và 80px
với khoảng cách mỗi hàng là 15px
.
.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-column-gap: 10px;
grid-row-gap: 15px;
}
grid-gap
Thuộc tính này kết hợp column-gap và row-gap vào 1 dòng khai báo.
Giá trị hợp lệ:
- <grid-column-gap> <grid-column-gap>: giá trị khoảng cách.
.container {
grid-gap: <grid-row-gap> <grid-column-gap>;
}
Ví dụ:
.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-gap: 15px 10px;
}
Lưu ý: nếu bạn chỉ khai báo 1 giá trị, thì column-gap
và row-gap
sẽ dùng chung giá trị này.
grid-gap: 15px
sẽ tương ứng với grid-gap: 15px 15px
justify-items
Căn chỉnh nội dung grid cell theo chiều ngang.
Giá trị hợp lệ:
- start: căn chỉnh item vào lề trái
- center: căn chỉnh item vào giữa
- end: căn chỉnh item vào lề phải
- stretch: Kéo nội dung vừa toàn bộ width của grid cell.
.container {
justify-items: start | end | center | stretch;
}
Một số ví dụ minh họa bên dưới:
.container {
justify-items: start;
}
Tương ứng, khi áp dụng justify-items: end | center | stretch
. Sẽ được kết quả như sau:
Nếu các bạn muốn dùng mỗi cell có justify một kiểu khác nhau, ở grid item sẽ sử dụng thuộc tính justify-self
. Phần này mình sẽ đề cập chi tiết trong bài tiếp theo.
align-items
Thuộc tính này tương tự với justify-items
, nhưng áp dụng theo chiều dọc.
Giá trị hợp lệ:
- start: căn chỉnh item theo cạnh trên.
- end: căn chỉnh item theo cạnh dưới.
- center: căn chỉnh item vào giữa theo chiều dọc
- stretch: Kéo nội dung vừa chiều cao của item.
.container {
align-items: start | end | center | stretch;
}
Hình minh họa bên dưới:
place-items
Thuộc tính này là sự kết hợp của justify-items và align-items vào 1 thuộc tính.
Giá trị hợp lệ:
- <align-items> – <justify-items>: Giá trị tương ứng cho
align-items
vàjustify-items
, nếu bạn chỉ input 1 giá trị thì 2 thuộc tính này sẽ có giá trị giống nhau.
justify-content
Đôi khi tổng giá trị width nội dung của cell sẽ không bằng giá trị width của container. Đặc biệt là khi bạn sử dụng giá trị tuyệt đối như px
. Trong những trường hợp như vậy, chúng ta sử dụng thuộc tính justify-content để căn chỉnh các grid cell trong container theo hàng ngang.
Giá trị hợp lệ:
- start: căn chỉnh theo cạnh trái container.
- end: căn chỉnh theo cạnh phải container.
- center: căn chỉnh vào giữa container.
- stretch: Kéo nội dung đầy hàng ngang container.
- space-around: thêm khoảng cách giữa mỗi column, bao gồm cả 2 rìa trái và phải container với giá trị 1/2 khoảng cách giữa 2 column.
- space-between: thêm khoảng cách giữa mỗi column, không bao gồm cả 2 rìa trái và phải container.
- space-evenly: thêm khoảng cách giữa mỗi column, bao gồm 2 rìa trái và phải container với giá trị bằng khoảng giữa 2 column.
.container {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
Các bạn xem hình minh họa bên dưới để hiểu rõ về chức năng của thuộc tính này:
Các bạn chú ý không nhầm lẫn giữa space-around
với space-evenly
nhé.
align-content
Thuộc tính này tương tự justify-content
, nhưng áp dụng về chiều dọc.
place-content
Thuộc tính place-content
là sự kết hợp giữa justify-content
và align-content
vào một dòng khai báo chung.
Giá trị hợp lệ:
- <align-content> / <justify-content>: giá trị tương ứng cho align-content và justify-content. Hai thuộc tính sẽ dùng chung nếu chỉ có 1 giá trị input.
grid-auto-columns / grid-auto-rows
Thuộc tính này quy định giá trị của các grid track được tự động tạo ra (khi item nằm ngoài template) theo chiều ngang với grid-auto-columns
và chiều dọc với grid-auto-rows
.
Giá trị hợp lệ:
- <track-size>: giá trị độ dài, bạn có thể dùng giá trị tuyệt đối hoặc tương đối như
fr
.
.container {
grid-auto-columns: <track-size> ...;
grid-auto-rows: <track-size> ...;
}
Ví dụ minh họa sau đây sẽ làm rõ hơn về thuộc tính này.
.container {
grid-template-columns: 60px 60px;
grid-template-rows: 90px 90px;
}
Tiếp đến, giả sử bạn sử dụng thuộc tính grid-colum
và grid-row
(chi tiết ở bài tiếp theo) để đặt vị trí cho một grid item
.item-a {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.item-b {
grid-column: 5 / 6;
grid-row: 2 / 3;
}
Ở đoạn code ví dụ trên, chúng ta quy định vị trí của item-b bắt đầu từ cột grid line thứ 5 đến cột thứ 6; từ hàng grid line thứ 2 đến hàng thứ 3. Nhưng trong grid template chúng ta không định nghĩa column thứ 5, lúc này item-b sẽ nằm ngoài template và có giá trị column = auto. Do nằm ngoài template nên giá trị column ở giữa (column 3 và 4) sẽ được tính bằng 0
kèm với giá trị grid gap mặc định. Trong trường hợp này, chúng ta sử dụng đến grid-auto-columns
và grid-auto-rows
để quy định kích thước cho cột và hàng được tự động tạo ra ngoài template. Ở đây là column 3 và 4.
.container {
grid-auto-columns: 60px;
}
grid-auto-flow
Đôi khi bạn không khai báo hoặc khai báo thiếu vị trí cho các phần tử grid item, thuộc tính grid-auto-flow sẽ quy định cách trình duyệt sắp xếp các item này trong grid.
Giá trị hợp lệ:
- row: Tự động sắp xếp các item còn lại theo hàng ngang trước.
- column: Tự động sắp xếp các item còn lại theo hàng dọc trước.
- dense: tự động lấp đầy các vị trí theo chiều ngang (row dense) hoặc dọc (column dense).
.container {
grid-auto-flow: row | column | row dense | column dense;
}
Các bạn xem các ví dụ bên dưới để dễ hình dung.
grid
Đây là thuộc tính tổng hợp của các thuộc tính ở trên: grid-template-rows
, grid-template-columns
, grid-template-areas
, grid-auto-rows
, grid-auto-columns
, và grid-auto-flow
.
Giá trị hợp lệ:
- none: đặt tất cả thuộc tính phụ về giá trị khởi tạo.
- <grid-template>: Tương tự thuộc tính grid-template.
- <grid-template-rows> / [ auto-flow && dense? ] <grid-auto-columns>? thiết lập giá trị thuộc tính
grid-template-rows
. Nếuauto-flow
đứng sau/
, thuộc tínhgrid-auto-flow
có giá trịcolumn
. Nếu có thêmdense
theo sau, thì áp dụngdense column
. Nếu thiếugrid-auto-columns
, thì giá trị của nó được set vềauto
. - [ auto-flow && dense? ] <grid-auto-rows>? / <grid-template-columns> – thiết lập giá trị
grid-template-columns
. Nếuauto-flow
đứng trước/
, thuộc tínhgrid-auto-flow
có giá trịrow
. Nếu có thêmdense
theo sau, thì áp dụngdense row
. Nếu thiếugrid-auto-rows
, thì giá trị của nó được set vềauto
.
Ví dụ minh họa:
.container {
grid: 100px 300px / 3fr 1fr;
}
Tương đương với đoạn mã bên dưới. Giá trị hai bên dấu /
là giá trị tương ứng của grid-template-rows
và grid-template-columns
.
.container {
grid-template-rows: 100px 300px;
grid-template-columns: 3fr 1fr;
}
Tương tự, 2 đoạn mã sau là tương đương:
.container {
grid: auto-flow dense 100px / 1fr 2fr;
}
.container {
grid-auto-flow: row dense;
grid-auto-rows: 100px;
grid-template-columns: 1fr 2fr;
}
Chúng ta tiếp tục đến với ví dụ phức tạp hơn một chút khi áp dụng thêm thuộc tính grid-template-areas
, grid-template-rows
, và grid-template-columns
.
.container {
grid: [row1-start] "header header header" 1fr [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}
Đoạn trên sẽ tương đương với:
.container {
grid-template-areas:
"header header header"
"footer footer footer";
grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end];
grid-template-columns: auto 50px auto;
}
Còn nhiều ví dụ phức tạp hơn nữa sẽ được trình bày ở các bài sau nhé. Tuy nhiên, nếu bạn chưa rành về cú pháp của grid
, thì hãy áp dụng từng thuộc tính riêng biệt.