Tabela HTML o 100% szerokości, z pionowym przewijaniem wewnątrz ciała

423

Jak ustawić <table>100% szerokości i umieścić tylko wewnątrz <tbody>pionowego przewijania dla pewnej wysokości?

pionowe przewijanie wewnątrz ciała

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>

Chcę uniknąć dodawania dodatkowego div, wszystko czego chcę to prosta tabela, a kiedy próbuję zmienić wyświetlanie table-layout, positioni wiele innych rzeczy w tabeli CSS nie działa dobrze przy 100% szerokości tylko ze stałą szerokością w px.

Marko S.
źródło
nie jestem pewien, co chcesz osiągnąć. spójrz na to: jsfiddle.net/CrSpu i powiedz, jak chcesz się zachowywać
x4rf41
2
Wiem, ale spójrz .. th i td nie są wyświetlane w pełnej szerokości .. postimg.org/image/mgd630y61
Marko S
Powiązane: stackoverflow.com/questions/1019938/…
Christophe Roussy

Odpowiedzi:

674

Aby umożliwić <tbody>przewijanie elementu, musimy zmienić sposób jego wyświetlania na stronie, np. Używając go display: block;do wyświetlania jako elementu na poziomie bloku.

Ponieważ zmieniamy displaywłaściwość tbody, powinniśmy również zmienić tę właściwość dla theadelementu, aby zapobiec uszkodzeniu układu tabeli.

Więc mamy:

thead, tbody { display: block; }

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

Przeglądarki internetowe domyślnie wyświetlają elementy theadi tbodyjako grupę wierszy ( table-header-groupi table-row-group).

Gdy to zmienimy, trelementy wewnętrzne nie zajmują całej przestrzeni pojemnika.

Aby to naprawić, musimy obliczyć szerokość tbodykolumn i zastosować odpowiednią wartość do theadkolumn za pomocą JavaScript.

Automatyczne kolumny szerokości

Oto wersja powyższej logiki 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]);
});    

A oto dane wyjściowe (w systemie Windows 7 Chrome 32) :

pionowe przewijanie wewnątrz ciała

DEMO ROBOCZE .

Tabela pełnej szerokości, kolumny o względnej szerokości

W miarę potrzeby Plakat oryginalny możemy rozszerzyć tabledo 100% widthjego kontenera, a następnie użyć wartości względnej ( Procent ) widthdla każdej kolumny tabeli.

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

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

Ponieważ tabela ma (w pewnym sensie) układ płynów , powinniśmy dostosować szerokość theadkolumn przy zmianie rozmiaru pojemnika.

Dlatego po zmianie rozmiaru okna powinniśmy ustawić szerokość kolumn:

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

Dane wyjściowe będą:

Płynny stół z pionowym przewijaniem wewnątrz ciała

DEMO ROBOCZE .


Obsługa przeglądarki i alternatywy

Testowałem dwie powyższe metody w systemie Windows 7 za pomocą nowych wersji głównych przeglądarek internetowych (w tym IE10 +) i działało.

Jednak nie działa poprawnie na IE9 i niższych.

Jest tak, ponieważ w układzie tabeli wszystkie elementy powinny mieć te same właściwości strukturalne.

Poprzez zastosowanie display: block;dla <thead>i <tbody>elementów, mamy złamane strukturę tabeli.

Przeprojektowanie układu za pomocą JavaScript

Jednym z podejść jest przeprojektowanie (całego) układu tabeli. Korzystanie z JavaScript do tworzenia nowego układu w locie oraz dynamiczne obsługiwanie i / lub dostosowywanie szerokości / wysokości komórek.

Na przykład spójrz na następujące przykłady:

Tabele zagnieżdżone

To podejście wykorzystuje dwie zagnieżdżone tabele z zawierającym div. Pierwsza tablema tylko jedną komórkę, która ma div, a druga tabela jest umieszczona wewnątrz tego divelementu.

Sprawdź pionowe tabele przewijania w CSS Play .

Działa to w większości przeglądarek internetowych. Powyższą logikę możemy również wykonać dynamicznie za pomocą JavaScript.

Tabela ze stałym nagłówkiem przy przewijaniu

