openplanning

Hướng dẫn và ví dụ CSS Grid Layout

  1. CSS {display: grid | inline-grid}
  2. Một số khái niệm cơ bản
  3. Quy tắc đặt tên
  4. CSS grid-template-columns/-rows
  5. CSS grid-template-areas, grid-area
  6. CSS grid-template
  7. CSS grid-column-start, grid-row-start,..
  8. CSS grid-column, grid-row
  9. CSS grid-column-gap, grid-row-gap
  10. CSS justify-items
  11. CSS justify-self
  12. CSS align-items
  13. CSS align-self

1. CSS {display: grid | inline-grid}

CSS {display:grid | inline-grid} được áp dụng cho một phần tử để chia bề mặt của nó thành một lưới (grid), bao gồm các hàng (row) và các cột (column), các phần tử con của nó sẽ được bố trí trên các ô lưới. Nó giúp bạn dễ dàng hơn trong việc thiết kế các trang thay vì sử dụng CSS float hoặc các kỹ thuật định vị phần tử.
CSS {display:grid | inline-grid} được hỗ trợ bởi tất cả các trình duyệt hiện đại.
grid, inline-grid chỉ là hai trong các giá trị của CSS display, bạn có thể xem thêm các giá trị khác trong bài viết dưới đây:
Để tạo được một hệ thống lưới bạn cần kết hợp một vài thuộc tính (property) CSS dưới đây, bao gồm các thuộc tính dành cho phần tử cha, và các thuộc tính cho các phần tử con.
Parent
Children (Grid Items)
  • display: grid | inline-grid
  1. grid-template-columns
  2. grid-template-rows
  3. grid-template-areas
  4. grid-template
  5. grid-column-gap
  6. grid-row-gap
  7. grid-gap
  8. justify-items
  9. align-items
  10. place-items
  11. justify-content
  12. align-content
  13. place-content
  14. grid-auto-columns
  15. grid-auto-rows
  16. grid-auto-flow
  17. grid
  1. grid-column-start
  2. grid-column-end
  3. grid-row-start
  4. grid-row-end
  5. grid-column
  6. grid-row
  7. grid-area
  8. justify-self
  9. align-self
  10. place-self

2. Một số khái niệm cơ bản

Có một vài khái niệm trong hệ thống lưới CSS (CSS Grid System) mà bạn cần làm quen trước khi bắt đầu học về nó:
Grid Line
Grid Line: Là đường thẳng nằm ngang (hoặc thẳng đứng) tham gia vào việc chia bề mặt phần tử ra thành các ô lưới.
Grid Track
Grid Track: Là một hàng (row) hoặc một cột (column).
Track Size
Track Size: Chiều rộng của một cột, hay chiều cao của một hàng.
Grid Cell
Grid Cell: (Một ô lưới) Là một hình chữ nhật, giao điểm (intersection) của một hàng và một cột.
Grid Area
Grid Area: Là một hình chữ nhật được tạo ra bởi việc hợp nhất (merge) nhiều ô lưới gần nhau.

3. Quy tắc đặt tên

CSS Grid cho phép bạn đặt tên cho các Grid Line, và Grid Track một cách tùy ý. Việc đặt tên cho các Grid Line, Grid Track giúp cho mô tả các thông số cho 1 phần tử con nào đó dễ dàng hơn, chẳng hạn, vị trí, căn chỉnh (align),...
CSS Grid khuyến nghị bạn đặt tên theo quy tắc sau:
Các Grid Line (Hoặc Grid Track) có thể đặt tên là line1, line2, line3,.... Cách này phù hợp với lưới có nhiều cột, nhiều dòng.
Các Grid Line (Hoặc các Grid Track) có thể đặt tên là first, second, third,.. last. Cách này phù hợp với lưới có số lượng hàng và cột ít (Nhỏ hơn 5).
Các Grid Line thẳng đứng có thể đặt tên là col1-start, col1-end, col2-start, col2-end,....
Các Grid Line nằm ngang có thể đặt tên là row1-start, row1-end, row2-start, row2-end,...
Chú ý: Bạn sẽ hiểu thêm về cách đặt tên thông qua các ví dụng trong bài viết này.

4. CSS grid-template-columns/-rows

CSS grid-template-columns cho phép bạn khai báo chiều rộng các cột của Grid. Hoặc khai báo tên các cột và chiều rộng của chúng.
CSS grid-template-rows cho phép bạn khai báo chiều rộng các hàng của Grid. Hoặc khai báo tên các hàng và chiều cao của chúng.
grid-template-columns: <track-size> ... | [name] <track-size> ...;

