Bảng HTML với chiều rộng 100%, với cuộn dọc bên trong tbody


423

Làm cách nào tôi có thể đặt <table>chiều rộng 100% và chỉ đặt bên trong <tbody>cuộn dọc cho một số chiều cao?

cuộn dọc bên trong tbody

table {
    width: 100%;
    display:block;
}
thead {
    display: inline-block;
    width: 100%;
    height: 20px;
}
tbody {
    height: 200px;
    display: inline-block;
    width: 100%;
    overflow: auto;
}
  
<table>
  <thead>
    <tr>
    	<th>Head 1</th>
    	<th>Head 2</th>
    	<th>Head 3</th>
    	<th>Head 4</th>
    	<th>Head 5</th>
    </tr>
  </thead>
  <tbody>
    <tr>
    	<td>Content 1</td>
    	<td>Content 2</td>
    	<td>Content 3</td>
    	<td>Content 4</td>
    	<td>Content 5</td>
    </tr>
  </tbody>
</table>

Tôi muốn tránh thêm một số div bổ sung, tất cả những gì tôi muốn là bảng đơn giản như thế này và khi tôi cố gắng thay đổi hiển thị table-layout, positionvà nhiều thứ khác trong bảng CSS không hoạt động tốt với chiều rộng 100% chỉ với chiều rộng cố định trong px.


Tôi không thực sự chắc chắn những gì bạn muốn đạt được. nhìn vào đây: jsfiddle.net/CrSpu và cho biết bạn muốn nó cư xử như thế nào
x4rf41

2
tôi biết nhưng nhìn .. th và td không được hiển thị toàn bộ chiều rộng .. postimg.org/image/mgd630y61
Marko S


Câu trả lời:


674

Để làm cho <tbody>phần tử có thể cuộn được, chúng ta cần thay đổi cách hiển thị trên trang tức là sử dụng display: block;để hiển thị phần tử đó dưới dạng phần tử cấp khối.

Vì chúng ta thay đổi thuộc displaytính của tbody, chúng ta cũng nên thay đổi thuộc tính đó cho theadphần tử để tránh phá vỡ bố cục bảng.

Vì vậy chúng tôi có:

thead, tbody { display: block; }

tbody {
    height: 100px;       /* Just for the demo          */
    overflow-y: auto;    /* Trigger vertical scroll    */
    overflow-x: hidden;  /* Hide the horizontal scroll */
}

Các trình duyệt web hiển thị theadtbodycác thành phần dưới dạng nhóm hàng ( table-header-grouptable-row-group) theo mặc định.

Khi chúng ta thay đổi điều đó, các trphần tử bên trong sẽ không lấp đầy toàn bộ không gian trong thùng chứa của chúng.

Để khắc phục điều đó, chúng tôi phải tính toán độ rộng của tbodycác cột và áp dụng giá trị tương ứng cho các theadcột thông qua JavaScript.

Cột chiều rộng tự động

Đây là phiên bản jQuery của logic trên:

// Change the selector if needed
var $table = $('table'),
    $bodyCells = $table.find('tbody tr:first').children(),
    colWidth;

// Get the tbody columns width array
colWidth = $bodyCells.map(function() {
    return $(this).width();
}).get();

// Set the width of thead columns
$table.find('thead tr').children().each(function(i, v) {
    $(v).width(colWidth[i]);
});    

Và đây là đầu ra (trên Windows 7 Chrome 32) :

cuộn dọc bên trong tbody

DEMO LÀM VIỆC .

Bảng chiều rộng đầy đủ, cột chiều rộng tương đối

Khi Poster gốc cần thiết, chúng tôi có thể mở rộng tabletới 100% lượng widthcontainer của nó và sau đó sử dụng một phần tương đối ( Tỷ lệ phần trăm ) widthcho mỗi cột của bảng.

table {
    width: 100%; /* Optional */
}

tbody td, thead th {
    width: 20%;  /* Optional */
}

Vì bảng có bố trí (sắp xếp) chất lỏng , chúng ta nên điều chỉnh độ rộng của theadcột khi thùng chứa thay đổi kích thước.

Do đó, chúng ta nên đặt độ rộng của các cột sau khi cửa sổ được thay đổi kích thước:

// Adjust the width of thead cells when *window* resizes
$(window).resize(function() {
    /* Same as before */ 
}).resize(); // Trigger the resize handler once the script runs

Đầu ra sẽ là:

Bảng chất lỏng với cuộn dọc bên trong tbody

DEMO LÀM VIỆC .


Hỗ trợ trình duyệt và các lựa chọn thay thế

Tôi đã thử nghiệm hai phương pháp trên trên Windows 7 thông qua các phiên bản mới của Trình duyệt web chính (bao gồm IE10 +) và nó đã hoạt động.

