ตารางที่มีส่วนหัวคงที่และคอลัมน์คงที่บน pure css


104

ฉันต้องการสร้างตาราง html (หรือสิ่งที่คล้ายกัน) โดยมีส่วนหัวคงที่และคอลัมน์แรกคงที่

ทุกวิธีที่ฉันเคยเห็นใช้ Javascript หรือjQueryตั้ง scrollTop / scrollLeft แต่มันทำงานไม่ราบรื่นบนเบราว์เซอร์มือถือดังนั้นฉันจึงกำลังมองหาโซลูชัน CSS ที่แท้จริง

ฉันพบวิธีแก้ปัญหาสำหรับคอลัมน์คงที่ที่นี่: jsfiddle.net/C8Dtf/20/แต่ฉันไม่รู้ว่าจะปรับปรุงอย่างไรเพื่อให้ส่วนหัวได้รับการแก้ไขด้วย

ฉันต้องการให้มันทำงานบนเบราว์เซอร์ webkit หรือใช้css3คุณสมบัติบางอย่างแต่ฉันขอย้ำอีกครั้งว่าฉันไม่ต้องการใช้Javascriptเพื่อเลื่อน

แก้ไข:นี่คือตัวอย่างของพฤติกรรมที่ฉันต้องการบรรลุ: https://web.archive.org/web/20130829032141/http://datatables.net/release-datatables/extras/FixedColumns/css_size.html


ฉันไม่เห็นว่า <html> <table> ที่มีส่วนหัวคงที่ <thead> เกี่ยวข้องกับ css-level-3 ในขณะนี้ คุณมีอะไรอีกบ้าง? คุณได้ลองทำอะไรมาบ้าง?
Milche Patern

ฉันพยายามใช้positionพฤติกรรมที่ซับซ้อนกับแถวและเซลล์ แต่ฉันไม่ค่อยเข้าใจว่ามันเป็นตัวแปรหรือไม่
panfil

2
คำตอบนี้อาจช่วยคุณได้stackoverflow.com/questions/14834198/…
Garry

คำตอบ:


153

โซลูชัน CSS ที่แท้จริงที่มีแถวส่วนหัวคงที่และคอลัมน์แรก

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

position: stickyคุณสมบัติรองรับการติดทั้งสองไปด้านบน (เท่าที่ผมเคยเห็นมันใช้มากที่สุด) และด้านข้างในรุ่นที่ทันสมัยของ Chrome, Firefox และขอบ สิ่งนี้สามารถใช้ร่วมกับdivที่มีoverflow: scrollคุณสมบัติเพื่อให้ตารางที่มีส่วนหัวคงที่ซึ่งสามารถวางไว้ที่ใดก็ได้บนหน้าของคุณ

วางโต๊ะของคุณในภาชนะ:

<div class="container">
  <table></table>
</div>

ใช้overflow: scrollบนคอนเทนเนอร์ของคุณเพื่อเปิดใช้งานการเลื่อน:

div.container {
  overflow: scroll;
}

ในฐานะที่เป็นDagmarชี้ให้เห็นในความคิดเห็นที่ภาชนะที่ยังต้องและmax-widthmax-height

ใช้position: stickyที่จะมีเซลล์โต๊ะติดกับขอบและtop, rightหรือleftเลือกที่ทันสมัยเพื่อติด:

thead th {
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  top: 0;
}

tbody th {
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  left: 0;
}

ตามที่MarredCheeseกล่าวไว้ในความคิดเห็นหากคอลัมน์แรกของคุณมี<td>องค์ประกอบแทนที่จะเป็น<th>องค์ประกอบคุณสามารถใช้tbody td:first-childใน CSS ของคุณแทนtbody th

หากต้องการให้ส่วนหัวในคอลัมน์แรกติดทางซ้ายให้ใช้:

thead th:first-child {
  left: 0;
  z-index: 1;
}

https://jsfiddle.net/qwubvg9m/1/


22
นี่เป็นคำตอบที่ดีที่สุด
user1190132

