Kiến thức lập trình

Luyện tập CSS Grid qua bài tập tạo layout Airbnb, youtube, Pinterest

  • Tác giả NIIT - ICT HANOI

  • Ngày đăng 20/ 04/ 2018

  • Bình luận 0 Bình luận

Học điều mới tốt nhất là thông qua thực hành, làm thực tế. Để bạn hiểu hơn về CSS Grid thì tôi sẽ cùng bạn thực hiện các bài luyện tập Css Grid thông qua việc dựng layout cơ bản của các trang web quen thuộc.

Lưới CSS là gì?

Các thuật ngữ trong CSS Grid

Grid Container

Grid Item

Grid Line

Grid Cell

Grid Area

Học CSS Grid thông qua các ví dụ

1. Xây dựng gird layout website Airbnb

2. Xây dựng layout Youtube bằng CSS Grid

3. Xây dựng layout Pinterest bằng CSS Grid

Tôi nghĩ luyện tập sẽ giúp bạn hiểu rõ hơn các khái niệm nhanh hơn nhiều.

Đối với mỗi layout, tôi đã dựng khung chính để cho bạn hiểu cách Grid làm việc như thế nào.

Lưu ý:

- Tôi đã bỏ qua hầu hết các chi tiết phức tạp về cách xử lý bố cục (hoạt ảnh, dữ liệu, v.v.) để tập trung vào việc khám phá cách bố trí và các tính năng Grid hoạt động như thế nào.

- Vì vậy, xin lưu ý rằng các chi tiết có thể không được chính xác như bản chính thức.

Mục tiêu của tôi trong bài viết này là để phục vụ tham khảo và một hướng dẫn để bố trí tương tự như Bootstrap nhưng với số code ít hơn (đó là lý do tại sao CSS Grid tốt hơn).

Tôi cũng dự định sẽ cập nhật thêm các ví dụ thiết kế layout vào bài viết này khi có thêm thời gian:

Các layout đang có:

1. Airbnb home page

2. YouTube home page

3. Pinterest home view

Layout dự kiến:

4. Soundcloud

5. Bloomberg

6. Huffington Post

Lưới CSS là gì?

 

CSS Grid Layout nổi bật khi chia trang thành các vùng lớn hoặc xác định mối quan hệ về size, position, và layer, giữa các phần được xây dựng từ HTML cơ bản.

Giống như table, Grid layout cho phép tác giả sắp xếp các phần tử thành các cột và hàng.

Tuy nhiên, nhiều layout khác làm bằng CSS Grid có thể dễ dàng hơn so với các bảng (bảng không được ưu tiên vì làm chậm tốc độ load).

Ví dụ: Các phần tử con của vùng grid container có thể tự định vị để chúng có thể đặt lên các layer, giống như các phần tử được định vị bằng CSS.

Tóm lại, CSS Grid cung cấp một tập hợp các công cụ sắp xếp layout và các công cụ mà các cài đặt hiện tại của layout theo cột và hàng được tạo ra từ việc sử dụng các thuộc tính witdh và height.

CSS Grid còn làm được nhiều hơn thế. Nó có thể tự động cập nhật các thuộc tính dựa trên các quy tắc bạn xác định (Chẳng hạn như: "khi trình duyệt có chiều rộng này, hãy làm điều này").

Do đó, tôi tin rằng CSS Grid là tương lai của các lập trình viên front-end.

Đối với những người mới tiếp xúc với khái niệm về grid: Một Grid là một tập hợp của các đường thằng, các đường ngang và dọc cho phép định vị vị trí các phần tử.

Các thuật ngữ trong CSS Grid

Grid Container

Grid Container là cha của tất cả các phần tử bên trong nó. Nó định nghĩa trạng thái ban đầu của các đường lưới (dọc và ngang).

Để tạo một CSS Grid, bạn chỉ cần thêm display: grid; cho class wapper hoặc container mà bạn đang làm việc trong document của mình.

Grid Item

Tất cả các item của các grid container được tham chiếu như là grid items.

Grid Line

Các đường lưới (grid lines) đại diện cho các đường dọc (vertical) và đường ngang (horizontal).

Thuộc tính grid-template-columns nghĩa các vị trí cột và grid-template-rows định nghĩa vị trí hàng.

Grid Cell

Đây là khu vực nhỏ nhất trong grid layout đó là không gian được xác định bởi bốn đường lưới.

Grid Area

Grid area là một vùng named-container-area chứa các khu vực được đặt tên cụ thể và xác định bởi các đường lưới được xác định khi viết css.

Học CSS Grid thông qua các ví dụ

1. Xây dựng gird layout website Airbnb

 

 

Document Layout:

<div class="wrapper">
  <header class="header">Airbnb</header>
    
  <article class="content">
    
  	<div class="panel">
  		<img src="#" />
  		<span>Home name</span>
  	</div>
    
    <!-- Rest of the home items ... -->
    
  </article>
  
  <aside class="sidebar">Sidebar - Map</aside>
  
</div>

Main Grid:

.wrapper {
  margin: 0 auto;
  display: grid;
  grid-template-columns: 65% 35%;
  grid-gap: 16px;
}

Class wrapper định nghĩa vùng chứa toàn bộ lưới, cái chứa các khối document chính (article là khu vực mà các item chính được chứa, bên cạnh đó là adside chứa sidebar map).

Sau khi thuộc tính display: grid; đã được thiết lập, layout đã được kích hoạt thuộc tính Grid

Các grid-template-columns khai báo kích thước (track-size) của cột, ở đây sử dụng giá trị % để responsive.

track-size có thể sử dụng px, %, hoặc đơn vị fr (một phần của không gian trống trong lưới)

.content {
  padding: 8px;
  display: grid;
  margin: 0 auto;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)) ;
  grid-auto-rows: minmax(264px, auto);
  grid-gap: 16px;
}

Main grid chứa một container thứ cấp (sub-grid) với một class-name của class .content. Điều này đại diện cho diện tích của phần tử bài viết chứa tất cả các mục chủ.

sub-grid được xác định bằng cả hai cột cũng như hàng để tất cả các item có thể có được kích thước phù hợp.

Có một vài điều mới được sử dụng ở đây vì vậy hãy khám chúng.

Khi định nghĩa các cột ta sử dụng repeat(auto-fill, minmax(300px, 1fr));

repeat() tránh được sự lặp lại của việc khai báo kích thước cho các cột. Nhưng nó sẽ thú vị hơn khi nó được sử dụng auto-fill.

Khi auto-fill được sử dụng, nếu grid container có kích thước xác định hoặc max-size trong trục có liên quan, thì số lần lặp lại là số nguyên dương lớn nhất có thể không gây ra tràn.

Bằng cách sử dụng tự auto-fill với repeat (), Grid có thể tự tìm ra có bao nhiêu item nó có thể đặt phù hợp trong kích thước vùng chứa đó.

Hàm minmax định nghĩa một phạm vi lớn hơn hoặc bằng min và nhỏ hơn hoặc bằng max

Nếu max <min, thì max sẽ bị bỏ qua và  hàm minmax (min, max) được coi là min.

Đơn vị fr cho phép bạn thiết lập kích thước của một phần nhỏ của không gian trống của grid container.

Ví dụ sau đây sẽ đặt mỗi mục một phần ba chiều rộng của vùng chứa lưới:

minmax cho phép chúng ta thiết lập cụ thể chiều rộng item phải được giữ cố định trong khi thay đổi kích cỡ màn hình.

Với các cột được khai báo, chúng ta khai báo thêm: grid-auto-rows: minmax(275px, auto); để giữ chiều cao của hàng nhỏ nhất là 275px.

