+7

Responsive table với CSS - phần 2

Ở phần 1, chúng ta đã thực hiện responsive cho table dạng đơn giản. Tuy nhiên, không phải lúc nào 1 table cũng chỉ có dạng mỗi cột tương ứng với mỗi hàng hoặc mỗi hàng tương ứng với mỗi cột, ta có thể xem ví dụ của 1 table khác với table ở bài trước như hình dưới đây:

1.PNG

Trong table này, trên 1 hàng không còn kiểu mỗi ô tương ứng với nhau theo từng cột nữa mà là 1 ô ở cột này có thể tương ứng với 2 hoặc nhiều ô khác trên cùng 1 hàng. Ví dụ như ở hình trên, trên mỗi hàng ô đầu tiên sẽ tương ứng với 2 hàng ở ô thứ 2 và thứ 3.

#Xử lý

Ta có cấu trúc HTML của table này như sau:

<div class="main-match">
  <h3>Round 1</h3>
  <table class="table table-customize table-responsive">
    <thead>
      <tr>
        <th>Match ID</th>
        <th>Game</th>
        <th>Detail</th>
        <th>Result</th>
        <th>Comment</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td rowspan="2" data-title="Match ID" class="col-id">1</td>
        <td data-title="Game" class="col-game">
          <div class="inner">
            <span class="team win">[admin] The senior (1)</span>
            <span class="vs">vs</span>
            <span class="team lose">[admin] The senior (2)</span>
          </div>
        </td>
        <td data-title="Detail">
          <a class="link-inline" href="#">Show</a>
        </td>
        <td rowspan="2" data-title="Result">
          Lorem ipsum dolor sit amet.
          <span class="badge">Won</span>
        </td>
        <td rowspan="2" data-title="Comment" class="col-comment">
          Lorem ipsum dolor sit
        </td>
      </tr>
      <tr>
        <td data-title="Match ID" class="col-id phone-visible">1</td>
        <td data-title="Game" class="col-game">
          <div class="inner">
            <span class="team draw">[admin] The senior (3)</span>
            <span class="vs">vs</span>
            <span class="team draw">[admin] The senior (4)</span>
          </div>
        </td>
        <td data-title="Detail">
          <a class="link-inline" href="#">Show</a>
        </td>
        <td rowspan="2" data-title="Result" class="phone-visible">
          Lorem ipsum dolor sit amet.
          <span class="badge">Won</span>
        </td>
        <td rowspan="2" data-title="Comment" class="phone-visible" class="col-comment">
          Lorem ipsum dolor sit amet
        </td>
      </tr>
    </tbody>
  </table>
</div>

Dùng CSS để style cho table:

.table-customize {
    margin: 0;
    border-radius: 4px;
    overflow: hidden;
    box-shadow: 0 0 0 1px #ccc inset;
}
.table-customize > thead > tr {
    background-color: #535353;
    border-radius: 3px 3px 0 0;
}
.table-customize > thead > tr > th {
    color: #ffffff;
    border-bottom: none;
    padding: 10px 14px;
    font-size: 14px;
    font-weight: 600;
    font-weight: 400;
    font-family: "Open Sans", sans-serif;
    border: 1px solid rgba(0, 0, 0, 0.2);
    vertical-align: middle;
}
.table-customize > thead > tr > th:first-child {
    border-radius: 3px 0 0 0;
    border-top: 1px solid rgba(0, 0, 0, 0.2);
}
.table-customize > thead > tr > th:last-child {
    border-radius: 0 3px 0 0;
}
.table-customize > tbody > tr > td {
    vertical-align: middle;
    padding: 15px 14px;
    color: #000;
    font-size: 14px;
    border: 1px solid #ccc;
}
@media (max-width: 767px) {
    .table-responsive,
    .table-responsive thead,
    .table-responsive tbody,
    .table-responsive th,
    .table-responsive td,
    .table-responsive tr {
        display: block;
    }
    .table-responsive td[class*="col-"],
    .table-responsive th[class*="col-"] {
        display: block;
    }
    .table-responsive > thead > tr {
        position: absolute;
        top: -9999px;
        left: -9999px;
    }
    .table-responsive > tbody > tr {
        border-top: 1px solid #ccc;
        border-bottom: 1px solid #ccc;
    }
    .table-responsive > tbody > tr:first-child {
        border-radius: 3px 3px 0 0;
        border-top: none;
    }
    .table-responsive > tbody > tr:last-child {
        border-radius: 0 0 3px 3px;
        border-bottom: none;
    }
    .table-responsive > tbody > tr td {
        border: none;
        border-bottom: 1px solid #ccc;
        position: relative;
        padding-left: 30% !important;
        width: 100% !important;
        overflow: hidden;
    }
    .table-responsive > tbody > tr td:before {
        content: attr(data-title);
        position: absolute;
        top: 15px;
        left: 14px;
        width: 30%;
        padding-right: 10px;
        white-space: nowrap;
        font-size: 14px;
        text-overflow: ellipsis;
        overflow: hidden;
    }
    .table-responsive > tbody > tr td:first-child {
        text-align: left;
    }
}
.main-match .col-game .team {
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
    display: inline-block;
    padding: 0 5px;
    border-radius: 2px;
    width: 172px;
    height: 26px;
    position: relative;
    top: 8px;
    line-height: 26px;
    text-align: center;
    font-weight: 600;
}
@media (max-width: 1024px) {
    .main-match .col-game .team {
        position: static;
        text-align: left;
        padding: 0;
    }
}
.main-match .col-game .team:first-child {
    margin: 0 30px 0 20px;
}
@media (max-width: 1024px) {
    .main-match .col-game .team:first-child {
        margin: 0;
    }
}
.main-match .col-game .team:last-child {
    margin: 0 20px 0 30px;
}
@media (max-width: 1024px) {
    .main-match .col-game .team:last-child {
        margin: 0;
    }
}
.main-match .col-game .team.win {
    color: #5aaddd;
}
.main-match .col-game .team.lose {
    color: #fc653c;
}
.main-match .col-game .team.draw {
    color: #666;
}
.main-match .col-game .vs {
    position: relative;
    padding: 0;
    display: inline-block;
    vertical-align: middle;
    width: 50px;
    height: 40px;
    line-height: 40px;
    border-left: 1px solid #aaa;
    border-right: 1px solid #aaa;
    text-align: center;
    font-size: 18px;
    background: #ddd;
    top: -1px;
}
@media (max-width: 1024px) {
    .main-match .col-game .vs {
        position: static;
        margin: 5px 0;
        height: 25px;
        line-height: 25px;
        border: 1px solid #aaa;
    }
}
.main-match .link-inline {
    font-size: 13px;
}
.main-match .badge {
    border-radius: 0;
    padding: 0;
    font-weight: 500;
    font-size: 14px;
    color: #333;
    background-color: transparent;
}
.main-match .badge-won {
    background-color: #289818;
    color: #fff;
}
.main-match .badge-pending {
    background-color: #ffcc00;
    color: #000;
}
.main-match .badge-draw {
    background-color: #999999;
    color: #fff;
}
.main-match .table-customize > tbody > tr > td {
    padding: 11px 14px;
}

Nhìn vào cấu trúc HTML có thể thấy mỗi hàng đều có đầy đủ giá trị nhưng ta sẽ chỉ hiển thị 1 giá trị chung cho từng cặp 2 thẻ tr ở các ô 1, 4 và 5 mà thôi. Sử dụng thuộc tính rowspan="2" của HTML dùng để nối hai ô với nhau, style cho thẻ td có class là phone-visible thuộc tính CSSdisplay: none; để ẩn 1 ô đi khi hiển thị table trên tablet và desktop.

Tiếp theo là responsive cho table này trên mobile, chúng ta chỉ cần đổi style cho thẻ td có class là phone-visible với thuộc tính CSS display: block; và phần còn lại thì thực hiện tương tự như phần responsive cho table ở phần 1, các bạn có thể tham khảo thêm ở đây.

.main-match h3 {
    background-color: #fc653c;
    color: #fff;
    border: none;
    padding: 10px 15px;
    font-size: 24px;
    margin: 0 0 7px;
}
.main-match .phone-visible {
    display: none;
}
@media (max-width: 767px) {
    .main-match .phone-visible {
        display: block;
    }
}
.main-match .col-comment {
    width: 185px;
}
.main-match .col-id {
    width: 50px;
}
.main-match .col-game {
    width: 510px;
}
@media (max-width: 1024px) {
    .main-match .col-game {
        width: 200px;
    }
}
.main-match .col-game .inner {
    margin: -15px;
}
@media (max-width: 1024px) {
    .main-match .col-game .inner {
        margin: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
    }
}
@media (max-width: 767px) {
    .main-match .col-game .inner {
        align-items: flex-start;
    }
}

Và đây là kết quả

2.PNG

#Kết luận

Như vậy là chúng ta đã thực hiện xong việc responsive table cho mobile ở dạng phức tạp hơn 1 chút. Về phương pháp thì nó cũng giống như việc responsive cho 1 table đơn giản ở phần trước nhưng có 1 vài sự thay đổi nhỏ cần lưu ý. Xin cảm ơn các bạn đã theo dõi và hẹn gặp lại!


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í