grid-template-rows: <track-size> ... | [name] <track-size> ...;
Ví dụ, một Grid với 2 hàng, 3 cột:
.container {
    display: grid;
    grid-template-rows: 100px 50px;
    grid-template-columns: 250px 150px 120px;
    border:1px solid #ddd;
}
.container {
    display: grid;
    grid-template-rows:  [first] 100px [line2] 50px ;
    grid-template-columns: [first] 250px [line2] 150px 120px ;
    border:1px solid #ddd;
}
.
Xem ví dụ đầy đủ:
grid-template-example-1a.html
<!DOCTYPE html>
<html>
   <head>
      <title>CSS grid-template-rows, grid-template-columns</title>
      <meta charset="UTF-8"/>
      <style>
         .container {
            display: grid;
            grid-template-rows: 100px 50px;
            grid-template-columns: 250px 150px 120px;
            border:1px solid #ddd;
         }
         .child {
           padding: 5px;
           background: #d4e6f1;
           margin: 5px;
         }
      </style>
   </head>
   <body>
       <h3>CSS grid-template-rows, grid-template-columns</h3>
        <div class="container">
           <div class="child">
               Child 1
           </div>
           <div class="child">
               Child 2
           </div>
           <div class="child">
               Child 3
           </div>
           <div class="child">
               Child 4
           </div>
           <div class="child">
               Child 5
           </div>
        </div>
   </body>
</html>
Chiều rộng, hoặc chiều cao của một cột cũng chấp nhận giá trị phần trăm ( % ) hoặc giá trị auto.
grid-template-example-2a.html
<!DOCTYPE html>
<html>
   <head>
      <title>CSS grid-template-rows, grid-template-columns</title>
      <meta charset="UTF-8"/>
      <style>
         .container {
            display: grid;
            grid-template-rows: 100px 50px;
            grid-template-columns: 100px 25% auto;
            border:1px solid #ddd;
         }
         .child {
           padding: 5px;
           background: #d4e6f1;
           margin: 5px;
         }
      </style>
   </head>
   <body>
       <h3>CSS grid-template-rows, grid-template-columns</h3>
       <p style="color: red;font-style: italic;">
         grid-template-rows: 100px 50px; <br/>
         grid-template-columns: 100px 25% auto;
       </p>
        <div class="container">
           <div class="child">
               Child 1
           </div>
           <div class="child">
               Child 2
           </div>
           <div class="child">
               Child 3
           </div>
           <div class="child">
               Child 4
           </div>
           <div class="child">
               Child 5
           </div>
        </div>
   </body>
</html>
repeat()
Ký hiệu (notation) repeat() giúp bạn lặp lại nhiều lần một phần code.
.container {
    display: grid;
    grid-template-rows: 100px 50px;
    grid-template-columns: 100px repeat(2, [my-column] auto);
    border:1px solid #ddd;
}
Đoạn code ở trên tương đương với:
.container {
    display: grid;
    grid-template-rows: 100px 50px;
    grid-template-columns: 100px [my-column] auto [my-column] auto;
    border:1px solid #ddd;
}
Đôi khi các cột có tên giống nhau, để tham chiếu đến nó bạn phải sử dụng tên và số thứ tự của nó (Số thứ tự bắt đầu từ 1).
.child {
  grid-column-start: my-column 2;
}
FR (Fraction):
FR (Fraction) là một đơn vị tính trong hệ thống lưới CSS.
Ví dụ:
.container {
    display: grid;
    grid-template-rows: 100px 50px;
    grid-template-columns: 100px 2fr 1fr 2fr;
    border:1px solid #ddd;
}

5. CSS grid-template-areas, grid-area