Ponieważ w celu dodania pionowy pasek przewijania do <tbody>jest wyświetlający tabeli nagłówek na górze każdego wiersza, moglibyśmy umieścić ten theadelement, do pobytu fixedw górnej części ekranu, zamiast.

Oto robocza demonstracja tego podejścia wykonana przez Juliena .
Ma obiecującą obsługę przeglądarki internetowej.

I tutaj czystym CSS wdrożenie przez Willem Van Bockstal .


Rozwiązanie Pure CSS

Oto stara odpowiedź. Oczywiście dodałem nową metodę i dopracowałem deklaracje CSS.

Tabela ze stałą szerokością

W takim przypadku tablepowinien mieć stały width (w tym sumę szerokości kolumn i szerokość pionowego paska przewijania) .

Każda kolumna powinna mieć swoisty szerokość i ostatnia kolumna z theadelementu potrzebuje większą szerokość , która jest równa innych width + szerokości pionowego przewijania bar.

Dlatego CSS byłby:

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

Oto wynik:

Tabela ze stałą szerokością

DEMO ROBOCZE .

Stół o 100% szerokości

W tym podejściu, tablema szerokość 100%i dla każdego th, a tdwartość widthnieruchomości powinna być mniejsza niż 100% / number of cols.

Ponadto, musimy zmniejszyć szerokość od theadjak wartość szerokości pionowego przewijania bar.

Aby to zrobić, musimy użyć calc()funkcji CSS3 w następujący sposób:

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

Oto demo online .

Uwaga: Podejście to nie powiedzie się, jeśli zawartość każdej kolumny łamie linię, tj . Zawartość każdej komórki powinna być wystarczająco krótka .


Poniżej znajdują się dwa proste przykłady czystego rozwiązania CSS, które stworzyłem w momencie, gdy odpowiedziałem na to pytanie.

Oto jsFiddle Demo v2 .

Stara wersja: jsFiddle Demo v1

Hashem Qolami
źródło
17
Z display: blocktobą tracisz właściwości tabeli jako szerokość kolumny dzieloną między thead i tbody. Wiem, że naprawiłeś to przez ustawienie, width: 19.2%ale jeśli nie znamy z góry szerokości każdej kolumny, to nie zadziała.
samb.
10
Ten kod wydaje się zakładać, że komórki ciała będą zawsze szersze niż komórki nagłówka.
Adam Donahue,
2
Nie działa, kiedy height: 100%(gdy chcesz, aby tabela rozszerzyła się na dół strony).
AlikElzin-kilaka
2
Działa to również fantastycznie z ng-repeattabelami AngularJS . Nie jestem pewien, dlaczego są te wszystkie biblioteki z ustalonymi nagłówkami tabel, a co nie, gdy jest takie rozwiązanie.
czakeda
2
Możesz to nieco poprawić za pomocą tej box-sizingwłaściwości, aby granice dwóch różnych grubości nie odrzucały wyrównania kolumny.
Ricca,
89

W poniższym rozwiązaniu tabela zajmuje 100% kontenera nadrzędnego, nie są wymagane bezwzględne rozmiary. Jest to czysty CSS, używany jest układ elastyczny.

Oto jak to wygląda: wprowadź opis zdjęcia tutaj

Możliwe wady:

  • pionowy pasek przewijania jest zawsze widoczny, niezależnie od tego, czy jest wymagany;
  • układ tabeli jest stały - kolumny nie zmieniają rozmiaru zgodnie z szerokością treści (nadal możesz ustawić dowolną szerokość kolumny, którą chcesz jawnie);
  • jest jeden rozmiar bezwzględny - szerokość paska przewijania, który dla przeglądarek, które mogłem sprawdzić, wynosi około 0,9 em.

HTML (skrócony):

<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, z niektórymi dekoracjami pominiętymi dla jasności:

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

pełny kod na jsfiddle

Ten sam kod w LESS, dzięki czemu możesz go mieszać:

.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%;
    }
  }
}
Tsayen
źródło
2
Dzięki za rozwiązanie! Wystąpił niewielki błąd .... ustawiłeś szerokość dla thead dwa razy, a ja zauważyłem, że odejmowanie 1,05em od szerokości jest nieco lepsze: jsfiddle.net/xuvsncr2/170
TigerBear
1
co z zawartością numeru znaku? bałagan pojawia się, gdy dodaje się więcej znaków lub słów w komórkach wiersza
Limon,
Myślę, że wprowadzenie odpowiedniej polityki pakowania tdpowinno pomóc
tsayen
Jakieś takie rozwiązanie, ale rezygnujecie z potrzeby 100% szerokości?
Alexandre Pereira Nunes,
2
@tsayen Jak powstrzymać go przed zgniataniem i nakładaniem się podczas zmiany rozmiaru okna?
clearshot66
31

W nowoczesnych przeglądarkach możesz po prostu użyć css:

th {
  position: sticky;
  top: 0;
  z-index: 2;
}
Gaus
źródło
8
Ta inkantacja jest niekompletna ... Chcesz opublikować przykład, a przynajmniej opracować?
Liam,
działa dobrze, ale dotyczy tylko th. Jeśli ustawimy pozycję lepką na thead, to nie zadziała.
Vishal
Naprawiono thead powinien dodać do W3C!
sonichy
2
Odpowiedź ta działa po owinąć <table>z <div>którym ma overflow-y: auto;, a niektóre max-height. Na przykład:<div style="overflow-y: auto; max-height: 400px;"><table>...</table></div>
Minwork
Począwszy od 2020 r., Będzie to wybrana odpowiedź (wraz z aktualizacją @Minwork)
Christophe Vidal
18

Używam display:blockdla theadi tbody. Z tego powodu szerokość theadkolumn różni się od szerokości tbodykolumn.

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

Aby to naprawić, używam małego jQuerykodu, ale można to zrobić JavaScripttylko w.

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

Oto moje działające demo: http://jsfiddle.net/gavroche/N7LEF/

Nie działa w IE 8

gavroche
źródło
Jest to najlepsze / najprostsze rozwiązanie, jakie znalazłem, które pozwala na nieokreślone szerokości kolumn (np. Sterowanie .NET DataGrid). W przypadku „produkcji” -colNumber zmienna może zostać zastąpiona kodem, który iteruje się zamiast znalezionych komórek, i należy pamiętać, że nie radzi sobie poprawnie, jeśli są jakieś colspans (w razie potrzeby można również poprawić kod, ale mało prawdopodobne, aby tego rodzaju tabela prawdopodobnie chce tej funkcji przewijania).
JonBrave
Działa to (w pewien sposób), ale nie radzi sobie, gdy rozmiar okna jest mniejszy niż tabela (ponieważ ignoruje szerokość paska przewijania).
Gone Coding
Tak, nagłówek i komórki już się nie zgadzają, jeśli szerokość tabeli jest ograniczona do ustalonej szerokości
Craig
najlepsza odpowiedź tutaj, również najprostsza
Charles Okwuagwu
18

Tylko CSS

dla Chrome, Firefox, Edge (i innych Evergreen przeglądarek )

Po prostu position: sticky; top: 0; twoje thelementy:

