Jak umieścić odstępy między elementami TBODY

99

Mam taki stół:

<table>
    <tfoot>
        <tr><td>footer</td></tr>
    </tfoot>
    <tbody>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
    </tbody>
</table>

Chciałbym umieścić odstępy między każdym elementem tbody, ale dopełnienie i marginesy nie mają wpływu. Jakieś pomysły?

nickf
źródło
Czy warto powtarzać tagi „tbody”? Zawsze widziałem, że wszystkie „<tr> .. </tr>” znajdują się w jednym tagu „tbody”.
Saneef
25
Tak, to jest ważne. Specyfikacja mówi: <! ELEMENT TABLE - - (CAPTION ?, (COL * | COLGROUP *), THEAD ?, TFOOT ?, TBODY +)>, co oznacza, że ​​musi istnieć co najmniej jedno ciało. w3.org/TR/html4/struct/tables.html#h-11.2.1
nickf

Odpowiedzi:

58

Spróbuj tego, jeśli nie masz nic przeciwko temu, by nie mieć granic.

<style>
table {
  border-collapse: collapse;
}

table tbody {
  border-top: 15px solid white;
}
</style>

<table>
    <tfoot>
        <tr><td>footer</td></tr>
    </tfoot>
    <tbody>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
    </tbody>
</table>
Dave Jensen
źródło
8
Wypróbuj border-top: jednolita przezroczystość 15 pikseli;
Steve Almond
3
Chciałem to podkreślić. Użyj transparentjako koloru obramowania. Co powiedział @SteveAlmond.
iheartcsharp
jeśli tabela / tbody / tr / td ma kolor tła, ustawienie koloru obramowania na transparentnada mu kolor tła elementu, zasadniczo nieodróżnialny od treści elementu. Musiałbyś wyraźnie pokolorować obramowanie na kolor, w jakim ma się pojawiać (aby było rzekomo niewidoczne)
Guy Passy
83

Coś takiego zadziała, w zależności od wymagań dotyczących obsługi przeglądarki:

tbody::before
{
  content: '';
  display: block;
  height: 15px;

}
MacNimble
źródło
1
To jedyne rozwiązanie, które działa, gdy twoje komórki mają tło, którego przestrzeń nie powinna mieć.
Laradda
To działało dobrze dla mnie. Czy są jakieś wady? Poza tym, dlaczego dwa dwukropki?
nh2
Świetne rozwiązanie. Wszystko jest dostępne!
Jason T Featheringham
1
@ nh2: dwukropki oznaczają pseudo-zawartość, a dwukropek - pseudoselektory. To aktualizacja składni CSS. Wszystko zwykło używać tylko jednego dwukropka. Starsze przeglądarki nie obsługują podwójnego dwukropka (np. IE <= 8).
dbmikus
3
Czy nie jest to bezpieczniejsze w użyciu display: table-row;?
rachel
20

Ludzie zawsze będą mieć kontrowersyjne opinie na temat używania pustych elementów tabeli do układu strony (o czym świadczy negatywna opinia). Rozumiem to, ale czasami łatwiej jest z nich korzystać w ten sposób, gdy pracujesz w „ szybki i brudny ” sposób.

Używałem pustych wierszy w poprzednich projektach, aby rozmieścić grupy wierszy tabeli. Przypisałem odstępom wierszom własną klasę css i zdefiniowałem wysokość dla tej klasy, która działała jako górny i dolny margines dla tej grupy wierszy tabeli.

    .separator{
             height: 50px;
    }

   <table>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>

           <tr class="separator" colspan="2"></tr>

           <tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>

           <tr class="separator" colspan="2"></tr>

           tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>
   </table>

Jeśli nie masz obramowań na komórkach tabeli, możesz również zdefiniować wysokość typowej komórki lub wiersza w arkuszu stylów, aby równomiernie rozdzielić wszystkie wiersze tabeli.

tr{
   height: 40px;
}
kevtrout
źródło
cóż, jeśli zamierzasz dodawać dodatkowe znaczniki, dlaczego po prostu nie umieścić klasy w pierwszym rzędzie każdego elementu?
nickf
Cóż, może to być spowodowane tym, że wiersze są generowanym kodem, a dodanie oddzielnego wiersza w znaczniku może być łatwiejsze w utrzymaniu niż utworzenie specjalnego przypadku dla pierwszego wiersza wygenerowanej treści.
Rolf Rander
12
Głosuj w dół, ile chcesz, ale to jedyne rozwiązanie bez wad - a nawet jeśli narusza separację, pusty wiersz nie jest tak wielkim problemem IMO.
Xkeeper
11
Bez wad mój tyłek! Spróbuj użyć do tego czytnika ekranu i zwróć uwagę na nieprawidłowe liczby wierszy. Jeszcze lepiej, spróbuj skopiować i wkleić tabelę do arkusza kalkulacyjnego. Jeśli masz dużo treści, będziesz formatować przez wiele godzin. Tabele służą do wyświetlania danych (i są niezwykle dostępne), a nie do umieszczania między sekcjami.
Jason T Featheringham
To tylko wizualne. Należy pamiętać, że html to także dokumenty, które można przetwarzać, dlatego zawartość w nich zawarta powinna być dobrze sformatowana. Jak wspomniano powyżej, kopiowanie i wklejanie tabeli lub użycie czytnika ekranu po prostu się nie powiedzie. Nie należy zachęcać do takiego projektu. :: rozwiązanie content jest lepsze, ponieważ nie psuje znaczników.
pawel-kuznik
12