9
@PirateApp หากคุณรู้จักwidthคอลัมน์แรกของคุณคุณสามารถใช้position: stickyกับเซลล์ในคอลัมน์ที่สองของคุณโดยมีleftค่าเท่ากับคอลัมน์แรกของคุณwidth: jsfiddle.net/wvypo83c/794
Matthew Schlachter

4
คำตอบนี้พิสูจน์ได้ว่าคุ้มค่าที่จะอ่านจนจบ!
mlerley

4
สิ่งนี้ใช้ไม่ได้หากไม่มีการตั้งค่าความกว้างสูงสุดและความสูงสูงสุดบนคอนเทนเนอร์
Dagmar

10
คำตอบนี้คือประภาคารที่นำทางเรากลับบ้านผ่านทะเลแห่งความผิดปกติที่ไม่สิ้นสุดซับซ้อนและเสียเวลาคำตอบจากโปสเตอร์ที่ได้รับการโหวตอย่างน่าประหลาดใจและน่าประหลาดใจที่ SO และทั่วทั้งเว็บ โปรดทราบว่าถ้าคอลัมน์แรกของคุณมี<td>องค์ประกอบแทน<th>องค์ประกอบคุณสามารถใช้tbody td:first-childใน CSS tbody thของคุณแทน
MarredCheese

33

ปัจจุบันนี้เป็นไปได้ที่จะบรรลุโดยใช้CSSกับposition: stickyคุณสมบัติเท่านั้น

นี่คือตัวอย่างข้อมูล:

(jsFiddle: https://jsfiddle.net/hbqzdzdt/5/ )

.grid-container {
  display: grid; /* This is a (hacky) way to make the .grid element size to fit its content */
  overflow: auto;
  height: 300px;
  width: 600px;
}
.grid {
  display: flex;
  flex-wrap: nowrap;
}
.grid-col {
  width: 150px;
  min-width: 150px;
}

.grid-item--header {
  height: 100px;
  min-height: 100px;
  position: sticky;
  position: -webkit-sticky;
  background: white;
  top: 0;
}

.grid-col--fixed-left {
  position: sticky;
  left: 0;
  z-index: 9998;
  background: white;
}
.grid-col--fixed-right {
  position: sticky;
  right: 0;
  z-index: 9998;
  background: white;
}

.grid-item {
  height: 50px;
  border: 1px solid gray;
}
<div class="grid-container">
  <div class="grid">
    <div class="grid-col grid-col--fixed-left">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col grid-col--fixed-right">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
    </div>

  </div>
</div>

เกี่ยวกับความเข้ากันได้. ใช้งานได้กับเบราว์เซอร์หลัก ๆ ทั้งหมด แต่ใช้ไม่ได้ใน IE มี polyfill สำหรับposition: stickyแต่ฉันไม่เคยลอง


2
เยี่ยมมากรักเลย!
Captain Lu

3
วิธีใดที่จะบรรลุสิ่งนี้ด้วยแท็ก <table> และไม่ใช่ <div>
Andreas

1
ฉันคิดว่าสิ่งนี้จะไม่มีประสิทธิภาพที่ดีหากคุณกำลังพัฒนาแอปพลิเคชันและจำเป็นต้องวนซ้ำระเบียนเพื่อพิมพ์ตารางนี้เนื่องจากทุกคอลัมน์ในตารางคุณต้องวนรอบอาร์เรย์ของระเบียนทั้งหมด HTML นี้ทำงานทีละคอลัมน์
igasparetto

@igasparetto คุณสามารถจัดเรียงแถว / คอลัมน์ในทางกลับกันได้และโซลูชันจะยังคงใช้งานได้ ถ้าฉันมีเวลาในภายหลังฉันสามารถสร้างตัวอย่างข้อมูลด้วยแถวลำดับตาราง ->
Alvaro

2
ฉันขอแนะนำไม่ให้แสดงข้อมูลแบบตารางโดยไม่ใช้ <table> และแท็กที่เกี่ยวข้อง มีปัญหาหลายประการในการทำลายวัตถุประสงค์การใช้ HTML ด้วยวิธีนี้รวมถึงการเข้าถึง ดูเพิ่มเติมที่: w3.org/WAI/tutorials/tables
Ben Morris

15

นี้จะไม่มีเรื่องง่าย.

ลิงค์ต่อไปนี้คือการสาธิตที่ใช้งานได้:

ลิงค์อัพเดทตามความคิดเห็นของ lanoxx

http://jsfiddle.net/C8Dtf/366/

อย่าลืมเพิ่มสิ่งเหล่านี้:

<script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/media/js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/media/js/jquery.dataTables.js"></script>
<script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/extras/FixedColumns/media/js/FixedColumns.js"></script>

ฉันไม่เห็นวิธีอื่นในการบรรลุสิ่งนี้ โดยเฉพาะอย่างยิ่งไม่ใช้ css เท่านั้น

นี่คือสิ่งที่ต้องผ่านมากมาย หวังว่านี่จะช่วยได้ :)