Tuy nhiên, nó không hoạt động đúng trên IE9 trở xuống.

Đó là bởi vì trong cách bố trí bảng , tất cả các phần tử phải tuân theo các thuộc tính cấu trúc giống nhau.

Bằng cách sử dụng display: block;cho các phần tử <thead><tbody>, chúng tôi đã phá vỡ cấu trúc bảng.

Thiết kế lại bố cục thông qua JavaScript

Một cách tiếp cận là thiết kế lại bố cục (toàn bộ) bảng. Sử dụng JavaScript để tạo bố cục mới một cách nhanh chóng và xử lý và / hoặc điều chỉnh độ rộng / chiều cao của các ô một cách linh hoạt.

Ví dụ, hãy xem các ví dụ sau:

Bàn làm tổ

Cách tiếp cận này sử dụng hai bảng lồng nhau với div chứa. Cái đầu tiên tablechỉ có một ô có một divvà bảng thứ hai được đặt bên trong divphần tử đó .

Kiểm tra các bảng cuộn dọc tại CSS Play .

Điều này hoạt động trên hầu hết các trình duyệt web. Chúng tôi cũng có thể thực hiện logic trên một cách linh hoạt thông qua JavaScript.

Bảng có tiêu đề cố định khi cuộn

Vì mục đích của việc thêm thanh cuộn dọc bên <tbody>đang hiển thị bảng tiêu đề ở đầu mỗi hàng, chúng ta có thể xác định vị trí các theadyếu tố để nghỉ fixedở phía trên cùng của màn hình để thay thế.

Dưới đây là một bản demo làm việc của phương pháp này được thực hiện bởi Julien .
Nó có một hỗ trợ trình duyệt web đầy hứa hẹn.

đây là một triển khai CSS thuần túy của Willem Van Bockstal .


Giải pháp CSS thuần túy

Đây là câu trả lời cũ. Tất nhiên tôi đã thêm một phương thức mới và tinh chỉnh các khai báo CSS.

Bảng có chiều rộng cố định

Trong trường hợp này, tablecần phải có một cố định width (bao gồm tổng chiều rộng của cột và chiều rộng của thanh cuộn dọc) .

Mỗi cột nên có một cụ thể chiều rộngcột cuối cùng của theadnguyên tố cần có một lớn hơn chiều rộng bằng với những người khác chiều rộng + các chiều rộng của cuộn thanh dọc.

Do đó, CSS sẽ là:

table {
    width: 716px; /* 140px * 5 column + 16px scrollbar width */
    border-spacing: 0;
}

tbody, thead tr { display: block; }

tbody {
    height: 100px;
    overflow-y: auto;
    overflow-x: hidden;
}

tbody td, thead th {
    width: 140px;
}

thead th:last-child {
    width: 156px; /* 140px + 16px scrollbar width */
}

Đây là đầu ra:

Bảng có chiều rộng cố định

DEMO LÀM VIỆC .

Bảng có chiều rộng 100%

Trong phương pháp này, tablecó chiều rộng 100%và cho mỗi thtd, giá trị của widthtài sản nên nhỏ hơn 100% / number of cols.

Ngoài ra, chúng ta cần phải giảm chiều rộng của theadnhư giá trị của chiều rộng của cuộn thanh dọc.

Để làm điều đó, chúng ta cần sử dụng calc()chức năng CSS3 , như sau:

table {
    width: 100%;
    border-spacing: 0;
}

thead, tbody, tr, th, td { display: block; }

thead tr {
    /* fallback */
    width: 97%;
    /* minus scroll bar width */
    width: -webkit-calc(100% - 16px);
    width:    -moz-calc(100% - 16px);
    width:         calc(100% - 16px);
}

tr:after {  /* clearing float */
    content: ' ';
    display: block;
    visibility: hidden;
    clear: both;
}

tbody {
    height: 100px;
    overflow-y: auto;
    overflow-x: hidden;
}

tbody td, thead th {
    width: 19%;  /* 19% is less than (100% / 5 cols) = 20% */
    float: left;
}

Đây là bản Demo trực tuyến .

Lưu ý: Cách tiếp cận này sẽ thất bại nếu nội dung của mỗi cột phá vỡ dòng, tức là nội dung của mỗi ô phải đủ ngắn .


Sau đây, có hai ví dụ đơn giản về giải pháp CSS thuần mà tôi đã tạo tại thời điểm tôi trả lời câu hỏi này.

Đây là bản thử nghiệm jsFiddle v2 .

Phiên bản cũ: jsFiddle Demo v1


17
Với display: blockcác thuộc tính của bảng lỏng lẻo như chiều rộng của cột được chia sẻ giữa thead và tbody. Tôi biết bạn đã sửa lỗi này bằng cách cài đặt width: 19.2%nhưng trong trường hợp chúng tôi không biết trước chiều rộng của mỗi cột, điều này sẽ không hoạt động.
samb

