Cách hiển thị thanh cuộn trên bảng html


85

Tôi đang viết một trang mà tôi cần một bảng html để duy trì kích thước đã đặt. Tôi cần các tiêu đề ở đầu bảng luôn ở đó nhưng tôi cũng cần phần nội dung của bảng để cuộn bất kể có bao nhiêu hàng được thêm vào bảng.

Tôi muốn nó trông giống như phương pháp 2 trong url này: http://www.cssplay.co.uk/menu/tablescroll.html

Tôi đã thử làm điều này nhưng không có thanh cuộn nào xuất hiện:

tbody {
  height: 80em;
  overflow: scroll;
}
<table border=1 id="qandatbl" align="center">
  <tr>
    <th class="col1">Question No</th>
    <th class="col2">Option Type</th>
    <th class="col1">Duration</th>
  </tr>

  <tbody>
    <tr>
      <td class='qid'></td>
      <td class="options"></td>
      <td class="duration"></td>
    </tr>
  </tbody>
</table>


Tại sao bạn không sử dụng mã từ phương thức ví dụ? <tbody>Thật không may, bạn không thể sử dụng .
Mike Park

Câu trả lời:


163

Một cái gì đó như thế này?

http://jsfiddle.net/TweNm/

Ý tưởng là bọc tệp <table>trong một vị trí không tĩnh <div>overflow:autothuộc tính CSS. Sau đó, định vị các phần tử trong <thead>hoàn toàn.

#table-wrapper {
  position:relative;
}
#table-scroll {
  height:150px;
  overflow:auto;  
  margin-top:20px;
}
#table-wrapper table {
  width:100%;

}
#table-wrapper table * {
  background:yellow;
  color:black;
}
#table-wrapper table thead th .text {
  position:absolute;   
  top:-20px;
  z-index:2;
  height:20px;
  width:35%;
  border:1px solid red;
}
<div id="table-wrapper">
  <div id="table-scroll">
    <table>
        <thead>
            <tr>
                <th><span class="text">A</span></th>
                <th><span class="text">B</span></th>
                <th><span class="text">C</span></th>
            </tr>
        </thead>
        <tbody>
          <tr> <td>1, 0</td> <td>2, 0</td> <td>3, 0</td> </tr>
          <tr> <td>1, 1</td> <td>2, 1</td> <td>3, 1</td> </tr>
          <tr> <td>1, 2</td> <td>2, 2</td> <td>3, 2</td> </tr>
          <tr> <td>1, 3</td> <td>2, 3</td> <td>3, 3</td> </tr>
          <tr> <td>1, 4</td> <td>2, 4</td> <td>3, 4</td> </tr>
          <tr> <td>1, 5</td> <td>2, 5</td> <td>3, 5</td> </tr>
          <tr> <td>1, 6</td> <td>2, 6</td> <td>3, 6</td> </tr>
          <tr> <td>1, 7</td> <td>2, 7</td> <td>3, 7</td> </tr>
          <tr> <td>1, 8</td> <td>2, 8</td> <td>3, 8</td> </tr>
          <tr> <td>1, 9</td> <td>2, 9</td> <td>3, 9</td> </tr>
          <tr> <td>1, 10</td> <td>2, 10</td> <td>3, 10</td> </tr>
          <!-- etc... -->
          <tr> <td>1, 99</td> <td>2, 99</td> <td>3, 99</td> </tr>
        </tbody>
    </table>
  </div>
</div>


15
Làm thế nào về không có cột cố định chiều rộng?
Fractaliste

3
Tôi đã thử câu trả lời của bạn nhưng các cột tiêu đề không được căn chỉnh. Tôi chỉ sử dụng css của bạn trong một thẻ kiểu bên trong thẻ nội dung nơi tôi đã sao chép bảng của bạn
Antonio

Giải pháp tuyệt vời, nhưng tôi đang gặp vấn đề với nó. Khi cố gắng ẩn một hàng và đặt hiển thị: không có khoảng trắng nào giữa các hàng. Đó không phải là trường hợp của bảng thông thường. Bất kỳ ý tưởng, mẹo hoặc đề xuất?
Daniil Sheboardsv