ในการสลับตัวกรองให้ใช้: "bFilter": false
lanoxx

6
มันเป็นไปได้ที่จะบรรลุเป้าหมายนี้ด้วย CSS เท่านั้น ไม่ใช่เรื่องง่าย แต่เป็นไปได้
Jimmy T.

จาก 10 วิธีแก้ปัญหานี่เป็นวิธีเดียวที่ใช้ได้ผล Btw เพื่อลบ "กำลังแสดง 1 ถึง 57 จาก 57 รายการ" ที่เพิ่ม"bInfo" : falseเข้าไปในการ.dataTable()โทร
hansaplast

ข้อมูล == "น่ากลัว"
billynoah

การลงคะแนนการแก้ปัญหานี้เนื่องจากไม่ดี theadอยู่ในโต๊ะของตัวเองที่จะไม่ผูกพันกับการเปลี่ยนแปลงของtdองค์ประกอบดังนั้นหากข้อความมือถือเป็นยาวthความกว้างจะไม่ปรับตาม
vsync

14

คำแนะนำทั้งหมดนี้ดีมากและทั้งหมดนี้เป็นเพียงการแก้ไขส่วนหัวหรือคอลัมน์เท่านั้นไม่ใช่ทั้งสองอย่างหรือใช้จาวาสคริปต์ เหตุผล - ไม่เชื่อว่าจะทำได้ใน CSS ที่บริสุทธิ์ เหตุผล:

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

ละเอียด. แต่ตอนนี้ปัญหา - คุณสามารถทำให้หนึ่งในนั้นคงอยู่ได้เมื่อคุณเลื่อน แต่อีกอันจะซ้อนอยู่ในพื้นที่การเลื่อนของอันดับแรกดังนั้นจึงอาจถูกเลื่อนออกไปจากสายตาดังนั้นจึงไม่สามารถแก้ไขได้ หน้าจอ. คุณพูดว่า 'Ah-ha' แต่ฉันสามารถใช้ตำแหน่งที่แน่นอนหรือคงที่เพื่อทำเช่นนั้นได้ '- ไม่คุณทำไม่ได้ ทันทีที่คุณทำคุณจะสูญเสียความสามารถในการเลื่อนคอนเทนเนอร์นั้น มันเป็นสถานการณ์ของไก่และไข่ - คุณไม่สามารถมีทั้งสองอย่างได้พวกเขาจะยกเลิกกันและกัน

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

http://tympanus.net/codrops/2014/01/09/sticky-table-headers-columns/


9

ฉันได้ทำการเปลี่ยนแปลงบางอย่างใน jsfiddle นี่อาจเป็นสิ่งที่คุณกำลังพยายามทำ

http://jsfiddle.net/C8Dtf/81/

ฉันได้เข้ารหัสชื่อเรื่องไว้แล้ว:

<table id="left_table" class="freeze_table">
    <tr class='tblTitle'>
         <th>Title 1</th>
         <th>Title 2</th>
    </tr>
</table>

และฉันได้เพิ่มรูปแบบบางอย่างเข้าไปด้วย