CSS grid-template-areas giúp bạn định nghĩa một mẫu (template) cho các Grid Area. Định nghĩa của mỗi Grid Area được đặt trong cặp nháy kép (double quotation marks) ( " " ).
.container {
  grid-template-areas:
     "<grid-area-name> | . | none | ..."
     "<grid-area-name> | . | none | ..."
     "...";
}
<grid-area-name>
Tên của một Grid Area.
.
(Dấu chấm), Biểu thị mô ô lưới trống.
none
Không có một Grid Area nào được định nghĩa.
CSS grid-area
.child {
  grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
}
Ví dụ, định nghĩa 4 Grid Area: (header, main, sidebar, footer) như hình minh họa dưới đây:
template-areas-example1.css
.container {
   display: grid;
   grid-template-rows: 50px 100px 50px;
   grid-template-columns: 100px auto 100px 100px;
   grid-template-areas:
      "header header header header"
      "main main . sidebar"
      "footer footer footer footer";
   border:1px solid #ddd;
}
.child {
  padding: 5px;
  background: #d4e6f1;
  margin: 5px;
} 
.child-header {
   grid-area: header;
}
.child-main {
   grid-area: main;
}
.child-sidebar {
   grid-area: sidebar;
}
.child-footer {
   grid-area: footer;
}
template-areas-example1.html
<!DOCTYPE html>
<html>
   <head>
      <title>CSS grid-template-areas</title>
      <meta charset="UTF-8"/>
      <link rel="stylesheet" href="template-areas-example1.css" />
   </head>
   <body>
       <h2>CSS grid-template-areas</h2>
       <p style="color: red;font-style: italic;">
          <b>grid-template-areas:</b> <br/>
             "header header header header" <br/>
             "main main . sidebar" <br/>
             "footer footer footer footer";
       </p>
        <div class="container">
           <div class="child child-header">
               Header
           </div>
           <div class="child child-main">
               Main
           </div>
           <div class="child child-sidebar">
               Sidebar
           </div>
           <div class="child child-footer">
               Footer
           </div>
        </div>
   </body>
</html>
Chú ý rằng, khi bạn định nghĩa các Grid Area một số Grid Line sẽ có thêm tên dựa trên tên của Grid Area, một Grid Line có thể có nhiều tên, giống như mình hinh họa dưới đây.

6. CSS grid-template

Sử dụng CSS grid-template là cách ngắn ngọn để thiết lập grid-template-rows, grid-template-columns, grid-template-areas.
Syntax
.container {
  grid-template: none | <grid-template-rows> / <grid-template-columns>;
}
none
Thiết lập các giá trị cho CSS grid-template-rows, grid-template-columns, grid-template-areas về giá trị ban đầu của chúng.
<grid-template-rows> / <grid-template-columns>
Thiết lập các giá trị cho grid-template-rows, grid-template-columns, và thiết lập giá trị none cho grid-template-areas.
Ví dụ:
.container {
   display: grid;
   border:1px solid #ddd;
   grid-template: 100px 50px / 150px auto 120px;
}
/* Same As: */
.container {
   display: grid;
   border:1px solid #ddd;
   grid-template-rows: 100px 50px;
   grid-template-columns: 150px auto 120px;
   grid-template-areas: none;
}
Một ví dụ phức tạp với sự tham gia của grid-template-areas:
.container {
   display: grid;
   border:1px solid #ddd;
   grid-template:
         [row1-start] "header header header" 100px [row1-end]
         [row2-start] "main main ." 50px [row2-end]
         [row3-start] "footer footer footer" 50px [row3-end]
        / 150px auto 120px;
}
/* Same As: */
.container2 {
   display: grid;
   border:1px solid #ddd; 
   grid-template-rows: [row1-start] 100px [row1-end row2-start] 50px [row2-end row3-start] 50px [row3-end];
   grid-template-columns: 150px auto 120px;
   grid-template-areas:
          "header header header"
          "main main ."
          "footer footer footer";
}

7. CSS grid-column-start, grid-row-start,..

Để thiết lập vị trí của một Grid Item bạn cần cung cấp giá trị cho 4 thuộc tính (property) sau:
  • grid-column-start
  • grid-column-end
  • grid-row-start
  • grid-row-end
