So legen Sie den Abstand zwischen TBODY-Elementen fest

95

Ich habe einen Tisch wie diesen:

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

Ich möchte einen gewissen Abstand zwischen die einzelnen Elemente setzen, aber Polsterung und Rand haben keine Auswirkung. Irgendwelche Ideen?

nickf
quelle
Ist es richtig, "tbody" -Tags zu wiederholen? Was ich immer gesehen habe, ist, dass sich alle "<tr> .. </ tr>" in einem einzigen "tbody" -Tag befinden.
Saneef
23
Ja das ist gültig. Die Spezifikation sagt: <! ELEMENT TABLE - - (CAPTION?, (COL * | COLGROUP *), THEAD?, TFOOT?, TBODY +)> was bedeutet, dass es einen oder mehrere Körper geben muss. w3.org/TR/html4/struct/tables.html#h-11.2.1
nickf

Antworten:

56

Versuchen Sie dies, wenn es Ihnen nichts ausmacht, keine Grenzen zu haben.

<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
quelle
7
Versuchen Sie es mit Rand oben: 15px fest transparent;
Steve Almond
3
Wollte das betonen. Verwenden Sie transparentals die Rahmenfarbe. Was @SteveAlmond gesagt hat.
Iheartcsharp
Wenn die Tabelle / tbody / tr / td eine Hintergrundfarbe hat, erhalten Sie durch Festlegen der transparentRahmenfarbe die Hintergrundfarbe des Elements, die im Wesentlichen vom Körper des Elements zu unterscheiden ist. Sie müssten den Rand explizit so färben, wie er erscheinen soll (um ihn angeblich unsichtbar zu machen)
Guy Passy
81

So etwas funktioniert abhängig von den Anforderungen Ihres Browser-Supports:

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

}
MacNimble
quelle
1
Dies ist die einzige Lösung, die funktioniert, wenn Ihre Zellen einen Hintergrund haben, den der Speicherplatz nicht haben sollte.
Laradda
Das hat bei mir gut funktioniert. Gibt es irgendwelche Nachteile? Warum auch zwei Doppelpunkte?
nh2
Tolle Lösung. Hält alles zugänglich!
Jason T Featheringham
1
@ nh2: Doppelpunkt steht für Pseudoinhalt und Einzelpunkt für Pseudoselektoren. Es ist ein Update der CSS-Syntax. Früher wurde nur der Doppelpunkt verwendet. Ältere Browser unterstützen keinen Doppelpunkt (z. B. IE <= 8).
Dbmikus
3
Ist es nicht sicherer zu benutzen display: table-row;?
Rachel
20

Die Leute werden immer kontroverse Meinungen über die Verwendung leerer Tabellenelemente zum Layout einer Seite haben (wie aus der Abwertung dieser Antwort hervorgeht). Ich erkenne das, aber manchmal ist es einfacher, sie so zu verwenden, wenn Sie " schnell und schmutzig " arbeiten.

Ich habe in früheren Projekten leere Zeilen verwendet, um Gruppen von Tabellenzeilen zu platzieren. Ich habe den Spacer-Zeilen eine eigene CSS-Klasse zugewiesen und eine Höhe für diese Klasse definiert, die als oberer und unterer Rand für diese Gruppe von Tabellenzeilen fungiert.

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

Wenn Ihre Tabellenzellen keine Ränder haben, können Sie auch eine Höhe für Ihre typische Zelle oder Zeile in Ihrem Stylesheet definieren, die alle Zeilen Ihrer Tabelle gleichmäßig verteilt.

tr{
   height: 40px;
}
kevtrout
quelle
Nun, wenn Sie zusätzliches Markup hinzufügen möchten, warum nicht einfach eine Klasse in die erste Reihe jedes Tbody setzen?
Nickf
Dies kann daran liegen, dass die Zeilen generierter Code sind und das Hinzufügen einer separaten Zeile im Markup möglicherweise besser zu warten ist als das Erstellen eines Sonderfalls für die erste Zeile des generierten Inhalts.
Rolf Rander
12
Stimmen Sie alles ab, was Sie wollen, aber dies ist die einzige Lösung ohne Nachteile - und selbst wenn sie die Trennung verletzt, ist eine leere Zeile IMO keine so große Sache.
Xkeeper
11
Ohne Nachteile, mein Hintern! Versuchen Sie es mit einem Screenreader und stellen Sie fest, dass die Anzahl der Zeilen falsch ist. Besser noch, versuchen Sie, die Tabelle zu kopieren und in eine Tabelle einzufügen. Sie werden stundenlang neu formatieren, wenn Sie viel Inhalt haben. Tabellen sollen Daten anzeigen (und extrem zugänglich sein) und keine Shim-Darstellung zwischen Abschnitten.
Jason T Featheringham
Es ist nur visuell. Beachten Sie, dass HTML auch Dokumente sind, die verarbeitet werden können. Daher sollten die darin enthaltenen Inhalte gut formatiert sein. Wie oben erwähnt, schlägt das Kopieren und Einfügen einer Tabelle oder die Verwendung des Bildschirmlesegeräts einfach fehl. Ein solches Design sollte nicht gefördert werden. :: content solution ist besser, weil es das Markup nicht durcheinander bringt.
Pawel-Kuznik
12

Ich hatte Probleme, <tbody>mit ::beforePseudo richtig mehrere Abstände einzuhalten <tr>, da <td>ich in einigen Browsern mit Rowspan enthalten war .

Grundsätzlich, wenn Sie eine <tbody>solche Struktur haben:

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

Und Sie folgen, wer rät, CSS auf ::beforePseudo-Element wie dieses zu schreiben :

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

Dies wirkt sich auf den Zeilenbereich aus und führt dazu, dass die Tabelle innerhalb des zweiten Bereichs "verliert", <tr>wie viele <td>Zeilenbereiche im ersten vorhanden sind.

Wenn also jemand auf diese Art von Problem stößt, besteht die Lösung darin, ::beforePseudo folgendermaßen zu formatieren:

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

Hier ist eine Geige

Nineoclick
quelle
6

Hier ist eine weitere Möglichkeit, die sich auf Folgendes stützt: Erstes Kind, das nicht in allen Browsern verfügbar ist:

<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
quelle
3
Dieser funktioniert nicht sehr gut, wenn Sie etwas haben, das von der Position des Inhalts im Verhältnis zur Größe der Zelle abhängt, wie Kastenschatten, Hintergrundbilder oder so ziemlich alles andere.
Xkeeper
1
Um zu verdeutlichen, dass andere diese Antwort auf Google finden, nehme ich an, dass diese Antwort jetzt (2015) in allen gängigen Browsern voll unterstützt wird, da sie 2008 geschrieben wurde. Zumindest scheint die Überprüfung des ersten Kindes auf caniuse.com gut unterstützt zu sein?
Redfox05
6

Einfach einstellen displayals blockund es wird funktionieren.

table tbody{
    display:block;
    margin-bottom:10px;
    border-radius: 5px;
}
user007
quelle
1
Diese Antwort sollte die akzeptierte Antwort sein, da sie die einzige ist, die die Verwendung eines umrandeten Körpers mit "no-border" -Spalten erlaubt.
Robsonrosa
13
display:blockUnterbricht die Spaltenausrichtung zwischen zwei Elementen. Sie profitieren nicht mehr von der Tabellenlayout-Engine
M Conrad
4

Von allen oben gegebenen Antworten behalten nur die Antworten von djenson47 die Trennung von Präsentation und Inhalt bei . Der Nachteil der kollabierten Grenze Modell Methode ist , dass Sie nicht mehr die Tabellen verwenden Grenze oder Cellspacing Attribute die einzelnen Zellen zu trennen. Sie könnten argumentieren, dass dies eine gute Sache ist und es einige Problemumgehungen gibt, aber es kann ein Schmerz sein. Also ich denke das erste Kind Methode die eleganteste ist.

Alternativ können Sie auch die Überlaufeigenschaft Ihrer TBODY-Klasse auf etwas anderes als "sichtbar" setzen. Mit dieser Methode können Sie auch ein Modell mit getrennten Rändern beibehalten:

<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
quelle
Ich wollte etwas Ähnliches tun, das ist perfekt für mich
Eruant
4

Da das Auffüllen auf TDs angewendet werden kann, können Sie einen Trick mit dem + -Zeichen ausführen. Dann ist es möglich, den TDs des ersten TR eines Körpers eine obere Polsterung zu geben:

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

Ich habe "tbody + tbody" hinzugefügt, damit der erste tbody keine obere Polsterung hat. Es ist jedoch nicht erforderlich.

Soweit ich weiß gibt es keine Nachteile :), habe aber die älteren Browser nicht getestet.

Maarten
quelle
2

Sie können border-spacingin einer Tabelle mit Tabellenzeilengruppen ein Leerzeichen zwischen diesen Gruppen hinzufügen. Ich glaube jedoch nicht, dass es eine Möglichkeit gibt, anzugeben, welche Gruppen voneinander beabstandet sind und welche nicht.

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

CSS

table {
  border-spacing: 0px 10px; /* h-spacing v-spacing */
}
OdraEncoded
quelle
0

NEUE ANTWORT

Sie können beliebig viele <tbody>Tags verwenden. Ich wusste bis jetzt nicht, dass W3C das in Ordnung war. Um nicht zu sagen, dass meine unten stehende Lösung nicht funktioniert (es funktioniert), aber um das zu tun, was Sie versuchen, weisen Sie Ihre <tbody>Tag-Klassen zu und verweisen Sie dann <td>über CSS wie folgt auf ihre einzelnen Tags:

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

und dein HTML also:

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

Probieren Sie diesen Kerl aus :)

ALTE ANTWORT

Was auch immer Sie tun, fügen Sie KEINE leeren Zeilen ein ...

Sie sollten nicht mehr als 1 tbody-Element in Ihrer Tabelle haben. Sie können das Klassen- oder ID-Attribut in Ihren <tr>Elementen festlegen und die entsprechenden <td>Tags auffüllen:

table {
    border-collapse: collapse;
}

tr.yourClass td {
    padding: 10px;
}

Sie können den oberen und unteren sogar <tr>eine zusätzliche Klasse zuweisen, sodass sie nur die oberen bzw. unteren Polster ausführen:

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

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

und in Ihrem HTML <tr>würde Ihr Tag so aussehen:

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

Hoffe das hilft!

Jason
quelle
0

Die Antwort von djensen47 funktioniert hervorragend für neuere Browser. Wie bereits erwähnt, funktioniert IE7 jedoch nicht.

Meine Problemumgehung für dieses Problem zur Unterstützung der älteren Browser bestand darin, den Inhalt jeder Zelle in ein div zu packen. Fügen Sie dann dem Div einen Rand nach oben hinzu.

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

Die Höheneinstellung hält die Zellen mindestens 30 Pixel hoch, um zu verhindern, dass die im div verwendeten Zellenfarben um den Text herum kollabieren. Der Rand oben schafft den gewünschten Platz, indem die gesamte Reihe höher gemacht wird.

Jereme Günther
quelle
0

Kam darüber hinweg, als ich versuchte, es selbst zu lösen. Ich hatte Erfolg damit, ein <br>Tag direkt vor das schließende </tbody>Tag zu setzen. Es ist eine rein visuelle Lösung, scheint aber auf den meisten von mir getesteten Browsern zu funktionieren.

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

Sollte auch zugänglich sein.

Ian
quelle