@Antonio: Tôi đã gặp vấn đề tương tự (các cột tiêu đề ở giữa * dường như không được căn chỉnh), nhưng việc thêm vào transform: translateX(-50%)đã giải quyết được vấn đề đối với tôi [* tập trung là kiểu chuẩn trong Firefox bị loại bỏ bởi tùy chọn “chuẩn hóa CSS” trong JSFiddle của câu trả lời này]
Sora.

44

Bạn phải chèn của bạn <table>vào một <div>cái mà nó có kích thước cố định và <div>theo phong cách bạn phải đặt overflow: scroll.


1
đã cho chiều cao là 500px cho div của tôi và nó hoạt động tốt. <div style = "Over: scroll; height: 500px;">
Ziggler

3
Không biết tại sao mọi người lại làm cho nó phức tạp như vậy. Đây phải là câu trả lời được chấp nhận.
amallard

1
Đây là giải pháp dễ dàng nhất. Có thể có những lưu ý khi thêm một div với độ tràn và chiều cao cố định nhưng giải pháp này ít nhất sẽ giúp bạn đi đúng hướng.
lsimonetti

1
Người bạn đời trả lời tuyệt vời! Chúc mừng bạn:) -
Sandepku

1
Đây phải là câu trả lời được chấp nhận. Đơn giản, đi thẳng vào vấn đề và tôi không phá hủy bất cứ điều gì khác với nó.
Tôi rất cố gắng nhưng tôi khóc nhiều hơn.

40

Câu trả lời được chấp nhận cung cấp một điểm khởi đầu tốt, nhưng nếu bạn thay đổi kích thước khung, thay đổi độ rộng cột hoặc thậm chí thay đổi dữ liệu bảng, các tiêu đề sẽ bị rối theo nhiều cách khác nhau. Mọi ví dụ khác mà tôi đã thấy đều có các vấn đề tương tự hoặc áp đặt một số hạn chế nghiêm trọng đối với bố cục của bảng.

Tôi nghĩ rằng cuối cùng tôi đã giải quyết được tất cả những vấn đề này. Phải tốn rất nhiều CSS, nhưng sản phẩm cuối cùng đáng tin cậy và dễ sử dụng như một bảng bình thường.

Đây là một ví dụ có tất cả các tính năng cần thiết để sao chép bảng được OP tham chiếu: jsFiddle

Màu sắc và đường viền sẽ phải được thay đổi để làm cho nó giống với tham chiếu. Thông tin về cách thực hiện các loại thay đổi đó được cung cấp trong phần nhận xét CSS.

Đây là mã:

