วิธีแสดงแถบเลื่อนบนตาราง html


86

ฉันกำลังเขียนหน้าที่ฉันต้องการตาราง html เพื่อรักษาขนาดที่ตั้งไว้ ฉันต้องการส่วนหัวที่ด้านบนสุดของตารางเพื่อให้อยู่ตรงนั้นตลอดเวลา แต่ฉันก็ต้องใช้ส่วนของตารางเพื่อเลื่อนไม่ว่าจะเพิ่มแถวลงในตารางกี่แถวก็ตาม

ฉันต้องการให้ดูเหมือนวิธีที่ 2 ใน url นี้: http://www.cssplay.co.uk/menu/tablescroll.html

ฉันได้ลองทำสิ่งนี้แล้ว แต่ไม่มีแถบเลื่อนปรากฏขึ้น:

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>


ทำไมคุณไม่ใช้รหัสจากวิธีการตัวอย่าง? คุณไม่สามารถใช้งานได้อย่าง<tbody>น่าเสียดาย
Mike Park

คำตอบ:


164

อะไรทำนองนี้?

http://jsfiddle.net/TweNm/

แนวคิดคือการรวมไว้<table>ในตำแหน่งที่ไม่คง<div>ที่ซึ่งมีoverflow:autoคุณสมบัติ CSS จากนั้นวางตำแหน่งองค์ประกอบใน<thead>อย่างแน่นอน

#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
แล้วไม่มีคอลัมน์คงความกว้างล่ะ?
Fractaliste

3
ฉันลองใช้คำตอบของคุณแล้ว แต่คอลัมน์ส่วนหัวไม่อยู่ในแนวเดียวกัน ฉันใช้เฉพาะ css ของคุณในแท็กสไตล์ภายในแท็กร่างกายที่ฉันคัดลอกตารางของคุณ
Antonio

ทางออกที่ดี แต่ฉันมีปัญหากับมัน เมื่อพยายามซ่อนแถวและตั้งค่าการแสดงผล: ไม่มีช่องว่างสีขาวระหว่างแถว นั่นไม่ใช่กรณีของตารางปกติ ความคิดเคล็ดลับหรือข้อเสนอแนะใด ๆ ?
Daniil Shevelev

@Antonio: ฉันมีปัญหาเดียวกัน (คอลัมน์ส่วนหัว * ที่อยู่ตรงกลางดูเหมือนจะไม่จัดแนว) แต่การเพิ่มtransform: translateX(-50%)ก็เป็นเคล็ดลับสำหรับฉัน [* ศูนย์กลางคือรูปแบบมาตรฐานใน Firefox ซึ่งถูกลบโดยตัวเลือก "normalize CSS" ใน JSFiddle ของคำตอบนี้]
โซระ

46

คุณต้องใส่ของคุณ<table>เป็น<div>ขนาดว่าจะได้รับการแก้ไขและในรูปแบบที่คุณต้องตั้ง<div>overflow: scroll


1
ให้ความสูงเป็น 500px สำหรับ div ของฉันและทำงานได้ดี <div style = "overflow: scroll; height: 500px;">
Ziggler

3
ไม่รู้ว่าทำไมทุกคนถึงทำมันซับซ้อนขนาดนี้ นี่ควรเป็นคำตอบที่ได้รับการยอมรับ
amallard

1
นี่เป็นวิธีแก้ปัญหาที่ง่ายที่สุด อาจมีข้อแม้ในการเพิ่ม div ที่มีส่วนเกินและความสูงคงที่ แต่อย่างน้อยวิธีนี้จะทำให้คุณไปในทิศทางที่ถูกต้อง
lsimonetti

1
เพื่อนตอบสุดยอด! ไชโย
:)

1
นี่ควรเป็นคำตอบที่ได้รับการยอมรับ เรียบง่ายตรงประเด็นและไม่ทำลายสิ่งอื่นใดด้วย
ฉันพยายามอย่างหนัก แต่ฉันร้องไห้หนักขึ้นเมื่อ

40

คำตอบที่ได้รับการยอมรับเป็นจุดเริ่มต้นที่ดี แต่ถ้าคุณปรับขนาดเฟรมเปลี่ยนความกว้างของคอลัมน์หรือแม้แต่เปลี่ยนข้อมูลตารางส่วนหัวจะยุ่งเหยิงในรูปแบบต่างๆ ทุกตัวอย่างอื่น ๆ ที่ฉันเคยเห็นมีปัญหาที่คล้ายกันหรือมีข้อ จำกัด ร้ายแรงบางอย่างในเค้าโครงของตาราง

ฉันคิดว่าในที่สุดฉันก็สามารถแก้ไขปัญหาเหล่านี้ได้แล้ว ต้องใช้CSS เป็นจำนวนมากแต่ผลิตภัณฑ์สุดท้ายมีความน่าเชื่อถือและใช้งานง่ายเหมือนตารางปกติ

นี่คือตัวอย่างที่มีคุณสมบัติที่จำเป็นทั้งหมดในการจำลองตารางที่อ้างอิงโดย OP: jsFiddle

สีและเส้นขอบจะต้องมีการเปลี่ยนแปลงเพื่อให้เหมือนกับข้อมูลอ้างอิง ข้อมูลเกี่ยวกับการเปลี่ยนแปลงประเภทนั้นมีอยู่ในความคิดเห็นของ CSS

นี่คือรหัส:

/*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]-->


งานที่ยอดเยี่ยม อย่างไรก็ตามฉันมีตารางที่มี 15 คอลัมน์และดูเหมือนว่าฉันจะไม่สามารถรวมตารางไว้ในหน้าได้หากไม่มีแถบเลื่อนแนวนอนในตอนนี้ ฉันได้ลองปรับแต่ง css ของคุณซึ่งเป็น css ที่เข้ารหัสอย่างสวยงามของคุณเพื่อรองรับคอลัมน์ที่มีความกว้างแบบไดนามิกมากขึ้น แต่ไม่มีอะไรที่ฉันเปลี่ยนแปลงนอกจากความกว้างของตารางที่สร้างความแตกต่าง ถ้าฉันเปลี่ยนความกว้างของตารางเป็น 100% ตารางจะแสดงผลตามความกว้างของตาราง แต่เนื่องจากความกว้างของคอลัมน์จะไม่รวมฉันจึงยังไม่เห็นข้อมูลทั้ง 15 คอลัมน์ ฉันเกือบจะมีตารางเลื่อนที่ดูเป็นระเบียบดังนั้นความช่วยเหลือใด ๆ จึงชื่นชม
nanker

รอสักครู่ไม่มีแถบเลื่อนแนวนอนตารางจะถูกตัดออก
nanker

@nanker หากคุณต้องการการเลื่อนในแนวนอนและยินดีที่จะใช้ JavaScript เพียงเล็กน้อยคุณควรตรวจสอบคำตอบนี้ เป็นวิธีที่ดีที่สุดในการทำตารางเลื่อนที่ฉันรู้ ไม่มีวิธีที่ดีในการเลื่อนในแนวนอนโดยใช้เพียง CSS ย้อนกลับเมื่อฉันโพสต์คำตอบนี้ แต่ฉันไม่ได้ตรวจสอบมาระยะหนึ่งแล้วดังนั้นฉันจึงไม่รู้ว่าจะเป็นไปได้อย่างไร
DoctorDestructo

งานดีมาก คุณช่วยแสดงความคิดเห็นเกี่ยวกับวิธีปรับแต่งแถวส่วนหัวหลายแถวได้ไหม เพียงแค่การ<tr><th></th>..</tr>สร้างซ้ำอย่างชัดเจนไม่ได้ผล ขอบคุณ.
David I. McIntosh

@ DavidI.McIntosh ส่วนหัวแบบหลายแถวจะยุ่งยากเมื่อใช้เทคนิคนี้ การเพิ่มแถวจะเป็นเรื่องง่าย แต่ฉันไม่แน่ใจว่าคุณจะได้เส้นขอบแนวนอนระหว่างแถวอย่างไร คุณอาจต้องการลองใช้โซลูชัน JavaScript ที่ฉันเชื่อมโยงไว้ในความคิดเห็นก่อนหน้านี้เว้นแต่คุณจะไม่สามารถใช้ JS ได้ด้วยเหตุผลบางประการ
DoctorDestructo

3

ฉันแก้ไขปัญหานี้โดยแยกเนื้อหาออกเป็นสองตาราง

ตารางหนึ่งคือแถวส่วนหัว

วินาทียังเป็น<table>แท็ก แต่ถูกรวมไว้<div>ด้วยความสูงคงที่และการเลื่อนล้น


1

ที่น่าสังเกตว่าขึ้นอยู่กับวัตถุประสงค์ของคุณ (ของฉันคือผลการป้อนอัตโนมัติของแถบค้นหา) คุณอาจต้องการให้ความสูงเปลี่ยนแปลงได้และสำหรับแถบเลื่อนจะมีอยู่ก็ต่อเมื่อความสูงเกินนั้น

หากคุณต้องการที่เปลี่ยนheight: x;กับmax-height: x;และกับoverflow:scrolloverflow:auto

นอกจากนี้คุณสามารถใช้overflow-xและoverflow-yถ้าคุณต้องการและเห็นได้ชัดว่าสิ่งเดียวกันทำงานในแนวนอนด้วยwidth : x;


0

หากคุณไปถึงจุดที่วิธีแก้ปัญหาที่กล่าวมาทั้งหมดไม่ได้ผล (ตามที่ได้รับสำหรับฉัน) ให้ทำสิ่งนี้:

  • สร้างสองตาราง หนึ่งสำหรับส่วนหัวและอีกอันสำหรับร่างกาย
  • กำหนดคอนเทนเนอร์ / div ระดับบนสุดที่แตกต่างกันทั้งสองตาราง
  • จัดรูปแบบ div ของตารางที่สองเพื่อให้สามารถเลื่อนเนื้อหาในแนวตั้งได้

เช่นนี้ในไฟล์ 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>

จากนั้นจัดรูปแบบพาเรนต์ของตารางที่สองเพื่ออนุญาตให้เลื่อนแนวตั้งในไฟล์ CSS

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

นี่เป็นการใช้งานแบบเดียวกับคำตอบของ Zvi เมื่อปีก่อน
TylerH

0

เพียงแค่เพิ่มบนโต๊ะ

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 = "overflow-x: auto;" `


คำถามคือวิธีทำให้เนื้อหาตารางเลื่อนในแนวตั้งในขณะที่ส่วนหัวคอลัมน์ยังคงอยู่
giraffedata

0

ง่ายมากเพียงแค่ห่อตารางด้วย div ที่มีoverflow-y:scroll;และoverflow-x:scrollคุณสมบัติแล้วทำให้ div มีความกว้างและความยาวเล็กกว่าตาราง มันจะทำงาน!!!


เอาล่ะฉันจะเพิ่มในคำตอบถัดไป
แขก

เอาล่ะฉันยังไม่รู้วิธีการเยื้องรหัสอย่างถูกต้อง แต่ในสแตกล้น
แขก

0

CSS: div{ overflow-y:scroll; overflow-x:scroll; width:20px; height:30px; } table{ width:50px; height:50px; }

คุณสามารถทำให้ตารางและ DIV รอบ ๆ โต๊ะเป็นขนาดใดก็ได้ที่คุณต้องการเพียงตรวจสอบให้แน่ใจว่า DIV มีขนาดเล็กกว่าตาราง คุณต้องมีตารางด้านใน DIV

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.