Responsive table với CSS - Phần 1
Bài đăng này đã không được cập nhật trong 3 năm
Table là 1 thành phần thường xuyên xuất hiện và không thể thiếu khi xây dựng các trang HTML/CSS để hiển thị nội dung dưới dạng bảng. Tuy nhiên, vấn đề xử lý để table hiển thị nội dung đầy đủ và rõ ràng cho các thiết bị mobile là 1 vấn đề khá nan giải, vì các thiết bị mobile có kích thước màn hình khá nhỏ.
Ví dụ, ta có 1 table với số column ít chỉ vài column thì vấn đề hiển thị nội dung của bảng trên mobile có vẻ như không có gì đáng lo. Nhưng nếu chúng ta xây dựng 1 table có số lượng column lớn, hàng chục thậm chí hàng trăm column thì khi hiển thị nội dung của table trên mobile thật là thảm họa.
#Vấn đề
Chúng ta sẽ lấy ví dụ là 1 table gồm 5 column, dưới đây là hình ảnh của table khi hiển thị nội dung bên trong trên các thiết bị có kích thước lớn...
...còn đây là khi hiển thị table trên mobile
Điều này sẽ không làm người dùng các thiết bị mobile hài lòng chút nào, nếu muốn xem hết nội dung trong table này thì bắt buộc họ phải vuốt màn hình qua 2 bên. Rõ ràng, tâm lý chung của người dùng là rất không thích việc phải trượt ngang trên điện thoại hay tablet.
#Xử lý
Ta có cấu trúc HTML
của bảng trên như sau:
<table class="table table-bordered table-customize table-responsive">
<thead>
<tr>
<th>Task</th>
<th>Category</th>
<th>Point</th>
<th>User</th>
<th>Time</th>
</tr>
</thead>
<tbody>
<tr>
<td data-title="Task"><a href="/task/138">The Very Beginning</a></td>
<td data-title="Category">Logic Game</td>
<td data-title="Point">10</td>
<td data-title="User"><a href="/user/profile/55"><img src="http://www.gravatar.com/avatar/c4f70b92d051f8323e18b24030f0d045?d=mm&s=24" alt="KhanhLD" title="KhanhLD"/></img> <span class="text-danger">KhanhLD</span></a></td>
<td data-title="Time">2016-06-18 10:22:45</td>
</tr>
<tr>
<td data-title="Task"><a href="/task/100">The Dead Clock</a></td>
<td data-title="Category">Logic Game</td>
<td data-title="Point">20</td>
<td data-title="User"><a href="/user/profile/2"><img src="http://www.gravatar.com/avatar/90b36c196a46f35da8c4fd1244cf15fd?d=mm&s=24" alt="bs90" title="bs90"/></img> <span class="text-danger">bs90</span></a></td>
<td data-title="Time">2016-06-18 11:12:44</td>
</tr>
<tr>
<td data-title="Task"><a href="/task/101">The Fotation</a></td>
<td data-title="Category">Logic Game</td>
<td data-title="Point">20</td>
<td data-title="User"><a href="/user/profile/2"><img src="http://www.gravatar.com/avatar/90b36c196a46f35da8c4fd1244cf15fd?d=mm&s=24" alt="bs90" title="bs90"/></img> <span class="text-danger">bs90</span></a></td>
<td data-title="Time">2016-06-18 11:13:11</td>
</tr>
<tr>
<td data-title="Task"><a href="/task/107">Hello world!</a></td>
<td data-title="Category">Logic Game</td>
<td data-title="Point">10</td>
<td data-title="User"><a href="/user/profile/2"><img src="http://www.gravatar.com/avatar/90b36c196a46f35da8c4fd1244cf15fd?d=mm&s=24" alt="bs90" title="bs90"/></img> <span class="text-danger">bs90</span></a></td>
<td data-title="Time">2016-06-18 18:10:32</td>
</tr>
<tr>
<td data-title="Task"><a href="/task/137">Picking CEO</a></td>
<td data-title="Category">Logic Game</td>
<td data-title="Point">5</td>
<td data-title="User"><a href="/user/profile/2"><img src="http://www.gravatar.com/avatar/90b36c196a46f35da8c4fd1244cf15fd?d=mm&s=24" alt="bs90" title="bs90"/></img> <span class="text-danger">bs90</span></a></td>
<td data-title="Time">2016-06-20 10:30:03</td>
</tr>
</tbody>
</table>
Dùng CSS
để style cho table:
/* Style for 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: #fff;
border-bottom: none;
padding: 10px 14px;
font-size: 14px;
font-weight: 400;
border: 1px solid rgba(0, 0, 0, 0.2);
}
.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: #ccc;
font-size: 14px;
color: #000;
border: 1px solid #ccc;
}
.table-customize > tbody > tr > td a {
text-decoration: none;
}
.table-order > tbody > tr:nth-child(-n + 3) > td:first-child {
position: relative;
font-size: 10px;
font-weight: 700;
}
.table-order > tbody > tr:nth-child(-n + 3) > td:first-child span {
position: absolute;
left: 0;
right: 0;
margin: auto;
top: 14px;
}
.table-order > tbody > tr:nth-child(1) > td:first-child {
background: url(../img/bg-order-1.png) no-repeat center center;
}
.table-order > tbody > tr:nth-child(2) > td:first-child {
background: url(../img/bg-order-2.png) no-repeat center center;
}
.table-order > tbody > tr:nth-child(3) > td:first-child {
background: url(../img/bg-order-3.png) no-repeat center center;
}
.table-order > tbody > tr td:first-child, .table-order > tbody > tr th:first-child {
text-align: center;
}
Tiếp theo sẽ là vấn đề quan trọng nhất, xử lý responsive cho table này để hiển thị nội dung tốt nhất có thể cho mobile, người dùng có thể xem và hiểu đầy đủ nội dung 1 cách dễ dàng chứ ko phải dùng đến thao tác trượt màn hình sang 2 bên hay phải zoom màn hình lại.
@media (min-width: 320px) and (max-width: 767px) {
.table-responsive,
.table-responsive thead,
.table-responsive tbody,
.table-responsive th,
.table-responsive td,
.table-responsive tr {
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%;
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;
}
.table-responsive > tbody > tr td:first-child {
text-align: left;
}
.table-responsive.table-order > tbody > tr:nth-child(-n + 3) > td:first-child {
padding: 25px 0 25px 30% !important;
background-position: left 32% center;
}
.table-responsive.table-order > tbody > tr:nth-child(-n + 3) > td:first-child span {
left: 32%;
}
}
Và đây là kết quả
Bây giờ, từng column của mỗi row sẽ là 1 khối độc lập theo hàng ngang và hiển thị đầy đủ, trực quan nội dung của table. Người dùng không còn phải trượt ngang trên mobile để có thể xem hết nội dung của bảng mà chỉ việc trượt dọc từ trên xuống.
Giải thích 1 chút về phần Responsive Table trong đoạn CSS trên:
- Đầu tiên ta sử dụng thẻ
@media
để xác định độ rộng của thiết bị mobile cần hiển thị responsive table. - Tiếp theo, set tất cả các thành phần bên trong table có thuộc tính
display: block;
. Thuộc tính này sẽ đưa giúp các thành phầnHTML
hiển thị như một khối, khi sử dụng giá trịblock
thành phần sẽ đứng một hàng độc lập so với thành phần trước và sau nó. - Ẩn tất cả các title hiện có của các column bằng thuộc tính
position: absolute
và hiển thị title cho từng column của mỗi row. - Để hiển thị title cho từng column của mỗi row, ta sẽ đẩy nội dung trong column đó sang trái với thuộc tính
padding
cho thẻtd
. Sử dụng phương thức:before
sau thẻtd
để hiển thị title, bằng cách truyền dữ liệu thông qua thuộc tínhcontent: attr(data-title);
,attr(data-title);
sẽ lấy nội dung bên trong thuộc tínhdata-title
của từng thành phầntd
ở fileHTML
mà chúng ta đã thêm vào tương ứng tên của từng column.
Như vậy chúng ta đã thực hiện xong việc responsive table cho mobile.
#Kết luận
Trên đây là 1 trong những phương pháp thực hiện responsive table cho mobile đơn giản nhất với sự kết hợp linh hoạt giữa HTML
và CSS
. Tuy nhiên, việc thực hiện responsive table cho mobile còn rất nhiều vấn đề với nhiều dạng table phức tạp khác nhau, chúng ta sẽ xử lý những vần đề này trong những bài tiếp theo. Cảm ơn và hẹn gặp lại!
#Tài liệu tham khảo
https://css-tricks.com/examples/ResponsiveTables/responsive.php
All rights reserved