10
Mã này dường như giả định các ô cơ thể sẽ luôn rộng hơn các ô tiêu đề.
Adam Donahue

2
Không hoạt động khi height: 100%(khi bạn muốn bảng mở rộng xuống cuối trang).
AlikElzin-kilaka

2
Điều này cũng hoạt động tuyệt vời với ng-repeatcác bảng AngularJS . Không chắc chắn tại sao có tất cả các thư viện có tiêu đề bảng cố định và những gì không phải khi có giải pháp này.
chakena

2
Bạn có thể cải thiện điều này nhiều hơn một chút với thuộc box-sizingtính để có đường viền có hai độ dày khác nhau không làm mất sự liên kết cột.
Ricca

89

Trong giải pháp sau đây, bảng chiếm 100% bộ chứa cha, không yêu cầu kích thước tuyệt đối. Đó là CSS thuần, bố cục flex được sử dụng.

Đây là cách nó trông: nhập mô tả hình ảnh ở đây

Nhược điểm có thể xảy ra:

  • thanh cuộn dọc luôn hiển thị, bất kể nó có yêu cầu hay không;
  • bố cục bảng được cố định - các cột không thay đổi kích thước theo chiều rộng nội dung (bạn vẫn có thể đặt bất kỳ chiều rộng cột nào bạn muốn một cách rõ ràng);
  • có một kích thước tuyệt đối - chiều rộng của thanh cuộn, khoảng 0,9em cho các trình duyệt tôi có thể kiểm tra.

HTML (rút ngắn):

<div class="table-container">
    <table>
        <thead>
            <tr>
                <th>head1</th>
                <th>head2</th>
                <th>head3</th>
                <th>head4</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>content1</td>
                <td>content2</td>
                <td>content3</td>
                <td>content4</td>
            </tr>
            <tr>
                <td>content1</td>
                <td>content2</td>
                <td>content3</td>
                <td>content4</td>
            </tr>
            ...
        </tbody>
    </table>
</div>

CSS, với một số trang trí được bỏ qua cho rõ ràng:

.table-container {
    height: 10em;
}
table {
    display: flex;
    flex-flow: column;
    height: 100%;
    width: 100%;
}
table thead {
    /* head takes the height it requires, 
    and it's not scaled when table is resized */
    flex: 0 0 auto;
    width: calc(100% - 0.9em);
}
table tbody {
    /* body takes all the remaining available space */
    flex: 1 1 auto;
    display: block;
    overflow-y: scroll;
}
table tbody tr {
    width: 100%;
}
table thead, table tbody tr {
    display: table;
    table-layout: fixed;
}

mã đầy đủ trên jsfiddle

Cùng mã trong LESS để bạn có thể trộn nó vào:

.table-scrollable() {
  @scrollbar-width: 0.9em;
  display: flex;
  flex-flow: column;

  thead,
  tbody tr {
    display: table;
    table-layout: fixed;
  }

  thead {
    flex: 0 0 auto;
    width: ~"calc(100% - @{scrollbar-width})";
  }

  tbody {
    display: block;
    flex: 1 1 auto;
    overflow-y: scroll;

    tr {
      width: 100%;
    }
  }
}

2
Cảm ơn giải pháp! Có một lỗi nhỏ .... bạn đã đặt độ rộng cho thead hai lần và tôi thấy rằng trừ đi 1,05em từ các đường rộng lên tốt hơn một chút: jsfiddle.net/xuvsncr2/170
TigerBear

1
Số nội dung của nhân vật thì sao? nó rối tung lên khi thêm nhiều ký tự hoặc từ bên trong các ô hàng
Limon

Tôi nghĩ rằng thiết lập một số chính sách gói phù hợp tdsẽ giúp
tsayen

Bất kỳ giải pháp như thế này nhưng bỏ nhu cầu về chiều rộng 100%?
Alexandre Pereira Nunes

2
@tsayen Làm thế nào để bạn ngăn chặn nó không hoạt động và chồng chéo khi bạn thay đổi kích thước cửa sổ?
Clearshot66

31

Trong các trình duyệt hiện đại, bạn chỉ cần sử dụng css:

th {
  position: sticky;
  top: 0;
  z-index: 2;
}

8
Câu thần chú này không đầy đủ ... Muốn đăng một ví dụ, hoặc ít nhất là công phu?
Liam

làm việc tốt, nhưng chỉ áp dụng cho th. Nếu chúng ta đặt vị trí dính trên thead thì nó không hoạt động.
Vishal

Đã sửa lỗi nên thêm vào W3C!
sonichy

2
Câu trả lời này hoạt động khi bạn quấn của bạn <table>với <div>trong đó có overflow-y: auto;một số max-height. Ví dụ:<div style="overflow-y: auto; max-height: 400px;"><table>...</table></div>
Công việc tối thiểu

Kể từ năm 2020, đây sẽ là câu trả lời được lựa chọn (cùng với bản cập nhật của @Minwork)
Vidal

18

Tôi đang sử dụng display:blockcho theadtbody. Do đó chiều rộng của các theadcột khác với chiều rộng của các tbodycột.

table {
    margin:0 auto; 
    border-collapse:collapse;
}
thead {
    background:#CCCCCC;
    display:block
}
tbody {
    height:10em;overflow-y:scroll;
    display:block
}

Để khắc phục điều này tôi sử dụng jQuerymã nhỏ nhưng nó chỉ có thể được thực hiện JavaScript.

var colNumber=3 //number of table columns    

for (var i=0; i<colNumber; i++) {
  var thWidth=$("#myTable").find("th:eq("+i+")").width();
  var tdWidth=$("#myTable").find("td:eq("+i+")").width();      
  if (thWidth<tdWidth)                    
      $("#myTable").find("th:eq("+i+")").width(tdWidth);
  else
      $("#myTable").find("td:eq("+i+")").width(thWidth);           
}  

Đây là bản demo làm việc của tôi: http://jsfiddle.net/gavroche/N7LEF/

Không hoạt động trong IE 8


Đây là giải pháp tốt nhất / đơn giản nhất mà tôi đã tìm thấy cho phép độ rộng cột không cố định (ví dụ: điều khiển .NET DataGrid). Đối với "sản xuất", colNumberbiến có thể được thay thế bằng mã lặp đi lặp lại qua các ô thực tế được tìm thấy và lưu ý rằng nó không đối phó chính xác nếu có bất kỳ colspans nào (cũng có thể được cải thiện trong mã, nếu cần, nhưng không chắc là loại bảng có khả năng muốn tính năng cuộn này).
JonBrave

Điều này hoạt động (theo kiểu), nhưng không đối phó khi kích thước cửa sổ nhỏ hơn bảng (vì nó bỏ qua chiều rộng của thanh cuộn).
Mã hóa

Vâng, tiêu đề và các ô không còn khớp nữa nếu chiều rộng bảng của bạn bị giới hạn theo chiều rộng đã đặt
Craig

câu trả lời hay nhất ở đây, đơn giản nhất
Charles Okwuagwu

17

Chỉ CSS

cho Chrome, Firefox, Edge (và các trình duyệt thường xanh khác)

Đơn giản là position: sticky; top: 0;các thyếu tố của bạn :

/* Fix table head */
.tableFixHead    { overflow-y: auto; height: 100px; }
.tableFixHead th { position: sticky; top: 0; }

/* Just common table stuff. */
table  { border-collapse: collapse; width: 100%; }
th, td { padding: 8px 16px; }
th     { background:#eee; }
<div class="tableFixHead">
  <table>
    <thead>
      <tr><th>TH 1</th><th>TH 2</th></tr>
    </thead>
    <tbody>
      <tr><td>A1</td><td>A2</td></tr>
      <tr><td>B1</td><td>B2</td></tr>
      <tr><td>C1</td><td>C2</td></tr>
      <tr><td>D1</td><td>D2</td></tr>
      <tr><td>E1</td><td>E2</td></tr>
    </tbody>
  </table>
</div>

PS: nếu bạn cần viền cho các phần tử TH th {box-shadow: 1px 1px 0 #000; border-top: 0;}sẽ có ích (vì các viền mặc định không được vẽ chính xác khi cuộn).

Đối với một biến thể ở trên chỉ sử dụng một chút JS để phù hợp với IE11, hãy xem câu trả lời này https://stackoverflow.com/a/47923622/383904


Nếu bạn có đường viền cho các phần tử thứ, sử dụng "đường viền sụp đổ: thu gọn" sẽ dán đường viền vào thân thay vì tiêu đề. Để tránh vấn đề này, bạn nên sử dụng "thu gọn biên giới: tách biệt". Xem stackoverflow.com/a/53559394
mrod

@mrod khi sử dụng separatebạn đang thêm dầu vào lửa. jsfiddle.net/RokoCB/o0zL4xyw và xem giải pháp TẠI ĐÂY: thêm viền vào cố định TH - Tôi hoan nghênh các đề xuất của OFC nếu tôi bỏ lỡ điều gì đó.
Roko C. Buljan

11

Tạo hai bảng lần lượt, đặt bảng thứ hai vào một div có chiều cao cố định và đặt thuộc tính tràn thành tự động. Ngoài ra, giữ tất cả các td bên trong thead trong bảng thứ hai trống.

<div>
    <table>
        <thead>
            <tr>
                <th>Head 1</th>
                <th>Head 2</th>
                <th>Head 3</th>
                <th>Head 4</th>
                <th>Head 5</th>
            </tr>
        </thead>
    </table>
</div>

<div style="max-height:500px;overflow:auto;">
    <table>
        <thead>
            <tr>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
            </tr>
        </thead>
        <tbody>
        <tr>
            <td>Content 1</td>
            <td>Content 2</td>
            <td>Content 3</td>
            <td>Content 4</td>
            <td>Content 5</td>
        </tr>
        </tbody>
    </table>    
</div>

8
Trong trường hợp này, các cột của bảng thứ hai không thể theo chiều rộng của bảng đầu tiên.
kat1330

2
Không tốt! Bạn mất đồng bộ hóa chiều rộng cho các cột trên hai bảng.
Zafar

1
để hoàn thành giải pháp này, chúng tôi cần thêm tập lệnh @Hashem Qolami ( mô tả ở trên ) để đồng bộ hóa chiều rộng cột tiêu đề
Elhay Avichzer

6

Cuối cùng tôi đã hiểu đúng với CSS thuần bằng cách làm theo các hướng dẫn sau:

http://tjaugeoll.com/2012/11/10/creating-cross-browser-scrollable-tbody/

Bước đầu tiên là đặt <tbody>khối hiển thị: để có thể áp dụng tràn và chiều cao. Từ đó, các hàng trong <thead>nhu cầu được đặt thành vị trí: tương đối và hiển thị: chặn để chúng sẽ nằm ở trên cùng của cuộn có thể cuộn <tbody>.

tbody, thead { display: block; overflow-y: auto; }

Bởi vì <thead>vị trí tương đối, mỗi ô của bảng cần có chiều rộng rõ ràng

td:nth-child(1), th:nth-child(1) { width: 100px; }
td:nth-child(2), th:nth-child(2) { width: 100px; }
td:nth-child(3), th:nth-child(3) { width: 100px; }

Nhưng thật không may, điều đó là không đủ. Do đó, khi có một thanh cuộn, các trình duyệt sẽ phân bổ không gian cho nó, do đó, <tbody>kết thúc có ít không gian có sẵn hơn <thead>. Lưu ý sự sai lệch nhỏ này tạo ra ...

Cách giải quyết duy nhất tôi có thể đưa ra là đặt độ rộng tối thiểu trên tất cả các cột trừ cột cuối cùng.

td:nth-child(1), th:nth-child(1) { min-width: 100px; }
td:nth-child(2), th:nth-child(2) { min-width: 100px; }
td:nth-child(3), th:nth-child(3) { width: 100px; }

Toàn bộ ví dụ codepen dưới đây:

CSS:

.fixed_headers {
  width: 750px;
  table-layout: fixed;
  border-collapse: collapse;
}
.fixed_headers th {
  text-decoration: underline;
}
.fixed_headers th,
.fixed_headers td {
  padding: 5px;
  text-align: left;
}
.fixed_headers td:nth-child(1),
.fixed_headers th:nth-child(1) {
  min-width: 200px;
}
.fixed_headers td:nth-child(2),
.fixed_headers th:nth-child(2) {
  min-width: 200px;
}
.fixed_headers td:nth-child(3),
.fixed_headers th:nth-child(3) {
  width: 350px;
}
.fixed_headers thead {
  background-color: #333333;
  color: #fdfdfd;
}
.fixed_headers thead tr {
  display: block;
  position: relative;
}
.fixed_headers tbody {
  display: block;
  overflow: auto;
  width: 100%;
  height: 300px;
}
.fixed_headers tbody tr:nth-child(even) {
  background-color: #dddddd;
}
.old_ie_wrapper {
  height: 300px;
  width: 750px;
  overflow-x: hidden;
  overflow-y: auto;
}
.old_ie_wrapper tbody {
  height: auto;
}

Html:

<!-- IE < 10 does not like giving a tbody a height.  The workaround here applies the scrolling to a wrapped <div>. -->
<!--[if lte IE 9]>
<div class="old_ie_wrapper">
<!--<![endif]-->

<table class="fixed_headers">
  <thead>
    <tr>
      <th>Name</th>
      <th>Color</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Apple</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Pear</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Grape</td>
      <td>Purple / Green</td>
      <td>These are purple and green.</td>
    </tr>
    <tr>
      <td>Orange</td>
      <td>Orange</td>
      <td>These are orange.</td>
    </tr>
    <tr>
      <td>Banana</td>
      <td>Yellow</td>
      <td>These are yellow.</td>
    </tr>
    <tr>
      <td>Kiwi</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Plum</td>
      <td>Purple</td>
      <td>These are Purple</td>
    </tr>
    <tr>
      <td>Watermelon</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Tomato</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Cherry</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Cantelope</td>
      <td>Orange</td>
      <td>These are orange inside.</td>
    </tr>
    <tr>
      <td>Honeydew</td>
      <td>Green</td>
      <td>These are green inside.</td>
    </tr>
    <tr>
      <td>Papaya</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Raspberry</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Blueberry</td>
      <td>Blue</td>
      <td>These are blue.</td>
    </tr>
    <tr>
      <td>Mango</td>
      <td>Orange</td>
      <td>These are orange.</td>
    </tr>
    <tr>
      <td>Passion Fruit</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
  </tbody>
</table>

<!--[if lte IE 9]>
</div>
<!--<![endif]-->

EDIT: Giải pháp thay thế cho chiều rộng bảng 100% (trên thực tế là dành cho chiều rộng cố định và không trả lời câu hỏi):

HTML:

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Color</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Apple</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Pear</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Grape</td>
      <td>Purple / Green</td>
      <td>These are purple and green.</td>
    </tr>
    <tr>
      <td>Orange</td>
      <td>Orange</td>
      <td>These are orange.</td>
    </tr>
    <tr>
      <td>Banana</td>
      <td>Yellow</td>
      <td>These are yellow.</td>
    </tr>
    <tr>
      <td>Kiwi</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
  </tbody>
</table>

CSS:

table {
  width: 100%;
  text-align: left;
  min-width: 610px;
}
tr {
  height: 30px;
  padding-top: 10px
}
tbody { 
  height: 150px; 
  overflow-y: auto;
  overflow-x: hidden;
}
th,td,tr,thead,tbody { display: block; }
td,th { float: left; }
td:nth-child(1),
th:nth-child(1) {
  width: 20%;
}
td:nth-child(2),
th:nth-child(2) {
  width: 20%;
  float: left;
}
td:nth-child(3),
th:nth-child(3) {
  width: 59%;
  float: left;
}
/* some colors */
thead {
  background-color: #333333;
  color: #fdfdfd;
}
table tbody tr:nth-child(even) {
  background-color: #dddddd;
}

Bản trình diễn: http://codepen.io/anon/pen/bNJeLO


1
Câu hỏi đặc biệt muốn có một bảng chiều rộng 100%, đó là điều mà ví dụ bạn tham chiếu không làm.
Mã hóa

@TrueBlueAussie Bắt tốt: D Đã thêm giải pháp thay thế cho chiều rộng 100%.
Mikael Lepistö

bạn không xem xét kinh độ của hàng ô
Limon

2

Cách giải quyết Css để buộc các cột hiển thị chính xác với một 'khối'

Giải pháp này vẫn yêu cầu thđộ rộng được tính toán và thiết lập bởi jQuery

table.scroll tbody,
table.scroll thead { display: block; }

table.scroll tbody {
    overflow-y: auto;
    overflow-x: hidden;
    max-height: 300px;
}

table.scroll tr {
    display: flex;
}

table.scroll tr > td {
    flex-grow: 1;
    flex-basis: 0;
}

Và Jquery / Javascript

var $table = $('#the_table_element'),
    $bodyCells = $table.find('tbody tr:first').children(),
    colWidth;

$table.addClass('scroll');

// Adjust the width of thead cells when window resizes
$(window).resize(function () {

    // Get the tbody columns width array
    colWidth = $bodyCells.map(function () {
        return $(this).width();
    }).get();

    // Set the width of thead columns
    $table.find('thead tr').children().each(function (i, v) {
        $(v).width(colWidth[i]);
    });

}).resize(); // Trigger resize handler

@Craig vào năm 2019, hoàn toàn ổn khi không quan tâm đến IE.
Automagisch

2

thử cách tiếp cận dưới đây, rất đơn giản dễ thực hiện

Dưới đây là liên kết jsfiddle

http://jsfiddle.net/v2t2k8ke/2/

HTML:

<table border='1' id='tbl_cnt'>
<thead><tr></tr></thead><tbody></tbody>

CSS:

 #tbl_cnt{
 border-collapse: collapse; width: 100%;word-break:break-all;
 }
 #tbl_cnt thead, #tbl_cnt tbody{
 display: block;
 }
 #tbl_cnt thead tr{
 background-color: #8C8787; text-align: center;width:100%;display:block;
 }
 #tbl_cnt tbody {
 height: 100px;overflow-y: auto;overflow-x: hidden;
 }

