+6

CSS - Grid Layout

Ở bài viết trước ta đã tìm hiểu về Flexbox. Trong bài viết tiếp theo trong series CSS này chúng ta sẽ tìm hiểu về Grid, các thuộc tính của nó cũng như cách sử dụng Grid trong thực tế.

Grid là gì?

CSS Grid Layout là một hệ thống bố cục lưới hai chiều, nhờ sự ra đời của Grid đã thay đổi hoàn toàn cách thiết kế bố cục củawebsite. Trước kia khi thiết kế website, ta thường sử dụng table, float, position nhưng các cách trên sẽ bị bỏ qua mốt số chức năng quan trọng(căn giữa phần tử theo chiều dọc, ...). Flexbox cũng có thể dùng để thiết kế bố cục rất tố nhưng trong một số trường hợp ta sử dụng Grid sẽ nhanh và tiện lợi hơn rất nhiều.

Một số khái niệm quan trọng

Grid Container

<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>

Screenshot from 2021-07-30 16-29-23.png

Như trong hình và code bạn có thể thấy container là toàn bộ phần có viền màu cam và nền màu xám chứa toàn bộ các grid-item hay container là element được gán thuộc tính CSS display: grid.

Grid Item

Grid item là các element con cấp đầu tiên của container của contaier.

<div class="grid-container">
    <div class="grid-item">
        <div class="not-child">1</div>
    </div>
    <div class="grid-item">2</div>
    <div class="grid-item">3</div>
</div>

Như trong code thì div với class not-child không phải là grid item.

Grid Line

Đường kẻ ngang hoặc dọc tạo nên cấu trúc và chia các grid-item được gọi là grid line. Như bạn có thể thấy đường kẻ màu xanh có các số bên dưới chính là là grid line.

Screenshot from 2021-07-30 16-54-58.png

Grid Cell

Grid cell là khoảng cách giữa hàng và cột của grid line. Nhưng ô 1 đến 9 hình bên dưới chính là grid-cell.

Screenshot from 2021-07-30 16-58-35.png

Grid Area

Grid area là một vùng bao gồm các grid-cell. Ví dụ như vùng bao gồm các cell 4, 5, 7, 8 bên trên là một grid area.

Một số thuộc tính của Grid

Container

grid-template-columns

grid-template-columns dùng đẻ xác định các cột trong grid layout. Các giá trị là kích thước của cột và được cách nhau bởi dấu cách.

grid-template-columns: value value ...

.grid-container {
   // Container sẽ được chia đều ra làm 3 phần mỗi cột một phần
   grid-template-columns: 1fr 1fr 1fr;
   
   // Container sẽ có 3 cột với độ rộng tương ứng
   grid-template-columns: 20% 50% 30%;
   
   // Các cột có độ rộng lần lượt là 200px, 150px, 400px
   grid-template-columns: 200px 150px 400px;
}

grid-template-rows

grid-template-rows dùng đẻ xác định các hàng trong grid layout. Các giá trị là kích thước của hàng và được cách nhau bởi dấu cách.

grid-template-rows: value value ...

.grid-container {
   // Container sẽ được chia đều ra làm 3 phần (chiều dọc) mỗi hàng một phần
   grid-template-rows: 1fr 1fr 1fr;
   
   // Container sẽ có 3 hàng với độ cao tương ứng
   grid-template-rows: 20% 50% 30%;
   
   // Các hàng có độ cao lần lượt là 200px, 150px, 400px
   grid-template-rows: 200px 150px 400px;
}

grid-template-areas

grid-template-areas dùng để xác định một template grid giúp căn chỉnh layout một cách trực quan hơn và thường đi kèm với thuộc tính grid-areagrid-item.

grid-template-areas:
    "col1 col2 col3"
    "col4 col5 col6"
    ...

Giả sử ta muốn tạo một layout có 2 hàng và 3 cột với ô đầu tiên có chiều rộng là 2 cell ta sẽ có template như sau.

grid-template-areas:
    "col1 col1 col2"
    "col3 col4 col5"

grid-column-gap

grid-column-gap là khoảng trống giữa các cột trong grid layout.

grid-column-gap: <value>

.grid-container {
    grid-column-gap: 1rem;
}

Screenshot from 2021-07-30 18-00-44.png

Ta có thể thấy khoảng cách giữa các cột đã được set là 1 rem.

grid-row-gap

Tương tự như grid-cloumn-gap thì grid-row-gap là đối với các hàng.