Miałem problem z poprawnym rozstawieniem wielu <tbody>z ::beforepseudo, w obecności <tr>zawierania <td>z rowspan w kilku przeglądarkach.

Zasadniczo, jeśli masz taką <tbody>strukturę:

<tbody>
    <tr>
        <td>td 1</td>
        <td rowspan"2">td 2</td>
        <td>td 3</td>
        <td>td 4</td>
    </tr>
    <tr>
        <td>td 1</td>
        <td>td 2</td>
        <td>td 4</td>
    </tr>
</tbody>

I obserwujesz, kto radzi pisać css na ::beforepseudo elemencie w ten sposób:

tbody::before
{
    content: '';
    display: block;
    height: 10px;
}

Wpłynie to na rozpiętość wierszy, sprawiając, że tabela „traci” w ciągu sekundy <tr>liczbę <td>-rowspan obecnych w pierwszej.

Jeśli więc ktoś napotka taki problem, rozwiązaniem jest stylizacja ::beforepseudo w następujący sposób:

tbody::before
{
    content: '';
    display: table-row;
    height: 10px;
}

Oto skrzypce

Nineoclick
źródło
6

Oto kolejna możliwość, która polega na: first-child, która nie jest dostępna we wszystkich przeglądarkach:

<style>
table {
  border-collapse: collapse;
}

td {
  border: 1px solid black;
}

tbody tr:first-child td {
  padding-top: 15px;
}

</style>

<table>
    <tfoot>
        <tr><td>footer</td></tr>
    </tfoot>
    <tbody>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
    </tbody>
</table>
Dave Jensen
źródło
3
Ten nie będzie działał zbyt dobrze, jeśli masz coś, co zależy od pozycji zawartości w stosunku do rozmiaru komórki, na przykład cienie pola, obrazy tła lub prawie wszystko inne.
Xkeeper
1
Aby wyjaśnić innym, którzy znaleźli tę odpowiedź w Google, zakładam, że skoro została napisana w 2008 roku, ta odpowiedź teraz (2015) ma pełne wsparcie we wszystkich głównych przeglądarkach? Przynajmniej sprawdzenie na caniuse.com first-child wydaje się być dobrze obsługiwane?
redfox05
6

Po prostu ustaw displayjako blocki będzie działać.

table tbody{
    display:block;
    margin-bottom:10px;
    border-radius: 5px;
}
user007
źródło
1
ta odpowiedź powinna być akceptowaną odpowiedzią, ponieważ jest jedyną, która pozwala na użycie obramowanego ciała z kolumnami „bez obramowania”.
robsonrosa
13
display:blockprzerywa wyrównanie kolumn między elementami tbody. Nie masz już korzyści z silnika układu tabeli
M Conrad
4

Ze wszystkich odpowiedzi udzielonych powyżej, tylko odpowiedzi djensona47 zachowują oddzielenie prezentacji i treści . Wadą metody modelu zwiniętego obramowania jest to, że nie można już używać atrybutów obramowania tabeli lub odstępów między komórkami do oddzielania poszczególnych komórek. Możesz argumentować, że to dobra rzecz i istnieją pewne obejścia, ale może to być uciążliwe. Myślę więc, że metoda pierwszego dziecka jest najbardziej elegancka.

Alternatywnie możesz również ustawić właściwość przepełnienia klasy TBODY na wartość inną niż „widoczne”. Ta metoda pozwala również zachować model oddzielnych granic:

<style>
tbody {
    overflow: auto;
    border-top: 1px solid transparent;
}
</style>
<table>
    <tfoot>
        <tr><td>footer</td></tr>
    </tfoot>
    <tbody>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
    </tbody>
</table>
Calvin
źródło
Szukałem czegoś podobnego, to jest dla mnie idealne
Eruant
4

Ponieważ do TD można zastosować dopełnienie, możesz zrobić sztuczkę ze znakiem +. Wtedy będzie możliwe nadanie górnego wypełnienia TD's pierwszego TR z ciała:

// The first row will have a top padding
table tbody + tbody tr td {
    padding-top: 20px;
}

// The rest of the rows should not have a padding
table tbody + tbody tr + tr td {
    padding-top: 0px;
}