/*the following html and body rule sets are required only if using a % width or height*/
/*html {
width: 100%;
height: 100%;
}*/
body {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0 20px 0 20px;
  text-align: center;
  background: white;
}
.scrollingtable {
  box-sizing: border-box;
  display: inline-block;
  vertical-align: middle;
  overflow: hidden;
  width: auto; /*if you want a fixed width, set it here, else set to auto*/
  min-width: 0/*100%*/; /*if you want a % width, set it here, else set to 0*/
  height: 188px/*100%*/; /*set table height here; can be fixed value or %*/
  min-height: 0/*104px*/; /*if using % height, make this large enough to fit scrollbar arrows + caption + thead*/
  font-family: Verdana, Tahoma, sans-serif;
  font-size: 15px;
  line-height: 20px;
  padding: 20px 0 20px 0; /*need enough padding to make room for caption*/
  text-align: left;
}
.scrollingtable * {box-sizing: border-box;}
.scrollingtable > div {
  position: relative;
  border-top: 1px solid black;
  height: 100%;
  padding-top: 20px; /*this determines column header height*/
}
.scrollingtable > div:before {
  top: 0;
  background: cornflowerblue; /*header row background color*/
}
.scrollingtable > div:before,
.scrollingtable > div > div:after {
  content: "";
  position: absolute;
  z-index: -1;
  width: 100%;
  height: 100%;
  left: 0;
}
.scrollingtable > div > div {
  min-height: 0/*43px*/; /*if using % height, make this large enough to fit scrollbar arrows*/
  max-height: 100%;
  overflow: scroll/*auto*/; /*set to auto if using fixed or % width; else scroll*/
  overflow-x: hidden;
  border: 1px solid black; /*border around table body*/
}
.scrollingtable > div > div:after {background: white;} /*match page background color*/
.scrollingtable > div > div > table {
  width: 100%;
  border-spacing: 0;
  margin-top: -20px; /*inverse of column header height*/
  /*margin-right: 17px;*/ /*uncomment if using % width*/
}
.scrollingtable > div > div > table > caption {
  position: absolute;
  top: -20px; /*inverse of caption height*/
  margin-top: -1px; /*inverse of border-width*/
  width: 100%;
  font-weight: bold;
  text-align: center;
}
.scrollingtable > div > div > table > * > tr > * {padding: 0;}
.scrollingtable > div > div > table > thead {
  vertical-align: bottom;
  white-space: nowrap;
  text-align: center;
}
.scrollingtable > div > div > table > thead > tr > * > div {
  display: inline-block;
  padding: 0 6px 0 6px; /*header cell padding*/
}
.scrollingtable > div > div > table > thead > tr > :first-child:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 20px; /*match column header height*/
  border-left: 1px solid black; /*leftmost header border*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div > div:first-child,
.scrollingtable > div > div > table > thead > tr > * + :before {
  position: absolute;
  top: 0;
  white-space: pre-wrap;
  color: white; /*header row font color*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div[label]:after {content: attr(label);}
.scrollingtable > div > div > table > thead > tr > * + :before {
  content: "";
  display: block;
  min-height: 20px; /*match column header height*/
  padding-top: 1px;
  border-left: 1px solid black; /*borders between header cells*/
}
.scrollingtable .scrollbarhead {float: right;}
.scrollingtable .scrollbarhead:before {
  position: absolute;
  width: 100px;
  top: -1px; /*inverse border-width*/
  background: white; /*match page background color*/
}
.scrollingtable > div > div > table > tbody > tr:after {
  content: "";
  display: table-cell;
  position: relative;
  padding: 0;
  border-top: 1px solid black;
  top: -1px; /*inverse of border width*/
}
.scrollingtable > div > div > table > tbody {vertical-align: top;}
.scrollingtable > div > div > table > tbody > tr {background: white;}
.scrollingtable > div > div > table > tbody > tr > * {
  border-bottom: 1px solid black;
  padding: 0 6px 0 6px;
  height: 20px; /*match column header height*/
}
.scrollingtable > div > div > table > tbody:last-of-type > tr:last-child > * {border-bottom: none;}
.scrollingtable > div > div > table > tbody > tr:nth-child(even) {background: gainsboro;} /*alternate row color*/
.scrollingtable > div > div > table > tbody > tr > * + * {border-left: 1px solid black;} /*borders between body cells*/
<div class="scrollingtable">
  <div>
    <div>
      <table>
        <caption>Top Caption</caption>
        <thead>
          <tr>
            <th><div label="Column 1"></div></th>
            <th><div label="Column 2"></div></th>
            <th><div label="Column 3"></div></th>
            <th>
              <!--more versatile way of doing column label; requires 2 identical copies of label-->
              <div><div>Column 4</div><div>Column 4</div></div>
            </th>
            <th class="scrollbarhead"/> <!--ALWAYS ADD THIS EXTRA CELL AT END OF HEADER ROW-->
          </tr>
        </thead>
        <tbody>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
        </tbody>
      </table>
    </div>
    Faux bottom caption
  </div>
</div>

<!--[if lte IE 9]><style>.scrollingtable > div > div > table {margin-right: 17px;}</style><![endif]-->


công việc tuyệt vời. Tuy nhiên, tôi có một bảng với 15 cột và dường như tôi không thể chứa bảng vào trang mà không có thanh cuộn ngang bây giờ. Tôi đã thử điều chỉnh css của bạn, css được mã hóa đẹp mắt của bạn, để chứa các cột có chiều rộng động hơn nhưng không có gì tôi thay đổi ngoài chiều rộng bảng tạo ra sự khác biệt. Nếu tôi thay đổi chiều rộng bảng thành 100%, thì bảng sẽ hiển thị theo chiều rộng của bảng, nhưng vì chiều rộng cột không bao trùm nên tôi vẫn không thể thấy tất cả 15 cột dữ liệu. Tôi gần như có một bảng cuộn trông rất đẹp, vì vậy mọi sự trợ giúp đều được đánh giá cao.
nanker