grid-row-gap: <value>

gap

Ta có thể sử dụng gap để viết tắt cho 2 thuộc tính là grid-column-gapgrid-row-gap.

gap: <grid-row-gap> <grid-column-gap> / <value> (cho cả 2 row và column)

.grid-container {
   gap: 1rem;
}

Screenshot from 2021-07-30 18-06-52.png

grid-auto-columns và grid-auto-rows

Hai thuộc tính này dùng để chỉ định kích thước của cột hoặc hàng.

grid-auto-columns/rows: min-content | max-content | auto | <value>

place-items

place-items là shorthand của align-items: start | end | center | stretch (căn theo chiều dọc(column)) và justify-items: start | end | center | stretch (căn theo chiều ngang (row)).

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

.grid-container {
    place-items: center;
}

Screenshot from 2021-07-30 18-11-19.png

Item

grid-column

Ta sử dụng grid-column để xác định xem cell được CSS có độ dài như thế nào bằng grid-line(line theo chiều dọc).

grid-column: grid-line-start(số bắt đầu)/grid-line-end(số kết thúc)

.grid-item:first-child {
    grid-column: 1/3;
}

.grid-item:last-child {
    grid-column: 2/4;
}

Screenshot from 2021-07-30 18-26-01.png Ta có thể thấy cell đầu tiên có độ rộng kéo dài từ line 1 đến 3 còn cell cuối cùng có độ rộng kéo dài từ line 2 đến line 4.

grid-row

Ta sử dụng grid-row để xác định xem cell được CSS có độ cao như thế nào bằng grid-line(line theo chiều dọc).

grid-row: grid-line-start(số bắt đầu)/grid-line-end(số kết thúc)

.grid-item:first-child {
    grid-column: 1/3;
    grid-row: 1/4;
}

Screenshot from 2021-07-30 18-30-58.png

Tương tự như trên ta thấy cell đầu tiên có độ dài từ line 1 đến line 3 và chiều cao từ line 1 đến line 4.

grid-area

Đưa ra tên được định nghĩa trong template grid-template-areas, grid-item đó sẽ có bố cục giống như trong template.

grid-area: <name-in-template>.

.grid-container {
    width: 500px;
    height: 500px;
    display: grid;
    gap: 1rem;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 2fr 1fr 2fr;
    grid-template-areas:
        "img1 img2 img3"
        "img1 img5 img5"
        "img4 img5 img5"
    ;
}

.grid-item:first-child {
    grid-area: img1;
}

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

.grid-item:nth-child(3) {
    grid-area: img3;
}

.grid-item:nth-child(4) {
    grid-area: img4;
}

.grid-item:last-child {
    grid-area: img5;
}

Screenshot from 2021-07-30 18-45-05.png

Như hình ta có thể thấy dễ dàng tạo layout bằng cách lấy tên được định nhĩa trong grid-template-areas để gán giá trị cho grid-area của grid-item.

Thực hành

Mình sẽ tạo một ví dụ đơn giản về việc sử dụng grid để responsive.

<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 class="grid-item">10</div>
    <div class="grid-item">11</div>
    <div class="grid-item">12</div>
    <div class="grid-item">13</div>
    <div class="grid-item">14</div>
    <div class="grid-item">15</div>
    <div class="grid-item">16</div>
    <div class="grid-item">17</div>
</div>
.grid-container {
    display: grid;
    gap: 1rem;

    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    grid-auto-rows: 150px;
}

.grid-item {
    width: 100%;
    height: 100%;
    background-color: #FFAA4C;
    border: 1px solid #5089C6;
    display: flex;
    justify-content: center;
    align-items: center;
}

Ở đây mình có dùng repeat(), minmax()auto-fit để responsive. Các cột của grid sẽ có chiều rộng giao động từ 250px đến 1fr và auto=fit ở đây dùng để khi chiều dài của block lớn hơn container các block sẽ tự động xuống dòng và giãn ra. Kết quả các bạn có thể xem ở đây.

Tổng kết

Như vậy qua bài viết này mình đã giúp các bạn tìm hiểu về Grid. Nó giúp ta có thể layout một cách dễ dàng. Ngoài ra còn một số thuộc tính hữu dụng khác của Grid mà mình chưa đề cập đến các bạn có thể tham khảo ở đây. Mình hy vọng qua bài viết này các bạn có thể sử dụng được Grid cho những project của mình. Cảm ơn các bạn đã theo dõi đến hết bài viết ❤️.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí