ตาราง HTML ที่มีความกว้าง 100% พร้อมการเลื่อนในแนวตั้งภายในร่างกาย


423

ฉันจะตั้งค่า<table>ความกว้าง 100% และวางไว้ในการ<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>

ฉันต้องการที่จะหลีกเลี่ยงการเพิ่มบาง div เพิ่มเติมทั้งหมดที่ฉันต้องการเป็นตารางที่เรียบง่ายเช่นนี้และเมื่อฉันพยายามที่จะแสดงผลการเปลี่ยนแปลงtable-layout, positionและกิจกรรมอื่น ๆ อีกมากมายในตาราง CSS ไม่ได้ทำงานที่ดีมีความกว้าง 100% เท่านั้นที่มีความกว้างคงที่ใน px


ฉันไม่แน่ใจว่าสิ่งที่คุณต้องการบรรลุ ดูที่นี่: jsfiddle.net/CrSpuและบอกว่าคุณต้องการให้มันทำงานอย่างไร
x4rf41

2
ฉันรู้ แต่ดู .. th และ td ไม่แสดงเต็มความกว้าง .. postimg.org/image/mgd630y61
Marko S

ที่เกี่ยวข้อง: stackoverflow.com/questions/1019938/…
Christophe Roussy

คำตอบ:


674

เพื่อให้สามารถ<tbody>เลื่อนองค์ประกอบได้เราจำเป็นต้องเปลี่ยนวิธีการแสดงผลบนหน้าเว็บเช่นใช้display: block;เพื่อแสดงว่าเป็นองค์ประกอบระดับบล็อก

เนื่องจากเราเปลี่ยนdisplayคุณสมบัติของtbodyเราควรเปลี่ยนคุณสมบัติของtheadองค์ประกอบเช่นกันเพื่อป้องกันไม่ให้เค้าโครงตารางแตก

ดังนั้นเราจึงมี:

thead, tbody { display: block; }

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

เว็บเบราว์เซอร์แสดงtheadและtbodyองค์ประกอบเป็นกลุ่มแถว ( table-header-groupและtable-row-group) ตามค่าเริ่มต้น

เมื่อเราเปลี่ยนสิ่งนั้นtrองค์ประกอบภายในจะไม่เติมพื้นที่ทั้งหมดของคอนเทนเนอร์

ในการแก้ไขนั้นเราต้องคำนวณความกว้างของtbodyคอลัมน์และใช้ค่าที่สอดคล้องกับtheadคอลัมน์ผ่านทาง JavaScript

คอลัมน์ความกว้างอัตโนมัติ

นี่คือรุ่น jQuery ของตรรกะด้านบน:

// 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]);
});    

และนี่คือผลลัพธ์(ใน Windows 7 Chrome 32) :

เลื่อนแนวตั้งภายในร่างกาย

ทำงาน DEMO

ตารางความกว้างเต็ม, คอลัมน์ความกว้างสัมพัทธ์

ตามที่ผู้โพสต์ดั้งเดิมต้องการเราสามารถขยายได้tableถึง 100% ของwidthคอนเทนเนอร์แล้วใช้ญาติ ( ร้อยละ ) widthสำหรับแต่ละคอลัมน์ของตาราง

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

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

เนื่องจากตารางมี (ประเภท) รูปแบบของเหลวเราควรปรับความกว้างของtheadคอลัมน์เมื่อปรับขนาดภาชนะ

ดังนั้นเราควรตั้งค่าความกว้างของคอลัมน์เมื่อปรับขนาดหน้าต่างแล้ว:

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

ผลลัพธ์จะเป็น:

ตารางของไหลที่มีการเลื่อนในแนวตั้งภายในร่างกาย

ทำงาน DEMO


การสนับสนุนเบราว์เซอร์และทางเลือก

ฉันได้ทดสอบทั้งสองวิธีข้างต้นใน Windows 7 ผ่านเว็บเบราว์เซอร์หลักรุ่นใหม่ (รวมถึง IE10 +) และใช้งานได้

อย่างไรก็ตามมันไม่ ทำงาน อย่างถูกต้อง ใน IE9และด้านล่าง

นั่นเป็นเพราะในเค้าโครงตารางองค์ประกอบทั้งหมดควรเป็นไปตามคุณสมบัติโครงสร้างเดียวกัน

โดยใช้display: block;สำหรับ<thead>และ<tbody>องค์ประกอบเราได้ทำลายโครงสร้างตาราง

ออกแบบเลย์เอาต์ใหม่ผ่าน JavaScript

วิธีหนึ่งคือการออกแบบเค้าโครงตาราง (ทั้งหมด) ใหม่ ใช้ JavaScript เพื่อสร้างเค้าโครงใหม่ได้ทันทีและจัดการและ / หรือปรับความกว้าง / ความสูงของเซลล์แบบไดนามิก

ตัวอย่างเช่นลองดูตัวอย่างต่อไปนี้:

ตารางทำรัง

วิธีนี้ใช้ตารางที่ซ้อนกันสองตัวพร้อมกับ div ที่มีอยู่ ครั้งแรกtableมีเพียงเซลล์เดียวที่มีdivและตารางที่สองถูกวางไว้ภายในdivองค์ประกอบนั้น

ตรวจสอบตารางการเลื่อนแนวตั้งที่CSS เล่น

สิ่งนี้ใช้ได้กับเว็บเบราว์เซอร์ส่วนใหญ่ นอกจากนี้เรายังสามารถทำตรรกะข้างต้นแบบไดนามิกผ่านทาง JavaScript

ตารางที่มีส่วนหัวคงที่ในการเลื่อน

เนื่องจากจุดประสงค์ในการเพิ่มแถบเลื่อนแนวตั้งลง<tbody>ในตารางแสดงส่วนหัวที่ด้านบนของแต่ละแถวเราสามารถวางตำแหน่งtheadองค์ประกอบที่จะเข้าพักfixedที่ด้านบนของหน้าจอแทน

นี่คือการสาธิตการทำงานของวิธีการนี้ดำเนินการโดยมั๊ย
มีการสนับสนุนเว็บเบราว์เซอร์ที่มีแนวโน้ม

และนี่บริสุทธิ์ CSSการดำเนินงานโดยวิลเล็มแวน Bockstal


โซลูชัน CSS เพียว

นี่คือคำตอบเก่า แน่นอนฉันได้เพิ่มวิธีการใหม่และปรับปรุงการประกาศ CSS

ตารางที่มีความกว้างคงที่

ในกรณีนี้tableควรมีการแก้ไขwidth (รวมถึงผลรวมของความกว้างของคอลัมน์และความกว้างของแถบเลื่อนแนวตั้ง) (รวมผลรวมของความกว้างคอลัมน์และความกว้างของแนวตั้งเลื่อนแถบ)

แต่ละคอลัมน์ควรจะมีเฉพาะความกว้างและคอลัมน์สุดท้ายของtheadองค์ประกอบความต้องการมากขึ้นความกว้างซึ่งเท่ากับคนอื่น ๆความกว้างด้าน + ความกว้างของแถบเลื่อนแนวตั้ง

ดังนั้น CSS จะเป็น:

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

นี่คือผลลัพธ์:

ตารางที่มีความกว้างคงที่

สาธิตการทำงานDEMO

ตารางที่มีความกว้าง 100%

ในวิธีการtableนี้มีความกว้าง100%และสำหรับแต่ละthและtdมูลค่าของwidthทรัพย์สินควรน้อยกว่า100% / number of colsคุณสมบัติที่ควรจะน้อยกว่า

นอกจากนี้เราต้องลดความกว้างของtheadตามค่าความกว้างของแถบเลื่อนแนวตั้ง

เพื่อที่จะทำเช่นนั้นเราจำเป็นต้องใช้calc()ฟังก์ชั่นCSS3 ดังต่อไปนี้:

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;
}

นี่คือการสาธิตออนไลน์

หมายเหตุ:วิธีการนี้จะล้มเหลวถ้าเนื้อหาของแต่ละแบ่งคอลัมน์บรรทัดเช่นเนื้อหาของแต่ละเซลล์ควรจะเพียงพอสั้น


ในตัวอย่างต่อไปนี้มีสองตัวอย่างง่ายๆของโซลูชัน CSS บริสุทธิ์ที่ฉันสร้างขึ้นเมื่อฉันตอบคำถามนี้

นี่คือjsFiddle Demo v2 v2

รุ่นเก่า: jsFiddle Demo v1


17
เมื่อdisplay: blockคุณคลายคุณสมบัติของตารางตามความกว้างของคอลัมน์ที่แชร์ระหว่าง thead และ tbody ฉันรู้ว่าคุณได้แก้ไขสิ่งนี้ด้วยการตั้งค่าwidth: 19.2%แต่ในกรณีที่เราไม่ทราบความกว้างของแต่ละคอลัมน์ล่วงหน้าสิ่งนี้จะไม่ทำงาน
samb

10
รหัสนี้ดูเหมือนว่าจะถือว่าเซลล์ร่างกายจะกว้างกว่าเซลล์ส่วนหัวเสมอ
Adam Donahue

2
ไม่ทำงานเมื่อheight: 100%(เมื่อคุณต้องการให้ตารางขยายไปถึงด้านล่างของหน้า)
AlikElzin-kilaka

2
สิ่งนี้ยังใช้งานได้ดีกับng-repeatตารางAngularJS ไม่แน่ใจว่าทำไมมีไลบรารีทั้งหมดที่มีส่วนหัวของตารางคงที่และสิ่งที่ไม่เมื่อมีวิธีนี้
chakeda

2
คุณสามารถปรับปรุงสิ่งนี้ได้อีกเล็กน้อยด้วยbox-sizingคุณสมบัติเพื่อให้เส้นขอบที่มีความหนาแตกต่างกันสองตัวไม่ทำให้การจัดแนวคอลัมน์ลดลง
Ricca

89

ในโซลูชันต่อไปนี้ตารางใช้ 100% ของคอนเทนเนอร์หลักไม่จำเป็นต้องใช้ขนาดที่แน่นอน มันเป็น CSS ล้วนๆใช้ flex layout

นี่คือลักษณะ: ป้อนคำอธิบายรูปภาพที่นี่

ข้อเสียที่เป็นไปได้:

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

HTML (สั้นลง):

<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 โดยมีการตกแต่งบางอย่างเพื่อความชัดเจน:

.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;
}

รหัสเต็มใน jsfiddle

รหัสเดียวกันใน LESS เพื่อให้คุณสามารถผสมใน:

.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
ขอบคุณสำหรับการแก้ปัญหา! มีข้อผิดพลาดเล็กน้อย .... คุณตั้งค่าความกว้างสำหรับ thead สองครั้งและฉันพบว่าการลบ 1.05em จากความกว้างเป็นเส้นที่ดีขึ้นเล็กน้อย: jsfiddle.net/xuvsncr2/170
TigerBear

1
จำนวนเนื้อหาของตัวละครเป็นอย่างไร? มันเลอะเมื่อมีการเพิ่มตัวอักษรหรือคำเพิ่มเติมภายในเซลล์แถว
Limon

ผมคิดว่าการกำหนดนโยบายการตัดบางส่วนที่เหมาะสมบนtdจะช่วย
tsayen

วิธีแก้ปัญหาเช่นนี้ แต่ต้องการความกว้าง 100% หรือไม่
Alexandre Pereira Nunes

2
@tsayen คุณจะหยุดการกระทืบและทับซ้อนเมื่อคุณปรับขนาดหน้าต่างได้อย่างไร
clearshot66

31

ในเบราว์เซอร์สมัยใหม่คุณสามารถใช้ css:

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

8
คาถานี้ไม่สมบูรณ์ ... สนใจที่จะโพสต์ตัวอย่างหรืออย่างน้อยก็มีความละเอียด?
เลียม

ทำงานได้ดี แต่ใช้กับ th เท่านั้น หากเราตั้งค่าตำแหน่งเหนียวบน thead มันก็ไม่ทำงาน
Vishal

แก้ไข thead ควรเพิ่มใน W3C!
sonichy

2
คำตอบนี้ทำงานเมื่อคุณห่อของคุณ<table>ด้วย<div>ซึ่งมีและบางoverflow-y: auto; max-heightตัวอย่างเช่น:<div style="overflow-y: auto; max-height: 400px;"><table>...</table></div>
Minwork

ตั้งแต่ปี 2020 นี่เป็นคำตอบที่เลือก (พร้อมอัปเดตของ @Minwork)
Christophe Vidal

18

ฉันใช้display:blockสำหรับและthead tbodyเนื่องจากความกว้างของtheadคอลัมน์นั้นแตกต่างจากความกว้างของtbodyคอลัมน์

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

ในการแก้ไขปัญหานี้ฉันใช้jQueryรหัสขนาดเล็กแต่สามารถทำได้ใน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);           
}  

นี่คือตัวอย่างการทำงานของฉัน: http://jsfiddle.net/gavroche/N7LEF/

ไม่ทำงานใน IE 8


นี่เป็นทางออกที่ดีที่สุด / ง่ายที่สุดที่ฉันพบซึ่งอนุญาตสำหรับความกว้างของคอลัมน์ที่ไม่คงที่ (เช่น. NET DataGrid control) สำหรับ "การผลิต" colNumberตัวแปรอาจถูกแทนที่ด้วยรหัสซึ่งวนซ้ำผ่านเซลล์จริงที่พบแทนและโปรดทราบว่ามันไม่สามารถจัดการได้อย่างถูกต้องหากมีcolspans (สามารถปรับปรุงได้ในรหัสถ้าจำเป็น แต่ไม่น่าจะเป็นในรูปแบบของ ตารางน่าจะต้องการคุณลักษณะการเลื่อนนี้)
JonBrave

วิธีนี้ใช้งานได้ (ตามแฟชั่น) แต่ไม่สามารถรับมือได้เมื่อขนาดหน้าต่างเล็กกว่าตาราง (เนื่องจากจะไม่พิจารณาความกว้างของแถบเลื่อน)
Gone Coding

ใช่ส่วนหัวและเซลล์ไม่ตรงถ้าคุณความกว้างของตารางถูกกักขังอยู่ในความกว้างชุด
เครก

คำตอบที่ดีที่สุดที่นี่ง่ายที่สุดเช่นกัน
Charles Okwuagwu

18

CSS เท่านั้น

สำหรับChrome, Firefox, Edge (และเบราว์เซอร์อื่น ๆ ที่เขียวชอุ่มตลอดปี )

เพียงแค่องค์ประกอบposition: sticky; top: 0;ของคุณth:

/* 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: หากคุณต้องการเส้นขอบสำหรับองค์ประกอบ TH th {box-shadow: 1px 1px 0 #000; border-top: 0;}จะช่วยได้ (เนื่องจากเส้นขอบเริ่มต้นจะไม่ถูกวาดอย่างถูกต้องในการเลื่อน)

สำหรับตัวแปรด้านบนที่ใช้เพียงเล็กน้อยของ JS เพื่อรองรับIE11ดูคำตอบนี้https://stackoverflow.com/a/47923622/383904


หากคุณมีเส้นขอบสำหรับองค์ประกอบ th การใช้ "เส้นขอบยุบ: ยุบ" จะติดขอบกับร่างกายแทนที่จะเป็นส่วนหัว เพื่อหลีกเลี่ยงปัญหานี้คุณควรใช้ "เส้นขอบยุบ: แยก" ดูstackoverflow.com/a/53559396
mrod

@ คลั่งเมื่อใช้separateคุณกำลังเติมน้ำมันลงไปในไฟ jsfiddle.net/RokoCB/o0zL4xywและดูวิธีแก้ปัญหาที่นี่: เพิ่มเส้นขอบเพื่อแก้ไข TH - ฉันยินดีรับข้อเสนอแนะ OFC หากฉันพลาดบางสิ่งบางอย่าง
Roko C. Buljan

11

สร้างสองตารางหนึ่งหลังจากนั้นวางตารางที่สองใน div ของความสูงคงที่และตั้งค่าคุณสมบัติการล้นเป็นอัตโนมัติ ยังทำให้ td ทั้งหมดอยู่ใน thead ในตารางที่สองว่าง

<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
ในกรณีนี้คอลัมน์ตารางที่สองไม่สามารถติดตามความกว้างของตารางแรกได้
kat1330

2
ไม่ดี! คุณสูญเสียการซิงโครไนซ์ความกว้างสำหรับคอลัมน์ในสองตาราง
Zafar

1
เพื่อแก้ปัญหานี้ให้สมบูรณ์เราจำเป็นต้องเพิ่มสคริปต์ @Hashem Qolami (อธิบายด้านบน ) เพื่อซิงโครไนซ์ความกว้างคอลัมน์ส่วนหัว
Elhay Avichzer

6

ในที่สุดฉันก็เข้าใจถูกต้องด้วย CSS บริสุทธิ์โดยทำตามคำแนะนำเหล่านี้:

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

ขั้นตอนแรกคือการตั้งค่าเป็น<tbody>display: block เพื่อให้สามารถใช้งาน overflow และ height ได้ จากนั้นแถวในที่<thead>จะต้องมีการตั้งค่าไปยังตำแหน่ง: ญาติและการแสดงผล: <tbody>บล็อกเพื่อที่พวกเขาจะนั่งอยู่บนด้านบนของเลื่อนในขณะนี้

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

เนื่องจาก<thead>ตำแหน่งค่อนข้างอยู่ในแต่ละเซลล์ตารางจึงต้องการความกว้างที่ชัดเจน

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; }

แต่น่าเสียดายที่นั่นยังไม่เพียงพอ เมื่อเลื่อนเป็นเบราว์เซอร์ปัจจุบันจัดสรรพื้นที่สำหรับมันจึงสิ้นสุดลงด้วยการมีพื้นที่น้อยกว่าที่มีอยู่<tbody> <thead>สังเกตุว่ามีการเยื้องศูนย์เล็กน้อยที่สิ่งนี้สร้าง ...

วิธีแก้ปัญหาเดียวที่ฉันสามารถทำได้คือตั้งค่าความกว้างขั้นต่ำในทุกคอลัมน์ยกเว้นคอลัมน์สุดท้าย

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; }

ตัวอย่าง codepen ทั้งหมดด้านล่าง:

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

แก้ไข: โซลูชันทางเลือกสำหรับความกว้างของตาราง 100% (จริง ๆ แล้วสำหรับความกว้างคงที่และไม่ได้ตอบคำถาม):

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;
}

การสาธิต: http://codepen.io/anon/pen/bNJeLO


1
คำถามต้องการตารางความกว้าง 100% โดยเฉพาะซึ่งเป็นสิ่งหนึ่งที่ตัวอย่างที่คุณอ้างอิงไม่ได้ทำ
Gone Coding

@TrueBlueAussie จับได้ดี: D เพิ่มโซลูชันทางเลือกสำหรับความกว้าง 100%
Mikael Lepistö

คุณไม่พิจารณาเส้นแวงเนื้อหาเซลล์แถว
Limon

2

วิธีแก้ปัญหา CSS สำหรับบังคับให้คอลัมน์แสดงอย่างถูกต้องด้วย 'บล็อก' tbody

โซลูชันนี้ยังต้องการthความกว้างในการคำนวณและตั้งค่าโดย 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;
}

และ 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 ในปี 2019 เป็นเรื่องปกติมากที่จะไม่สนใจ IE เลย
Automagisch

2

ลองวิธีการด้านล่างง่ายมากที่จะใช้งานง่าย

ด้านล่างเป็นลิงค์ 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;
 }

jquery:

 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
วิธีนี้ไม่สามารถรับมือกับหน้าต่างที่แคบกว่าความกว้างของตาราง มันควรเปิดใช้งานการเลื่อนแนวนอนเมื่อเกิดขึ้น ส่วนหัวยังไม่สอดคล้องกับเซลล์ข้อมูล (Chrome)
Gone Coding

ปัจจุบันใช้งานไม่ได้
MrHIDEn

2

การเพิ่มความกว้างคงที่เพื่อtd, THหลังจากการtbody & theadบล็อกจอแสดงผลการทำงานอย่างสมบูรณ์และนอกจากนี้เราสามารถใช้slimscrollปลั๊กอินที่จะทำให้แถบเลื่อนที่สวยงาม

ป้อนคำอธิบายรูปภาพที่นี่

<!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

นี่คือรหัสที่ใช้งานได้สำหรับฉันในการสร้างกระดาษเหนียวเหนียวบนโต๊ะที่มีลำตัวเลื่อนได้:

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

สำหรับการใช้ "โอเวอร์โฟลว์: เลื่อน" คุณต้องตั้งค่า "display: block" บน thead และ tbody และนั่นทำให้เกิดความกว้างของคอลัมน์ระหว่างสิ่งนั้น แต่จากนั้นคุณสามารถโคลนแถว thead ด้วย Javascript และวางลงใน tbody เป็นแถวที่ซ่อนอยู่เพื่อรักษาความกว้างคอลัมน์ที่แน่นอน

$('.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>

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

ลองjsfiddleนี้ นี่ใช้ jQuery และทำจากคำตอบของ Hashem Qolami ในตอนแรกทำตารางปกติแล้วทำให้เลื่อนได้

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");

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