Ồ, chờ một chút, không có thanh cuộn ngang, bảng chỉ bị cắt.
nanker

@nanker Nếu bạn cần cuộn ngang và sẵn sàng sử dụng một chút JavaScript, bạn nên kiểm tra câu trả lời này . Đó là cách tốt nhất để thực hiện một bảng cuộn mà tôi biết. Không có cách nào tốt để thực hiện cuộn ngang chỉ với CSS trở lại khi tôi đăng câu trả lời này, nhưng tôi đã không xem xét nó một thời gian nên tôi không biết điều gì có thể xảy ra bây giờ.
DoctorDestructo

Công việc tuyệt vời. Bạn có thể nhận xét về cách điều chỉnh cho nhiều hàng tiêu đề? Đơn giản chỉ cần lặp lại <tr><th></th>..</tr>cấu trúc rõ ràng không hoạt động. Cảm ơn.
David I. McIntosh

@ DavidI.McIntosh Một tiêu đề nhiều hàng sẽ rất khó nếu sử dụng kỹ thuật này. Thêm các hàng sẽ dễ dàng, nhưng tôi không chắc bạn làm cách nào để có được các đường viền ngang giữa chúng. Bạn có thể muốn thử giải pháp JavaScript mà tôi đã liên kết trong nhận xét trước của mình trừ khi bạn không thể sử dụng JS vì một số lý do.
DoctorDestructo

3

Tôi đã giải quyết vấn đề này bằng cách tách nội dung của mình thành hai bảng.

Một bảng là hàng tiêu đề.

Giây cũng được <table>gắn thẻ, nhưng được bao bọc bởi <div>chiều cao tĩnh và cuộn tràn.


1

Cần lưu ý rằng tùy thuộc vào mục đích của bạn (của tôi là kết quả tự động điền của thanh tìm kiếm), bạn có thể muốn chiều cao có thể thay đổi được và thanh cuộn chỉ tồn tại nếu chiều cao vượt quá.

Nếu bạn muốn điều đó, hãy thay thế height: x;bằng max-height: x;, và overflow:scrollbằng overflow:auto.

Ngoài ra, bạn có thể sử dụng overflow-xoverflow-ynếu bạn muốn, và rõ ràng là cùng một thứ hoạt động theo chiều ngang vớiwidth : x;


0

Nếu bạn đến mức mà tất cả các giải pháp đã đề cập không hoạt động (như tôi đã làm), hãy làm như sau:

  • Tạo hai bảng. Một cho tiêu đề và một cho nội dung
  • Cung cấp cho hai bảng các vùng chứa / div chính khác nhau
  • Tạo kiểu cho div của bảng thứ hai để cho phép cuộn nội dung của nó theo chiều dọc.

Như thế này, trong HTML

<div class="table-header-class">
    <table>
       <thead>
          <tr>
            <th>Ava</th>
            <th>Alexis</th>
            <th>Mcclure</th>
          </tr>
       </thead>
    </table>
</div>
<div class="table-content-class">
   <table>
       <tbody>
          <tr>
            <td>I am the boss</td>
            <td>No, da-da is not the boss!</td>
            <td>Alexis, I am the boss, right?</td>
          </tr>
       </tbody>
    </table>
</div>

Sau đó, tạo kiểu cho cha của bảng thứ hai để cho phép cuộn dọc, trong CSS

    .table-content-class {
        overflow-y: scroll;    // use auto; or scroll; to allow vertical scrolling; 
        overflow-x: hidden;    // disable horizontal scroll 
    }

Đây là cách triển khai tương tự như câu trả lời của Zvi một năm trước.
TylerH

0

chỉ cần thêm trên bàn

style="overflow-x:auto;"

<table border=1 id="qandatbl" align="center" style="overflow-x:auto;">
    <tr>
    <th class="col1">Question No</th>
    <th class="col2">Option Type</th>
    <th class="col1">Duration</th>
    </tr>

   <tbody>
    <tr>
    <td class='qid'></td>
    <td class="options"></td>
    <td class="duration"></td>
    </tr>
    </tbody>
</table>

style = "tràn-x: auto;" `

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.