Các thuộc tính (property) nói trên chấp nhận các giá trị số (Là thứ tự của Grid Line). Nó cũng chấp nhận tên của Grid Line, tên của các Grid Line cần phải được định nghĩa trước khi sử dụng.
Syntax
.child {
  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;
}
Mặc định các Grid Line đã được đánh số thứ tự, bắt đầu từ 1:
.container {
   display: grid;
   grid-template-columns: 40px 50px auto 50px 40px;
   grid-template-rows: 35px 50px 30px; 
   border:1px solid #ddd;
   margin-top:10px;
}
.child {
  padding: 5px;
  background: #d4e6f1;
  margin: 5px;
}
.child-1 {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
}
Nếu muốn sử dụng tên bạn cần định nghĩa nó trước khi sử dụng.
.container {
   display: grid;
   grid-template-columns: 40px [line2] 50px auto [line4] 50px 40px;
   grid-template-rows: [row1-start] 35px 50px 30px;

   border:1px solid #ddd;
   margin-top:10px;
}
.child {
  padding: 5px;
  background: #d4e6f1;
  margin: 5px;
}
.child-1 {
  grid-column-start: line2;
  grid-column-end: line4;
  grid-row-start: row1-start;
  grid-row-end: 3;
}
.container {
   display: grid;
   grid-template-columns: 40px 50px auto [col4-start] 50px 40px;
   grid-template-rows: 35px 50px 30px;

   border:1px solid #ddd;
   margin-top:10px;
}
.child {
  padding: 5px;
  background: #d4e6f1;
  margin: 5px;
}
.child-1 {
   grid-column-start: 2;
   grid-column-end: span col4-start;
   grid-row-start: 2;
   grid-row-end: span 2;
}
Chú ý: Nếu CSS grid-colum-end, CSS grid-row-end không được cung cấp chúng sẽ có giá trị mặc định là "span 1".
Các Grid Item có thể chồng chéo (overlap) lên nhau, vì vậy bạn có thể sử dụng CSS z-index để kiểm soát chúng.
grid-overlap-example.css
.container {
   display: grid;
   grid-template-columns: 40px 50px auto 50px 40px;
   grid-template-rows: 35px 50px 30px;

   border:1px solid #ddd;
   margin-top:10px;
}
.child {
  padding: 5px;
  background: #d4e6f1;
  margin: 5px;
}
.child-1 {
   grid-column-start: 2;
   grid-column-end: 4;
   grid-row-start: 2;
   grid-row-end: 4;
   z-index: 1000;
   background: lightblue;
}
.child-2 {
    grid-column-start: 3;
    grid-column-end: 5;
    grid-row-start: 1;
    grid-row-end: 3;
    z-index: 2000;
    background: lightgreen;
  }
grid-overlap-example.html
<!DOCTYPE html>
<html>
   <head>
      <title>CSS grid-column-*, grid-row-*</title>
      <meta charset="UTF-8"/>
      <link rel="stylesheet" href="grid-overlap-example.css" />
   </head>
   <body>
       <h3>CSS Overlap Grid Items</h3>
        <div class="container">
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
        </div> 
        <div class="container">
          <div class="child child-1"></div>
          <div class="child child-2"></div>
        </div>
   </body>
</html>

8. CSS grid-column, grid-row

Sử dụng CSS grid-column là cách ngắn gọn để thiết lập giá trị cho grid-column-start, grid-column-end. Tương tự, sử dụng CSS grid-row là cách ngắn gọn để thiết lập giá trị cho grid-row-start, grid-row-end.
Syntax
.child {
  grid-column: <start-line> / <end-line> | <start-line> / span <value>;
  grid-row: <start-line> / <end-line> | <start-line> / span <value>;
}
Ví dụ:
grid-column-row-example.css
.container {
   display: grid;
   grid-template-columns: 40px [line2] 50px auto [line4] 50px 40px;
   grid-template-rows: [row1-start] 35px 50px 30px;

   border:1px solid #ddd;
   margin-top:10px;
}
.child {
  padding: 5px;
  background: #d4e6f1;
  margin: 5px;
}
.child-1 {
  background: lightblue;
  grid-column : line2 / line4;
  grid-row : row1-start / 3;
} 
.child-2 {
   background: lightgreen;
   grid-column : 1 / span 2;
   grid-row : 2 / 4;
  }
grid-column-row-example.html
<!DOCTYPE html>
<html>
   <head>
      <title>CSS grid-column, grid-row</title>
      <meta charset="UTF-8"/>
      <link rel="stylesheet" href="grid-column-row-example.css" />
   </head>
   <body>
       <h3>CSS grid-column, grid-row</h3>
        <div class="container">
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
          <div class="child"></div>
        </div> 
        <div class="container">
          <div class="child child-1">Child 1</div>
          <div class="child child-2">Chid 2</div>
        </div>
   </body>
</html>

9. CSS grid-column-gap, grid-row-gap

CSS grid-column-gap, CSS grid-row-gap được sử dụng để sét đặt chiều rộng cho Grid Line. Điều này tạo ra khoảng cách giữa các Grid Track.
CSS grid-row-gap, CSS grid-column-gap chấp nhận giá trị cụ thể, chẳng hạn 1px, 2em,... hoặc giá trị phần trăm ( % ).
.container {
  grid-template-columns: 100px auto 100px;
  grid-template-rows: 80px auto 80px;
  grid-column-gap: 10px;
  grid-row-gap: 15px;
}
Chú ý: grid-column-grid, grid-row-grid đang được đổi tên thành column-grid, row-grid. Và nó đã sẵn sàng trong các trình duyệt:
Firefox 63+, Chrome 68+, Safari 11.2 Release 50+, Opera 54+.
CSS grid-gap
Sử dụng CSS grid-gap là cách ngắn gọn để thiết lập giá trị cho grid-row-gap & grid-column-gap.
Syntax
.container {
  grid-gap: <grid-row-gap> <grid-column-gap>;
}
Ví dụ:
.container {
  grid-template-columns: 100px auto 100px;
  grid-template-rows: 80px auto 80px;
  grid-gap: 15px 10px;
}
.container {
   ...
  grid-gap: 15px ;
}
/* Same as: */
.container {
   ...
  grid-gap: 15px 15px;
}

