Hướng dẫn thiết kế bố cục bài viết dạng grid cho widget

Thiết kế bố cục thế nào cho cân đối, đều nhau không bị lệch, cách đếm số thứ tự css của mỗi post như thế nào sẽ được mình tổng hợp trong bài viết hướng dẫn thiết kết bố cục dạng grid cho widget. Đầu tiên mình giải thích Grid hay còn gọi là Lưới là gì? Đó là một tổ hợp của những đường ngang và dọc cắt nhau - một nhóm xác định các cột và nhóm kia xác định các hàng. Các phần tử có thể được đặt lên lưới, dựa vào các đường hàng và cột này.

Nói đơn giản thì các bài viết được sắp thành các hàng ngang nhau tùy thuộc vào độ rộng của mỗi bài mà mỗi hàng có thể sắp xếp được bao nhiêu bài. Bây giờ để đi và phân tích bố cục chúng ta cần có HTML hiển thị mình sẽ lấy bố cục như sau:

<div class="main-wrapper"
  <div class="widget HTML" data-version="2" id="HTML1 ">
    <div class="posts">
      <ul>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
      </ul>
    </div>
  </div>
</div>

Trong đó các phần tử li đại diện cho một post (bài viết) được nằm trong vòng lặp của phần tử ul được cố định trong phần tử div có class="posts". Tất cả các phần tử con này nằm trong phần tử div chính có class="widget HTML" và id="HTML1".

Đầu tiên định hình cho bố cục thân trang của phần tử div có class="main-wrapper" bao ngoài tất cả các class còn lại có kích thước rộng tối đa bằng ví dụ 1100px

.main-wrapper {
    position: relative;
    display: block;
    float: left;
    max-width: 1100px;
    margin: auto;
}

Khi định hình bố cục chính xong bắt đầu đi vào thiết kế cho phần tử con tiếp theo có class="posts", đây là phần tử bao ngoài tất cả các bài viết

.posts {
    background: #fff;
    margin-bottom: 15px;
    float: left;
    width: 100%;
    padding: 15px 15px 0 15px;
    border: 1px solid rgba(0, 0, 0, 0.12);
    border-radius: 4px;
    clear: both;
}

Tiếp theo cần xác định mỗi hàng có bao nhiêu bài viết hay phần tử li, độ rộng của mỗi phần tử li được tính bằng 100% chia cho số bài muốn hiển thị trong một hàng, vì chúng ta có phần tử div class="posts" có độ rộng 100% tương đương rộng tối đa 1100px. Như vậy nếu muốn mỗi hàng ngang có bao nhiêu bài thì lấy 100% chia cho bấy nhiêu bài

Giả sử theo ví dụ HTML chúng ta có 10 phần tử li mà muốn mỗi hàng có 5 thì chúng ta có 2 hàng và mỗi phần tử li đều có độ rộng bằng 100% chia cho 5 bằng 20%.

Tiếp theo chúng ta cần khoảng cách giữa mỗi phần tử li chúng ta sử dụng thuộc tính padding, tổng hợp như sau:

.posts ul li {
    padding: 0 7.5px 15px 7.5px; // khoảng cách trái, phải 7.5px và dưới 15px
    width: 20%; // rộng 20%
    display: inline-block;
    vertical-align: top;
    position: relative;
}

Vì chúng ta kéo độ rộng trái, phải là 7.5px của mỗi phần tử li dẫn đến các phần tử li ngoài cùng bên trái bị giãn 7.5px và ngoài cùng bên phải bị giãn 7.5px do đó tổng kích thước của các phần tử cộng lại của mỗi hàng lớn hơn 100% như vậy sẽ bị nhảy hàng. Do đó cần kéo giản phần tử ul hai bên mỗi bên 7.5px

.posts ul {
    margin: 0 -7.5px;
}

Trên đây là cách chia đều cho mỗi phần tử li như vậy mỗi hàng và mỗi cột đều nhau. Bây giờ mở rộng ra chia các thành phần li không đều nhau và thêm một cột do vậy độ rộng của mỗi phần tử khác nhau và các cột không thẳng hàng nhau.

Tương tự với 10 phần tử li mà muốn chia 3 cột với hàng đầu tiên 2 phần tử, hàng thứ hai 5 phần tử li tiếp theo và hàng thứ ba với 3 phần tử cuối cùng. Như vậy với hàng đầu tiên có 2 post vậy mỗi post rộng 50%, 5 post tiếp theo của hàng thứ hai có độ rộng 20% và 3 post của hàng thứ ba có độ rộng 33.33%.

Trong css có đánh số thứ tự từ trái qua phải của mỗi hàng trên cùng và từ phải qua trái với hàng cuối cùng áp dụng với dạng lưới và từ trên xuống và từ dưới lên áp dụng cho dạng cột như sau:

- Hàng trên cùng từ trái qua phải sử dụng thuộc tính :nth-of-type(1), :nth-of-type(2), :nth-of-type(3)...
- Hàng cuối cùng từ phải qua trái sử dụng thuộc tính :nth-last-of-type(1), :nth-last-of-type(2), :nth-last-of-type(3)...

Áp dụng chia bố cục cho các phần tử đả sắp xếp như trên ta được

- 2 bài viết của hàng đầu tiên:

.posts ul li:nth-of-type(1), .posts ul li:nth-of-type(2) {
    width: 50%;
}

- 5 bài viết tiếp theo của hàng thứ 2 chúng ta đã tạo css .posts ul li bên trên có width:20% rồi nên không cần thêm nữa

- 3 bài viết cuối cùng của hàng thứ ba:

.posts ul li:nth-last-of-type(1), .posts ul li:nth-last-of-type(2), .posts ul li:nth-last-of-type(3) {
    width: 33.33%;
}

Ngoài ra còn sử dụng thuộc tính :fisrt-child cho post đầu tiên và :last-child cho post cuối cùng nhưng thuộc tính này chỉ nên áp dụng cho bố cục dạng cột thôi.

Tiếp theo chúng ta sẽ định hình cho các phần tử con nằm trong mỗi phần tử li để hình thành nên thông tin 1 post, ví dụ ta có HTML của 1 phần tử li như sau:

<li>
  <div class="post-thumb"> // Ảnh
    <a href="" title=""><img alt="" src=""></a>
  </div>
  <h2 class="post-title"> // Tiêu đề
    <a href="" title=""></a>
  </h2>
  <div class="post-meta"> // Thông tin
    <span class="post-author"><a href="" title=""></a></span> // Tác giả
    <span class="post-date"></span> // Thời gian
  </div>
  <p class="post-snippet"></p> // Tóm tắt
</li>

Như vậy chúng ta có 4 phần tử con chính trong một phần tử li là được sắp xếp thành các hàng đều nhau từ trên xuống:

- Ảnh
- Tiêu đề
- Thông tin bao gồm 2 phần tử con tác giả và thời gian
- Tóm tắt

+ Với Ảnh sử dụng class="post-thumb"

.posts ul li .post-thumb {
    width: 100%;
    height: 140px;
    overflow: hidden;
    margin-bottom: 10px;
}
.posts ul li .post-thumb img {
    width: 100%;
    height: 100%;
}

Tương tự như các phần tử li được chia thành hàng thì các phần tử con của li cũng phải chia thành hàng chỉ có điều với mỗi phần tử là một hàng. Lấy ví dụ như tiêu đề bài viết phải được cắt thành 1 hoặc hai hàng.., đều nhau nhưng do tiêu đề bài viết có thể dài hoặc ngắn do độ rộng của main-wrapper như ví dụ ở màn hình kích thước 1100px mà hàng thứ ba có 3 post như vậy có thể có một post sẽ có tiêu đề 1 hàng do tiêu đề bài viết ngắn dẫn đến post bên dưới bị nhảy hàng vậy thống nhất cho tiêu đề chỉ 1 hàng đều nhau.

+ Tiêu đề sử dụng class="post-title"

.posts ul li .post-title {
    font-size: 16px;
    font-weight: bold;
    line-height: 1.6;
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.posts ul li .post-title a {
    display: block;
    color: #000;
}

Tương tự ngay dưới tiêu đề sẽ có 2 class thông tin tác giả và thời gian cũng được đặt thành 1 hàng

+ Thông tin sử dụng class="post-meta"

.posts ul li .post-meta {
    font-size: 15px;
    font-weight: normal;
    line-height: 1.6;
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.posts ul li .post-meta span, .posts ul li .post-meta a {
    color: rgb(136,136,136);
}
.posts ul li span.post-author:after {
    content: "-";
    padding: 0 5px;
}

+ Cuối cùng là tóm tắt chúng ta có thể chia đều thành 2 hàng như sau:

.posts ul li .post-snippet {
    font-size: 15px;
    font-weight: normal;
    line-height: 1.6;
    xolor: #000;
    display: -webkit-box;
    overflow: hidden;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    white-space: normal;
    text-overflow: ellipsis;
}

Trên đây là các phần tử con đặt trong một phần tử li hiển thị thông tin của 1 post áp dụng với cá phần tử li chia đều nhau. Nhưng nếu các phần tử li được chia không đều nhau như ví dụ bên trên thì phài áp dụng thuộc tính thứ tự vào mỗi class của mỗi phần tử con, ví dụ:

- Ảnh áp dụng với 2 post đầu tiên có độ rộng 50%

.posts ul li:nth-of-type(1) .post-thumb, .posts ul li:nth-of-type(2) .post-thumb {
    height: 240px;
}

- Ảnh áp dụng với 3 post cuối có độ rộng 33.33%

.posts ul li:nth-last-of-type(1) .post-thumb, .posts ul li:nth-last-of-type(2) .post-thumb,  .posts ul li:nth-last-of-type(3) .post-thumb {
    height: 185px;
}

Tương tự như các phần tử con khác còn lại còn lại cũng phải được thêm thuộc tính thứ tự như ảnh.

Làm việc với reponsive

Khi độ rộng màn hình thu bé lại theo các kích thước của các thiết bị nhỏ hơn độ rộng 1100px ví dụ như ipad là 768px thì độ rộng của các post sẽ hẹp lại chẳng hạn ban đầu các post được chia độ rộng 20% để có mỗi hàng 5 post với độ rộng 1100px nhưng khi giảm xuống còn 768px thì cần chỉnh lại độ rộng xuống còn 33.33% để chỉ còn mỗi hàng 3 post

media (max-width:768px) {
    .posts ul li {
        width: 33.33%;
    }
    .posts ul li .post.thumb {
        height: 145px;
    }
}

Kết luận:

Qua bài viết này bạn đã hiểu và nắm căn bản các bước để tạo được bố cục bài viết dạng Grid tuy nhiên bạn phải thực hành nhiều để nắm rõ hơn đặc biệt là khi thiết kế reponsive và khi thiết kế các post sắp xếp hàng ngang có độ rộng không đều nhau, lúc đó cần sử dụng nhiều thuộc tính css hơn.
Bài đăng mới hơn Bài đăng cũ hơn
Bài viết này có hữu ích không?