Câu hỏi:

 var data = [
    {
    "status":"moving","vehno":"tr544","loc":"bng","dri":"ttt"
    }, {
    "status":"stop","vehno":"tr54","loc":"che", "dri":"ttt"
    },{    "status":"idle","vehno":"yy5499999999999994","loc":"bng","dri":"ttt"
    },{
    "status":"moving","vehno":"tr544","loc":"bng", "dri":"ttt"
    }, {
    "status":"stop","vehno":"tr54","loc":"che","dri":"ttt"
    },{
    "status":"idle","vehno":"yy544","loc":"bng","dri":"ttt"
    }
    ];
   var sth = '';
   $.each(data[0], function (key, value) {
     sth += '<td>' + key + '</td>';
   });
   var stb = '';        
   $.each(data, function (key, value) {
       stb += '<tr>';
       $.each(value, function (key, value) {
       stb += '<td>' + value + '</td>';
       });
       stb += '</tr>';
    });
      $('#tbl_cnt thead tr').append(sth);
      $('#tbl_cnt tbody').append(stb);
      setTimeout(function () {
      var col_cnt=0 
      $.each(data[0], function (key, value) {col_cnt++;});    
      $('#tbl_cnt thead tr').css('width', ($("#tbl_cnt tbody") [0].scrollWidth)+ 'px');
      $('#tbl_cnt thead tr td,#tbl_cnt tbody tr td').css('width',  ($('#tbl_cnt thead tr ').width()/Number(col_cnt)) + 'px');}, 100)

