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!