.tblTitle{
   position:absolute;
    top:0px;
    margin-bottom:30px;
    background:lightblue;
}
td, th{
    padding:5px;
    height:40px;
    width:40px;
    font-size:14px;
}

หวังว่านี่คือสิ่งที่คุณต้องการ :)


1
ฉันต้องการส่วนหัวของตารางที่ถูกต้องเพื่อเลื่อนไปพร้อมกับเนื้อหา
panfil

นี่คือ URL: jsfiddle.net/C8Dtf/84 คุณเพียงแค่ต้องเล่นกับรูปแบบสำหรับโต๊ะด้านขวามือเพื่อจัดแนวสองตาราง
Phillip-juan

ไม่คุณไม่ค่อยเข้าใจ ฉันต้องการให้ส่วนหัวของตารางด้านขวายึดไว้ที่ด้านบนเพื่อที่จะยังคงมองเห็นได้เมื่อตารางเลื่อนขึ้นและลง แต่เมื่อตารางเลื่อนไปทางขวาหรือส่วนหัวซ้ายจะต้องเลื่อนไปทางขวาหรือซ้าย แต่ยังคงได้รับการแก้ไขที่ด้านบน ขอโทษที่ทักษะภาษาอังกฤษไม่ดี
panfil

ต้องการให้ส่วนหัวของตารางด้านขวาได้รับการแก้ไขเมื่อเลื่อนในแนวตั้งและเพื่อเลื่อนเมื่อเลื่อนในแนวนอน?
Phillip-juan

นี่คือตัวอย่างของพฤติกรรมที่ฉันต้องการบรรลุ: datatables.net/release-datatables/extras/FixedColumns/…
panfil

9

ตัวอย่างการใช้ CSS เท่านั้น:

.table {
  table-layout: fixed;
  width: 500px;
  border-collapse: collapse;
}

.header th {
  font-family: Calibri;
  font-size: small;
  font-weight: lighter;
  border-left: 1px solid #000;
  background: #d0d0d0;
}

.body_panel {
  display: inline-block;
  width: 520px;
  height: 300px;
  overflow-y: scroll;
}

.body tr {
  border-bottom: 1px solid #d0d0d0;
}