2
Giải pháp này không đối phó với cửa sổ hẹp hơn chiều rộng của bảng. Nó sẽ cho phép cuộn ngang khi điều đó xảy ra. Ngoài ra, các tiêu đề không được căn chỉnh chính xác với các ô dữ liệu (Chrome).
Mã hóa

Nó không hoạt động ngày nay
MrHIDEn

2

Thêm chiều rộng cố định vào td, sau khi làm cho khối hiển thị tbody & thead hoạt động hoàn hảo và chúng ta cũng có thể sử dụng plugin slimscroll để làm cho thanh cuộn đẹp.

nhập mô tả hình ảnh ở đây

<!DOCTYPE html>
<html>

<head>
    <title> Scrollable table </title>
    <style>
        body {
            font-family: sans-serif;
            font-size: 0.9em;
        }
        table {
            border-collapse: collapse;
            border-bottom: 1px solid #ddd;
        }
        thead {
            background-color: #333;
            color: #fff;
        }
        thead,tbody {
            display: block;
        }
        th,td {
            padding: 8px 10px;
            border: 1px solid #ddd;
            width: 117px;
            box-sizing: border-box;
        }
        tbody {
            height: 160px;
            overflow-y: scroll
        }
    </style>
</head>

<body>

    <table class="example-table">
        <thead>
            <tr>
                <th> Header 1 </th>
                <th> Header 2 </th>
                <th> Header 3 </th>
                <th> Header 4 </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td> Row 1- Col 1 </td>
                <td> Row 1- Col 2 </td>
                <td> Row 1- Col 3 </td>
                <td> Row 1- Col 4 </td>
            </tr>
            <tr>
                <td> Row 2- Col 1 </td>
                <td> Row 2- Col 2 </td>
                <td> Row 2- Col 3 </td>
                <td> Row 2- Col 4 </td>
            </tr>
            <tr>
                <td> Row 3- Col 1 </td>
                <td> Row 3- Col 2 </td>
                <td> Row 3- Col 3 </td>
                <td> Row 3- Col 4 </td>
            </tr>
            <tr>
                <td> Row 4- Col 1 </td>
                <td> Row 4- Col 2 </td>
                <td> Row 4- Col 3 </td>
                <td> Row 4- Col 4 </td>
            </tr>
            <tr>
                <td> Row 5- Col 1 </td>
                <td> Row 5- Col 2 </td>
                <td> Row 5- Col 3 </td>
                <td> Row 5- Col 4 </td>
            </tr>
            <tr>
                <td> Row 6- Col 1 </td>
                <td> Row 6- Col 2 </td>
                <td> Row 6- Col 3 </td>
                <td> Row 6- Col 4 </td>
            </tr>
            <tr>
                <td> Row 7- Col 1 </td>
                <td> Row 7- Col 2 </td>
                <td> Row 7- Col 3 </td>
                <td> Row 7- Col 4 </td>
            </tr>
            <tr>
                <td> Row 8- Col 1 </td>
                <td> Row 8- Col 2 </td>
                <td> Row 8- Col 3 </td>
                <td> Row 8- Col 4 </td>
            </tr>
            <tr>
                <td> Row 9- Col 1 </td>
                <td> Row 9- Col 2 </td>
                <td> Row 9- Col 3 </td>
                <td> Row 9- Col 4 </td>
            </tr>
            <tr>
                <td> Row 10- Col 1 </td>
                <td> Row 10- Col 2 </td>
                <td> Row 10- Col 3 </td>
                <td> Row 10- Col 4 </td>
            </tr>
            <tr>
                <td> Row 11- Col 1 </td>
                <td> Row 11- Col 2 </td>
                <td> Row 11- Col 3 </td>
                <td> Row 11- Col 4 </td>
            </tr>
            <tr>
                <td> Row 12- Col 1 </td>
                <td> Row 12- Col 2 </td>
                <td> Row 12- Col 3 </td>
                <td> Row 12- Col 4 </td>
            </tr>
            <tr>
                <td> Row 13- Col 1 </td>
                <td> Row 13- Col 2 </td>
                <td> Row 13- Col 3 </td>
                <td> Row 13- Col 4 </td>
            </tr>
            <tr>
                <td> Row 14- Col 1 </td>
                <td> Row 14- Col 2 </td>
                <td> Row 14- Col 3 </td>
                <td> Row 14- Col 4 </td>
            </tr>
            <tr>
                <td> Row 15- Col 1 </td>
                <td> Row 15- Col 2 </td>
                <td> Row 15- Col 3 </td>
                <td> Row 15- Col 4 </td>
            </tr>
            <tr>
                <td> Row 16- Col 1 </td>
                <td> Row 16- Col 2 </td>
                <td> Row 16- Col 3 </td>
                <td> Row 16- Col 4 </td>
            </tr>
        </tbody>
    </table>


    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery-slimScroll/1.3.8/jquery.slimscroll.min.js"></script>
    <script>
        $('.example-table tbody').slimscroll({
            height: '160px',
            alwaysVisible: true,
            color: '#333'
        })
    </script>