10. CSS justify-items

CSS justify-items được sử dụng cho phần tử cha, để căn chỉnh (align) theo phương ngang cho các phần tử con của nó. Các giá trị có thể của nó là:
  • start
  • end
  • center
  • stretch (Default)
.container  {
   justify-items: start | end | center | stretch;
}
CSS {justify-items:start}
Căn chỉnh các Grid Item sang bên trái ô chứa nó.
CSS {justify-items:end}
Căn chỉnh các Grid Item sang bên phải ô chứa nó.
CSS {justify-items:center}
Căn chỉnh các Grid Item vào chính giữa ô chứa nó theo phương ngang.
CSS {justify-items:stretch}
Làm cho các Grid Item lấp đầy ô chứa nó theo chiều ngang.

11. CSS justify-self

CSS justify-self được sử dụng để căn chỉnh theo phương nằm ngang cho một Grid Item trong một Grid Cell (Hoặc Grid Area). Các giá trị của nó có thể là:
  • start
  • end
  • center
  • stretch (Default)
.child {
   justify-self: start | end | center | stretch;
}
justify-self-example.css
.container {
     display: grid;
     grid-template-rows: 150px 100px;
     grid-template-columns: auto auto;
     border:1px solid #ddd;
}
.child {
     padding: 5px;
     background: #d4e6f1;
     margin: 5px;
}
.child-1 {
     justify-self: start;
}
.child-2 {
     justify-self: end;
}
.child-3 {
     justify-self: center;
}
.child-4 {
     justify-self: stretch;
}
justify-self-example.html
<!DOCTYPE html>
<html>
   <head>
      <title>CSS justify-self</title>
      <meta charset="UTF-8"/>
      <link rel="stylesheet" href="justify-self-example.css" />
   </head>
   <body>
       <h2>CSS justify-self</h2>
        <div class="container">
           <div class="child child-1">
               justify-self: start
           </div>
           <div class="child child-2">
               justify-self: end
           </div>
           <div class="child child-3">
               justify-self: center
           </div>
           <div class="child child-4">
               justify-self: stretch
           </div>
        </div>
   </body>
</html>

12. CSS align-items

CSS align-items được sử dụng cho phần tử cha, để căn chỉnh (align) theo phương thẳng đứng cho các phần tử con của nó. Các giá trị có thể của nó là:
  • start
  • end
  • center
  • stretch (Default)
.container  {
   align-items: start | end | center | stretch;
}
CSS {align-items:start}
Căn chỉnh các Grid Item đến cạnh trên (top) của ô lưới.
CSS {align-items:end}
Căn chỉnh các Grid Item đến cạnh dưới (bottom) của ô lưới.
CSS {align-items:center}
Căn chỉnh các Grid Item vào chính giữa (middle) ô chứa nó theo phương thẳng đứng.
CSS {align-items:stretch}
Làm cho các Grid Item lấp đầy ô chứa nó theo chiều thẳng đứng.

13. CSS align-self

CSS align-self được sử dụng để căn chỉnh theo phương thẳng đứng cho một Grid Item trong một Grid Cell (Hoặc Grid Area). Các giá trị của nó có thể là:
  • start
  • end
  • center
  • stretch (Default)
.child {
   align-self: start | end | center | stretch;
}
align-self-example.css
.container {
     display: grid;
     grid-template-rows: 150px 100px;
     grid-template-columns: 200px auto;
     border:1px solid #ddd;
}
.child {
     padding: 5px;
     background: #d4e6f1;
     margin: 5px;
}
.child-1 {
     align-self: start;
}
.child-2 {
     align-self: end;
}
.child-3 {
     align-self: center;
}
.child-4 {
     align-self: stretch;
}
align-self-example.html
<!DOCTYPE html>
<html>
   <head>
      <title>CSS align-self</title>
      <meta charset="UTF-8"/>
      <link rel="stylesheet" href="align-self-example.css" />
   </head>
   <body>
       <h2>CSS align-self</h2>
        <div class="container">
           <div class="child child-1">
               align-self: start
           </div>
           <div class="child child-2">
               align-self: end
           </div>
           <div class="child child-3">
               align-self: center
           </div>
           <div class="child child-4">
               align-self: stretch
           </div>
        </div>
   </body>
</html>