.body td {
  border-left: 1px solid #d0d0d0;
  padding-left: 3px;
  font-family: Calibri;
  font-size: small;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
<body>

  <table class="table">

    <thead class="header">

      <tr>
        <th style="width:20%;">teste</th>
        <th style="width:30%;">teste 2</th>
        <th style="width:50%;">teste 3</th>
      </tr>

    </thead>
  </table>

  <div class="body_panel">

    <table class="table">
      <tbody class="body">

        <tr>
          <td style="width:20%;">asbkj k kajsb ksb kabkb</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

      </tbody>
    </table>

  </div>

</body>


3
ฉันไม่เพียง แต่ต้องการความปลอดภัยเท่านั้น แต่ต้องแก้ไขคอลัมน์แรก
panfil

ตัวอย่างนี้แสดงแนวทางที่มีสองตารางใน html: ตารางหนึ่งแสดงผลเฉพาะส่วนหัว ตารางที่สองแสดงผลเฉพาะแถว แต่ทำภายในไฟล์div. เป็นการdivอนุญาตให้มีการเลื่อนแถวในขณะที่ส่วนหัวยังคงอยู่ที่เดิม วิธีนี้ใช้ได้ผลกับความต้องการของฉัน
David Tansey

หากมีการเลื่อนในแนวนอนคุณต้องมี JS เพื่อซิงโครไนซ์ตำแหน่งการเลื่อนของตาราง
ZoltánTamási

4

ฉันพบวิธีแก้ปัญหาที่ยอดเยี่ยมโดย Paul O'Brien สำหรับปัญหานี้และต้องการแชร์ลิงก์: https://codepen.io/paulobrien/pen/LBrMxa

ฉันลบสไตล์สำหรับส่วนท้าย:

html {
  box-sizing: border-box;
}
*,
*:before,
*:after {
  box-sizing: inherit;
}
.intro {
  max-width: 1280px;
  margin: 1em auto;
}
.table-scroll {
  position: relative;
  width:100%;
  z-index: 1;
  margin: auto;
  overflow: auto;
  height: 350px;
}
.table-scroll table {
  width: 100%;
  min-width: 1280px;
  margin: auto;
  border-collapse: separate;
  border-spacing: 0;
}
.table-wrap {
  position: relative;
}
.table-scroll th,
.table-scroll td {
  padding: 5px 10px;
  border: 1px solid #000;
}
.table-scroll thead th {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
}

th:first-child {
  position: -webkit-sticky;
  position: sticky;
  left: 0;
  z-index: 2;
  background: #ccc;
}
thead th:first-child {
  z-index: 5;
}

4

ในการแก้ไขทั้งส่วนหัวและคอลัมน์คุณสามารถใช้ปลั๊กอินต่อไปนี้:


อัปเดตในเดือนกรกฎาคม 2019

เมื่อเร็ว ๆ นี้ยังมีโซลูชัน CSS บริสุทธิ์ที่ใช้คุณสมบัติ CSS position: sticky;( ที่นี่สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้) ที่ใช้กับแต่ละTHรายการ (แทนคอนเทนเนอร์หลัก)


1
ลิงค์แรกเสีย อันที่สองใช้ jQuery
PussInBoots

อัปเดตคำตอบเพื่อลบลิงก์ที่ตายแล้ว
Luca Detomi

2

ฉันเพิ่งสร้างโซลูชันที่มีกลุ่มส่วนหัวคงที่และคอลัมน์แรกคงที่ ฉันแบ่งตารางของฉันออกเป็น div และใช้ jquery เพื่อจับการเลื่อนหน้าต่าง

http://jsfiddle.net/TinT/EzXub/2346/

var prevTop = 0;
var prevLeft = 0;

$(window).scroll(function(event){
  var currentTop = $(this).scrollTop();
  var currentLeft = $(this).scrollLeft();

  if(prevLeft !== currentLeft) {
    prevLeft = currentLeft;
    $('.header').css({'left': -$(this).scrollLeft()})
  }
  if(prevTop !== currentTop) {
    prevTop = currentTop;
    $('.leftCol').css({'top': -$(this).scrollTop() + 40})
  }
});

1

เพื่อนร่วมงานและฉันเพิ่งเปิดตัวโครงการ GitHub ใหม่ที่ให้คำสั่ง Angular ที่คุณสามารถใช้ตกแต่งตารางของคุณด้วยส่วนหัวคงที่: https://github.com/objectcomputing/FixedHeader

มันขึ้นอยู่กับ css และเชิงมุมเท่านั้นโดยมีคำสั่งที่เพิ่ม div บางตัว ไม่จำเป็นต้องใช้ jQuery

การใช้งานนี้ไม่ได้มีคุณลักษณะครบถ้วนเหมือนกับการใช้งานอื่น ๆ แต่หากคุณต้องการเพียงแค่เพิ่มตารางคงที่เราคิดว่านี่อาจเป็นตัวเลือกที่ดี


1

หลังจากสองวันต่อสู้กับ Internet Explorer 9 + Chrome + Firefox (Windows) และ Safari (Mac) ฉันได้พบระบบที่เป็น

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

ผลลัพธ์: ป้อนคำอธิบายภาพที่นี่

HTML:

  <thead>
    <tr>
      <th class="nombre"><%= f.label :cost_center %></th>
      <th class="cabecera cc">Personal</th>
      <th class="cabecera cc">Dpto</th>
    </tr>
  </thead>
  <tbody>
    <% @cost_centers.each do |cc| %>
    <tr>
      <td class="nombre"><%= cc.nombre_corto %></td>
      <td class="cc"><%= cc.cacentrocoste %></td>
      <td class="cc"><%= cc.cacentrocoste_dpto %></td>
    </tr>
    <% end %>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="3"><a href="#">Mostrar mas usuarios</a></td>
    </tr>
  </tfoot>
</table>

CSS:

div.cost_center{
  width:320px;
  font-size:75%;
  margin-left:5px;
  margin-top:5px;
  margin-bottom: 2px;
  float: right;
  display: inline-block;
  overflow-y: auto;
  overflow-x: hidden;
  max-height:300px;  
}

div.cost_center label { 
  float:none;
  font-size:14px;
}

div.cost_center table{
  width:300px;
  border-collapse: collapse; 
  float:right;
  table-layout:fixed;
}

div.cost_center table tr{
  height:16px;
}
div.cost_center th{
  font-weight:normal;
}

div.cost_center table tbody{
  display: block;
  overflow: auto;
  max-height:240px;
}

div.cost_center table thead{
  display:block;
}

div.cost_center table tfoot{
  display:block;
}
div.cost_center table tfoot td{
  width:280px;
}
div.cost_center .cc{
  width:60px;
  text-align: center; 
  border: 1px solid #999;
}

div.cost_center .nombre{
  width:150px;
}
div.cost_center tbody .nombre{
  border: 1px solid #999;
}

div.cost_center table tfoot td{
 text-align:center;  
 border: 1px solid #999; 
} 

div.cost_center table th, 
div.cost_center table td { 
  padding: 2px;
  vertical-align: middle; 
}

div.cost_center table tbody td {
  white-space: normal;
  font:  .8em/1.4em Verdana, sans-serif;
  color: #000;
  background-color: white;
}
div.cost_center table th.cabecera { 
  font:  0.8em/1.4em Verdana, sans-serif;
  color: #000;
  background-color: #FFEAB5;
}

ลองดี แต่ไม่ได้ผลสำหรับฉัน ในตัวอย่างนี้ ( jsfiddle.net/5ka6e ) ส่วนหัวไม่ได้ปรับขนาดอย่างถูกต้อง ข้อผิดพลาดประเภทนี้ในที่สุดอาจมีข้อมูลและส่วนหัวไม่ตรงกัน
darkzangel

1
คุณลืมเพิ่ม div.cost_center table{border-collapse: collapse;}และคำอธิบายภาพที่สามต้องเป็นสิ่งที่พอดีกับ 60px (ในตัวอย่างนี้)
Albert Català

1

คำตอบที่มีอยู่จะเหมาะกับคนส่วนใหญ่ แต่สำหรับผู้ที่ต้องการเพิ่มเงาภายใต้ส่วนหัวคงที่และทางด้านขวาของคอลัมน์แรก (คงที่) นี่คือตัวอย่างการทำงาน (pure css):

http://jsbin.com/nayifepaxo/1/edit?html,output

เคล็ดลับหลักในการทำให้สิ่งนี้ใช้งานได้คือการใช้::afterเพื่อเพิ่มเงาทางด้านขวาของแต่ละอันแรกtdในแต่ละอันtr:

tr td:first-child:after {
  box-shadow: 15px 0 15px -15px rgba(0, 0, 0, 0.05) inset;
  content: "";
  position:absolute;
  top:0;
  bottom:0;
  right:-15px;
  width:15px;
}

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


คุณยึดสิ่งนี้กับคนอื่นตอบและเพิ่มเงาหรือไม่?
PussInBoots

1

จำเป็นต้องแก้ไขส่วนท้ายของส่วนหัว


0

สิ่งนี้อาจได้ผลสำหรับคุณ ... คุณอาจต้องตั้งค่าความกว้างของคอลัมน์สำหรับแถวส่วนหัวของคุณ

thead { 
    position: fixed;
}

http://jsfiddle.net/vkhNC/

อัปเดต:

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


ฉันต้องการไม่เพียง แต่ส่วนหัวเท่านั้น แต่ต้องแก้ไขคอลัมน์แรกด้วย
panfil

5
ปัญหาคือส่วนหัวหลวมความกว้าง มันดูน่าเกลียดด้วยขนาดคอลัมน์ส่วนหัวและขนาดคอลัมน์ข้อมูลที่แตกต่างกัน
Akash Kava

0

อีกวิธีหนึ่งคือการใช้ AngularJS โมดูล AngularUI มีคำสั่งที่เรียกว่าng-gridซึ่งสนับสนุนคุณลักษณะที่เรียกว่าการตรึงคอลัมน์ ไม่ใช่ CSS ที่บริสุทธิ์ 100% แต่ไม่มีวิธีแก้ปัญหาอื่น ๆ

http://angular-ui.github.io/ng-grid/#columnPinning


0

ตัวอย่าง Pure CSS:

<div id="cntnr">
    <div class="tableHeader">
        <table class="table-header table table-striped table-bordered">
            <thead>
                <tr>
                    <th>this</th>
                    <th>transmission</th>
                    <th>is</th>
                    <th>coming</th>
                    <th>to</th>
                    <th>you</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                </tr>
            </tbody>
        </table>
    </div>


    <div class="tableBody">
        <table class="table-body table table-striped table-bordered">
            <thead>
                <tr>
                    <th>this</th>
                    <th>transmission</th>
                    <th>is</th>
                    <th>coming</th>
                    <th>to</th>
                    <th>you</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                </tr>
            </tbody>
        </table>
    </div>

</div>

#cntnr {
    width: auto;
    height: 200px;
    border: solid 1px #444;
    overflow: auto;
}

.tableHeader {
    position: fixed;
    height: 40px;
    overflow: hidden;
    margin-right: 18px;
    background: white;
}

.table-header tbody {
    height: 0;
    visibility: hidden;
}

.table-body thead {
    height: 0;
    visibility: hidden;
}

http://jsfiddle.net/cCarlson/L98m854d/

กีดขวาง:โครงสร้างส่วนหัวคง / ตรรกะเป็นธรรมขึ้นอยู่กับขนาดที่เฉพาะเจาะจงเพื่อนามธรรมอาจจะไม่ได้เป็นตัวเลือกที่ทำงาน


ต้องการทั้งส่วนหัวคงที่และคอลัมน์แรกคงที่
panfil

อา ... ขอบคุณสำหรับการชี้สิ่งนี้ panfil ฉันจะแก้ไข Cheers
Cody

0

ตำแหน่ง: Sticky ใช้ไม่ได้กับองค์ประกอบบางอย่างเช่น (thead) ใน Chrome และเบราว์เซอร์ webkit อื่น ๆ เช่น safari

แต่ใช้ได้ดีกับ (th)

body {
  background-color: rgba(0, 255, 200, 0.1);
}

.intro {
  color: rgb(228, 23, 23);
}

.wrapper {
  overflow-y: scroll;
  height: 300px;
}

.sticky {
  position: sticky;
  top: 0;
  color: black;
  background-color: white;
}
<div class="container intro">
  <h1>Sticky Table Header</h1>
  <p>Postion : sticky doesn't work for some elements like (thead) in chrome and other webkit browsers like safari. </p>
  <p>But it works fine with (th)</p>
</div>
<div class="container wrapper">
  <table class="table table-striped">
    <thead>
      <tr>
        <th class="sticky">Firstname</th>
        <th class="sticky">Lastname</th>
        <th class="sticky">Email</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>James</td>
        <td>Vince</td>
        <td>james@example.com</td>
      </tr>
      <tr>
        <td>Jonny</td>
        <td>Bairstow</td>
        <td>jonny@example.com</td>
      </tr>
      <tr>
        <td>James</td>
        <td>Anderson</td>
        <td>james@example.com</td>
      </tr>
      <tr>
        <td>Stuart</td>
        <td>Broad</td>
        <td>stuart@example.com</td>
      </tr>
      <tr>
        <td>Eoin</td>
        <td>Morgan</td>
        <td>eoin@example.com</td>
      </tr>
      <tr>
        <td>Joe</td>
        <td>Root</td>
        <td>joe@example.com</td>
      </tr>
      <tr>
        <td>Chris</td>
        <td>Woakes</td>
        <td>chris@example.com</td>
      </tr>
      <tr>
        <td>Liam</td>
        <td>PLunkett</td>
        <td>liam@example.com</td>
      </tr>
      <tr>
        <td>Jason</td>
        <td>Roy</td>
        <td>jason@example.com</td>
      </tr>
      <tr>
        <td>Alex</td>
        <td>Hales</td>
        <td>alex@example.com</td>
      </tr>
      <tr>
        <td>Jos</td>
        <td>Buttler</td>
        <td>jos@example.com</td>
      </tr>
      <tr>
        <td>Ben</td>
        <td>Stokes</td>
        <td>ben@example.com</td>
      </tr>
      <tr>
        <td>Jofra</td>
        <td>Archer</td>
        <td>jofra@example.com</td>
      </tr>
      <tr>
        <td>Mitchell</td>
        <td>Starc</td>
        <td>mitchell@example.com</td>
      </tr>
      <tr>
        <td>Aaron</td>
        <td>Finch</td>
        <td>aaron@example.com</td>
      </tr>
      <tr>
        <td>David</td>
        <td>Warner</td>
        <td>david@example.com</td>
      </tr>
      <tr>
        <td>Steve</td>
        <td>Smith</td>
        <td>steve@example.com</td>
      </tr>
      <tr>
        <td>Glenn</td>
        <td>Maxwell</td>
        <td>glenn@example.com</td>
      </tr>
      <tr>
        <td>Marcus</td>
        <td>Stoinis</td>
        <td>marcus@example.com</td>
      </tr>
      <tr>
        <td>Alex</td>
        <td>Carey</td>
        <td>alex@example.com</td>
      </tr>
      <tr>
        <td>Nathan</td>
        <td>Coulter Nile</td>
        <td>nathan@example.com</td>
      </tr>
      <tr>
        <td>Pat</td>
        <td>Cummins</td>
        <td>pat@example.com</td>
      </tr>
      <tr>
        <td>Adam</td>
        <td>Zampa</td>
        <td>zampa@example.com</td>
      </tr>
    </tbody>
  </table>
