CSS Grid: Container

css grid container

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:

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

dddgrid-template-areas

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 cho grid-template-rowsgrid-template-columns, giá trị của grid-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;
}
dddgrid-gap

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-gaprow-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 | end | center | stretch;
}}

Ví dụ:

.container {
  justify-items: start;
}
Justify-items: start

Tương ứng, khi áp dụng justify-items: end | center | stretch. Sẽ được kết quả như sau:

Justify-items: end
Justify-items: center
Justify-items: stretch

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:

Align-items: start
Align-items: end
Align-items: center
Align-items: stretch

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

justify-content: start
justify-content: end
justify-content: center
justify-content: stretch
justify-content: space-around
justify-content: space-between
justify-content: space-evenly

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-contentalign-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;
}
Grid template gồm 2 column x 2 row

Tiếp đến, giả sử bạn sử dụng thuộc tính grid-columgrid-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;
}
Vị trí của item-b khi không khai báo grid-auto-cloumns/auto-rows

Ở đ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-columnsgrid-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;
}
Vị trí của item-b sau khai báo grid-auto-cloumns/auto-rows

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ếu auto-flow đứng sau /, thuộc tính grid-auto-flow có giá trị column. Nếu có thêm dense theo sau, thì áp dụng dense column . Nếu thiếu grid-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ếu auto-flowđứng trước /, thuộc tính grid-auto-flow có giá trị row. Nếu có thêm dense theo sau, thì áp dụng dense row. Nếu thiếu grid-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-rowsgrid-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.

Bài cùng series:<< Tổng quan về CSS GridCSS Grid: Items >>