Chúng tôi đã sử dụng lại lần nữa để thiếp lập chiều cao tối đa của mỗi mục được đặt trên sub-grid, trong trường hợp này mỗi phần sẽ là 275px.

Nó giống hệt như maximum. Minimum đại diện cho kích thước tối thiểu lớn nhất của các item bên trong lưới. (Sử dụng min-witdh / min-height)

auto-fill được sử dụng thay vì 1fr trong khai báo cột bởi vì chúng tôi muốn số lượng của item thay đổi dựa trên chiều rộng của cột.

@media (max-width: 1100px) {
  .wrapper {
    grid-template-columns: 1fr;
  }
  
  .sidebar {
    display: none;
  }
  
  .content {
    width: 100%;
    grid-template-columns: repeat(auto-fill, minmax(360px, 1fr) ) ;
    grid-auto-rows: minmax(300px, auto);
  }  
}

Điều hay về CSS Grid trong ví dụ này là layout chỉ yêu cầu một truy vấn @media đơn giản để làm ra layout responsive.

Sự khác biệt chính trong cách bố trí trong truy vấn @media là main grid, ban đầu chứa hai cột được xác định theo % bây giờ có một cột được xác định với track-size là đơn vị 1fr (Tôi cũng đã giấu sidebar khi màn hình chỉ đủ hiển thị 2 cột).

Sau đó, đối với mỗi item được sử dụng cùng một thuộc tính nhưng sự khác biệt chính là tôi đã tăng width và height của các item lên thành (360px, 300px).

Đó là trang của Airbnb, bạn có thể xem lại ví dụ ở codepen để biết cách hoạt động của nó.

2. Xây dựng layout Youtube bằng CSS Grid

 

 

Document Layout:

<div class="wrapper">
  <header class="header">Youtube</header>
  
  <aside class="sidebar">Sidebar</aside>
    
  <article class="content">
    
     <div class="panel">
      <img class="panel-img" src="#">
      <span class="panel-title">Title of the video</span>
       <br>
      <span class="panel-subtitle">346,112 views</span>
    </div>
    
    <!--   Rest of the video items ... -->
    
    </article>
    
</div>

Main Grid:

.wrapper {
  margin: 0 auto;
  display: grid;
  grid-template-columns: 15% 85%;
  grid-gap: 16px;
}

Class wrapper dùng để định nghĩa cho main grid, có hai cột được định nghĩa với kích thước là 15% và 85%.

CSS cho nội dung bên trong <articles>

.content {
  padding-right: 64px;
  padding-left: 64px;
  display: grid;
  margin: 0 auto;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-auto-rows: minmax(150px, auto);
  grid-gap: 8px;
}

Ô bên trong grid sẽ được định nghĩa thông qua class .content .

Tôi đã sử dụng repeat(auto-fill, minmax(200px, 1fr)); để định nghĩa các cột, mỗi một mục video sẽ có kích thước nhỏ nhất là 200px và  tự động điền vào cột 1fr.

Hàng được định nghĩa bằng thuộc tính grid-auto-rows: minmax(150px, auto);. Mỗi một hàng sẽ có chiều cao là 150px, số lượng không hạn chế.

@media (max-width: 1200px) {
  .wrapper {
    grid-template-columns: 2fr; /* 1 cột đơn vị 2fr */
  }
  
  .sidebar {
    display: none; ?* Ẩn sidebar khi kích thước màn hình nhỏ hơn 1200px */
  } 
  
  .content {
    width: 100%;
    grid-template-columns: repeat(auto-fill, minmax(200px, 2fr));
/* Nội dung sẽ tự động điền, kích thước nhỏ nhất của các item là 200px điền vào 2 đơn vị fr*/
    grid-auto-rows: minmax(150px, auto);
/* Mỗi hàng cao ít nhất 150px, số lượng hàng không cố định trước*/
  }
}