</div>

หรือเยี่ยมชมตัวอย่าง codepen ของฉัน :


-1

ฉันคิดว่าสิ่งนี้จะช่วยคุณได้: https://datatables.net/release-datatables/extensions/FixedHeader/examples/header_footer.html

โดยสรุปหากคุณรู้วิธีสร้าง dataTable คุณเพียงแค่ต้องเพิ่มบรรทัด jQuery นี้ที่ด้านล่างของคุณ:

$(document).ready(function() {
    var table = $('#example').DataTable();

    new $.fn.dataTable.FixedHeader( table, {
        bottom: true
    } );
} );

bottom: true // ใช้สำหรับทำให้ส่วนหัวด้านล่างคงที่เช่นกัน


-2

หากคุณต้องการใช้ HTML และ CSS เพียงอย่างเดียวฉันมีวิธีแก้ปัญหาของคุณ:
ในjsFiddleนี้คุณจะเห็นโซลูชันที่ไม่ใช่สคริปต์ที่ให้ตารางที่มีส่วนหัวคงที่ ไม่ควรเป็นปัญหาในการปรับมาร์กอัปสำหรับคอลัมน์แรกที่คงที่เช่นกัน คุณจะต้องสร้างตารางในตำแหน่งสัมบูรณ์สำหรับคอลัมน์แรกภายในhWrapper-div และเปลี่ยนตำแหน่งvWrapper-div
การให้เนื้อหาแบบไดนามิกไม่น่าจะเป็นปัญหาในการใช้เอนจิ้นดึงดูดฝั่งเซิร์ฟเวอร์หรือฝั่งเบราว์เซอร์โซลูชันของฉันใช้งานได้ดีในเบราว์เซอร์รุ่นใหม่และเบราว์เซอร์รุ่นเก่าตั้งแต่ IE8 เป็นต้นไป


-2

เพียงแค่ต้องเปลี่ยนสไตล์เป็น

<table style="position: relative;">
   <thead>
      <thead>
        <tr>
           <th></th>
        </tr>
      </thead>
   </thead>
   <tbody style="position: absolute;height: 300px;overflow:auto;">
      <tr>
         <td></td>
      </tr>
   </tbody>
</table>

การสาธิต: https://plnkr.co/edit/Qxy5RMJBXmkaJAOjBtQn?p=preview


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