</body>

</html>


1

Đây là mã làm việc cho tôi để tạo ra một miếng dán dính trên bàn với một tbody có thể cuộn được:

table ,tr td{
    border:1px solid red
}
tbody {
    display:block;
    height:50px;
    overflow:auto;
}
thead, tbody tr {
    display:table;
    width:100%;
    table-layout:fixed;/* even columns width , fix width of table too*/
}
thead {
    width: calc( 100% - 1em )/* scrollbar is average 1em/16px width, remove it from thead width */
}
table {
    width:400px;
}

1

Để sử dụng "overflow: scroll", bạn phải đặt "display: block" trên thead và tbody. Và điều đó làm rối tung độ rộng cột giữa chúng. Nhưng sau đó, bạn có thể sao chép hàng thead bằng Javascript và dán nó vào tbody dưới dạng một hàng ẩn để giữ độ rộng col chính xác.

$('.myTable thead > tr').clone().appendTo('.myTable tbody').addClass('hidden-to-set-col-widths');

http://jsfiddle.net/Julesezaar/mup0c5hk/

<table class="myTable">
    <thead>
        <tr>
            <td>Problem</td>
            <td>Solution</td>
            <td>blah</td>
            <td>derp</td>
        </tr>
    </thead>
    <tbody></tbody>
</table>
<p>
  Some text to here
</p>

Các css:

table {
  background-color: #aaa;
  width: 100%;
}

thead,
tbody {
  display: block; // Necessary to use overflow: scroll
}

tbody {
  background-color: #ddd;
  height: 150px;
  overflow-y: scroll;
}

tbody tr.hidden-to-set-col-widths,
tbody tr.hidden-to-set-col-widths td {
  visibility: hidden;
  height: 0;
  line-height: 0;
  padding-top: 0;
  padding-bottom: 0;
}

td {
  padding: 3px 10px;
}

0

Thử cái này jsfiddle . Đây là sử dụng jQuery và được tạo từ câu trả lời của Hashem Qolami. Đầu tiên, tạo một bảng thông thường sau đó làm cho nó có thể cuộn được.

const makeScrollableTable = function (tableSelector, tbodyHeight) {
  let $table = $(tableSelector);
  let $bodyCells = $table.find('tbody tr:first').children();
  let $headCells = $table.find('thead tr:first').children();
  let headColWidth = 0;
  let bodyColWidth = 0;

  headColWidth = $headCells.map(function () {
    return $(this).outerWidth();
  }).get();
  bodyColWidth = $bodyCells.map(function () {
    return $(this).outerWidth();
  }).get();

  $table.find('thead tr').children().each(function (i, v) {
    $(v).css("width", headColWidth[i]+"px");
    $(v).css("min-width", headColWidth[i]+"px");
    $(v).css("max-width", headColWidth[i]+"px");
  });
  $table.find('tbody tr').children().each(function (i, v) {
    $(v).css("width", bodyColWidth[i]+"px");
    $(v).css("min-width", bodyColWidth[i]+"px");
    $(v).css("max-width", bodyColWidth[i]+"px");
  });

  $table.find('thead').css("display", "block");
  $table.find('tbody').css("display", "block");

  $table.find('tbody').css("height", tbodyHeight+"px");
  $table.find('tbody').css("overflow-y", "auto");
  $table.find('tbody').css("overflow-x", "hidden");

};
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.