@media (max-width: 768px) {
  .content {
    padding-right: 48px;
    padding-left: 48px;
    grid-template-columns: repeat(3, minmax(200px, 3fr));
    grid-auto-rows: minmax(150px, auto);
  }
}

@media (max-width: 700px) {
  .content {
    padding-right: 116px;
    padding-left: 116px;
    grid-template-columns: repeat(2, minmax(200px, 2fr));
    grid-auto-rows: minmax(150px, auto);
  }
}

Có ba điểm dừng khác nhau được sử dụng để phản ánh responsive của trang chủ YouTube.

Sự khác biệt chính bên trong layout là chúng tôi ẩn sidebar và xác định các cột khác nhau cho các mục video.

Đối với máy tính bảng, số lượng cột được đặt thành 3fr có nghĩa là có 3 cột cụ thể mà các video có thể phù hợp bên trong cho đến khi nó đạt đến điện thoại di động nơi nó được cố định ở 2 cột hai cột.

Khi bố cục co lại khoảng padding quanh các mục video (trái, phải) tăng, để đảm bảo kích thước của các hình thu nhỏ không tăng.

Vui lòng xem lại ví dụ CodePen ở trên để biết cách hoạt động.

3. Xây dựng layout Pinterest bằng CSS Grid

 

 

Document Layout:

<div class="wrapper">
  <header class="header">Pinterest</header>
    
  <article class="content">
    
    <div class="panel tall-panel">
      <img class="panel-img" src="#" />
    </div>
    
    <!--   Rest of the pin items ... -->
    
   </article>
    
</div>

Main Grid:

.wrapper {
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr;
  grid-gap: 16px;
}

Trong lớp class wrapper, chúng tôi xác định vùng chứa main grid và một cột đơn có kích thước là 1fr.

.content {
  padding-right: 40px;
  padding-left: 40px;
  display: grid;
  margin: 0 auto;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  grid-auto-rows: minmax(200px, auto);
  grid-gap: 16px;
}

Bên trong class content chúng ta sẽ xác định cột và hàng.

Khi xác định các cột chúng tôi đã sử dụng hàm repeat(auto-fill, minmax (240px, 1fr));

Với các colums đã tuyên bố chúng tôi di chuyển lên các dòng bằng grid-auto-rows: minmax (200px, auto);

Chúng tôi đã sử dụng minmax một lần nữa ở đây để cụ thể chiều rộng tối đa của mỗi mục đang được đặt trên lưới phụ, trong trường hợp này mỗi item sẽ được 200px.

auto được sử dụng thay vì 1fr trong khai báo cột bởi vì chúng tôi muốn độ rộng của mục tự động thay đổi dựa trên chiều rộng của cột.

@media (max-width: 1200px) { 
  .content {
    padding-right: 72px;
    padding-left: 72px;
    width: 100%;
    grid-template-columns: repeat(3, minmax(220px, 1fr) ) ;
    grid-auto-rows: minmax(200px, auto);
  }  
}

Truy vấn @media đơn giản được sử dụng để tạo bố cục responsive, nơi chúng tôi cập nhật class.content với khoảng đệm bổ sung xung quanh các ghim.

Các chi tiết quan trọng về cách chúng tôi xử lý các chốt tại thời điểm này đang thay đổi auto-fill value trong phương thức lặp lại thành 3 lưới (chúng ta muốn không ít hơn 3 cột trong khung nhìn).

Đó là layout của Pinterest, một bố cục tương đối đơn giản so với những trang khác. Vui lòng xem lại ví dụ CodePen ở trên để xem nó hoạt động như thế nào.

Hiện tại đây là tất cả, tôi sẽ bổ sung các layout khác trong suốt năm tới và tôi hy vọng phát triển các bố cục phức tạp hơn.

Note: Nếu bạn muốn học lập trình từ cơ bản đến chuyên sâu về front end hoặc lập trình web, hãy liên hệ với NIIT - ICT Hà Nội để được tư vấn học gì? bắt đầu học như thế nào tốt nhất.