/* 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: jeśli potrzebujesz granic dla elementów THth {box-shadow: 1px 1px 0 #000; border-top: 0;} , pomoże (ponieważ domyślne obramowania nie są poprawnie malowane na przewijaniu).

Dla wariantu powyższego, który wykorzystuje tylko trochę JS w celu dostosowania do IE11 zobacz tę odpowiedź https://stackoverflow.com/a/47923622/383904

Roko C. Buljan
źródło
Jeśli masz ramki dla tych elementów, użycie „border-collapse: collapse” spowoduje przyklejenie ramki do ciała zamiast do nagłówka. Aby uniknąć tego problemu, powinieneś użyć „border-collapse: oddzielnie”. Zobacz stackoverflow.com/a/53559396
mrod
@mrod podczas używania separatedodajesz olej do ognia. jsfiddle.net/RokoCB/o0zL4xyw i zobacz rozwiązanie TUTAJ: dodaj granice do ustalonego TH - nie mogę się doczekać sugestii OFC, jeśli coś przegapię
Roko C. Buljan
11

Utwórz dwie tabele jedna po drugiej, umieść drugą tabelę w div o stałej wysokości i ustaw właściwość overflow na auto. Również wszystkie td wewnątrz thead w drugim stole są puste.

<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>
Sushil Kumar
źródło
8
W takim przypadku kolumny drugiej tabeli nie mogą podążać za szerokością pierwszej tabeli.
kat1330
2
Niedobrze! Tracisz synchronizację szerokości dla kolumn w dwóch tabelach.
Zafar
1
do zakończenia tego rozwiązania musimy dodać @Hashem Qolami skrypt ( opisanego powyżej ) do kolumn nagłówka synchrinize szerokość
Elhay Avichzer
6

W końcu udało mi się to z czystym CSS, wykonując następujące instrukcje:

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

Pierwszym krokiem jest ustawienie <tbody>wyświetlania: blok, aby można było zastosować przelew i wysokość. Stamtąd <thead>należy ustawić rzędy w pozycji: krewny i display: blok, aby usiadły na przewijanym teraz <tbody>.

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

Ponieważ <thead>pozycja jest względnie ustawiona, każda komórka tabeli potrzebuje wyraźnej szerokości

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

Ale niestety to nie wystarczy. Gdy pasek przewijania jest obecny, przeglądarki przydzielają mu miejsce, dlatego w <tbody>efekcie ma mniej miejsca niż <thead>. Zwróć uwagę na niewielkie przesunięcie, które to powoduje ...

Jedynym obejściem, jakie mogłem wymyślić, było ustawienie minimalnej szerokości dla wszystkich kolumn oprócz ostatniej.

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

Cały przykład codepen poniżej:

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

EDYCJA: Alternatywne rozwiązanie dla szerokości stołu 100% (powyżej faktycznie dotyczy stałej szerokości i nie odpowiedział na pytanie):

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

Demo: http://codepen.io/anon/pen/bNJeLO

Mikael Lepistö
źródło
1
Pytanie specjalnie chciał 100% Tabela szerokość, która jest jedna rzecz, która odwołuje przykład ty nie robić.
Gone Coding
@TrueBlueAussie Dobry chwyt: D Dodano alternatywne rozwiązanie dla szerokości 100%.
Mikael Lepistö
nie uwzględnia się długości geograficznej zawartości wiersza komórki
Limon
2

Obejście css dla wymuszania poprawnego wyświetlania kolumn przy pomocy „bloku”

To rozwiązanie nadal wymaga thobliczenia i ustawienia szerokości przez 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;
}

I 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
Emmanuel
źródło
@Craig w 2019 roku, zupełnie nie przejmuj się IE.
Automagisch
2

wypróbuj poniższe podejście, bardzo proste łatwe do wdrożenia

Poniżej znajduje się link 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)
Nandha
źródło
2
To rozwiązanie nie radzi sobie z tym, że okno jest węższe niż szerokość stołu. Powinno to umożliwić przewijanie w poziomie, gdy to się stanie. Również nagłówki nie są dokładnie dopasowane do komórek danych (Chrome).
Gone Coding
Obecnie nie działa
MrHIDEn
2

Dodanie stałej szerokości do td, th po tym, jak blok wyświetlania tbody & thead działa idealnie, a także możemy użyć slimscroll wtyczki aby pasek przewijania był piękny.

wprowadź opis zdjęcia tutaj

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

codegeek
źródło
1

Oto kod, który działa dla mnie, aby stworzyć lepką teadę na stole z przewijalnym ciałem:

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;
}
Max Alexander Hanna
źródło
1

Aby użyć opcji „przepełnienie: przewiń”, należy ustawić opcję „display: block” na urządzeniu thead i tbody. I to miesza szerokości kolumn między nimi. Ale potem możesz sklonować wiersz thead za pomocą Javascript i wkleić go w tbody jako ukryty wiersz, aby zachować dokładne szerokości kolumn.

$('.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;
}
Julesezaar
źródło
0

Spróbuj tego jsfiddle . Wykorzystuje jQuery i jest odpowiedzią Hashem Qolami. Najpierw ułóż zwykły stół, a następnie przewiń.

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

};
lechat
źródło