Dodałem „tbody + tbody”, więc pierwsze ciało nie będzie miało górnego wypełnienia. Jednak nie jest to wymagane.

O ile wiem nie ma żadnych wad :), choć nie testowałem starszych przeglądarek.

Maarten
źródło
2

Możesz użyć border-spacingw tabeli z grupami wierszy tabeli, aby dodać spację między tymi grupami. Chociaż nie sądzę, aby można było określić, które grupy są rozmieszczone, a które nie.

<table>
  <thead>
    ...
  </head>
  <tbody>
    ...
  </tbody>
  <tbody>
    ...
  </tbody>
  <tfoot>
    ...
  </tfoot>
</table>

CSS

table {
  border-spacing: 0px 10px; /* h-spacing v-spacing */
}
OdraEncoded
źródło
0

NOWA ODPOWIEDŹ

Możesz użyć <tbody>dowolnej liczby tagów. Do tej pory nie zdawałem sobie sprawy, że W3C jest w porządku. Nie znaczy to, że moje poniższe rozwiązanie nie działa (działa), ale aby zrobić to, co próbujesz zrobić, przypisz <tbody>klasy tagów, a następnie odwołaj się do ich poszczególnych <td>tagów za pomocą CSS w następujący sposób:

table tbody.yourClass td {
    padding: 10px;
}

a więc twój HTML:

<table> 
<tbody>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</tbody>
<tbody class="yourClass">    
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</tbody>
<tbody>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</tbody>
</table>

Wypróbuj tego gościa :)

STARA ODPOWIEDŹ

cokolwiek robisz, NIE wstawiaj pustych wierszy ...

nie powinieneś mieć więcej niż 1 element tbody w swojej tabeli. co możesz zrobić, to ustawić atrybut class lub id w swoich <tr>elementach i <td>uzupełnić odpowiednie tagi:

table {
    border-collapse: collapse;
}

tr.yourClass td {
    padding: 10px;
}

Możesz nawet przypisać górną i dolną <tr>dodatkową klasę, tak aby wykonywały odpowiednio tylko górne lub dolne wypełnienie:

tr.yourClass.topClass td {
    padding: 10px 0 0 0;
}

tr.yourClass.bottomClass td {
    padding: 0 0 10px 0;
}

a w kodzie HTML <tr>tag wyglądałby tak:

<table> 
<tbody>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr class="yourClass topClass"><td>Text</td></tr>
<tr class="yourClass"><td>Text</td></tr>
<tr class="yourClass bottomClass"><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</tbody>
</table>

Mam nadzieję że to pomoże!

Jason
źródło
0

Odpowiedź djensen47 działa świetnie w nowszych przeglądarkach, jednak, jak wskazano, w IE7 nie działa.

Moim obejściem tego problemu w celu obsługi starszych przeglądarek było zawijanie zawartości każdej komórki do elementu div. Następnie dodaj górną część marginesu do elementu div.

<table class="tbl">
<tr></tr>
<tr></tr>
<tr></tr>
<tr><td><div></div></td></tr>
</table>

CSS

.tbl tr td div {
    height:30px;
    margin-top:20px;
}

Ustawienie wysokości utrzymuje komórki o wysokości co najmniej 30 pikseli, aby zapobiec zawijaniu się kolorów komórek w elemencie div wokół tekstu. Górny margines tworzy żądaną przestrzeń, zwiększając cały rząd.

Jereme Guenther
źródło
0

Przeszedłem przez to, próbując rozwiązać go samodzielnie. Udało mi się umieścić <br>tag tuż przed </tbody>tagiem zamykającym . Jest to poprawka czysto wizualna, ale wydaje się, że działa w większości testowanych przeglądarek.

<table>
    <tbody>
        <tr>
            <td></td>
        </tr>
        <br>
    </tbody>
    <tbody>
        <tr>
            <td></td>
        </tr>
    </tbody>
</table>

Powinien być również dostępny.

Ian
źródło
0

Z uznaniem dla wszystkich, którzy odpowiedzieli jako pierwsi ...

table {
  border-collapse: collapse;
  table-layout: fixed;
  width: 50%;
}
tbody:before {
  content: "";
  display:block;
  border-top: 15px solid white;
}
tbody tr {
  border-color: #000;
  border-style: solid;
}
tbody tr:first-of-type{
  border-width: 2px 2px 0 2px;
}
tbody tr:nth-of-type(1n+2){
  border-width: 0 2px 0 2px;
}
tbody tr:last-of-type{
  border-width: 0 2px 2px 2px;
}
tbody tr:nth-child(odd) {
  background-color: #ccc;
}
tbody tr:hover {
  background-color: #eee;
}
td {
  text-align: right;
}
<table>
  <tbody>
    <tr>
      <th colspan="3">One</th>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
  </tbody>
  <tbody>
    <tr>
      <th colspan="3">Two</th>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
  </tbody>
</table>

user2182349
źródło