Um bestimmte Zeilen in einer Tabelle grenzen?

120

Ich versuche, HTML / CSS zu entwerfen, mit dem bestimmte Zeilen in einer Tabelle umrandet werden können. Ja, ich weiß, dass ich eigentlich keine Tabellen für das Layout verwenden soll, aber ich kenne noch nicht genug CSS, um es vollständig zu ersetzen.

Wie auch immer, ich habe eine Tabelle mit mehreren Zeilen und Spalten, von denen einige mit Zeilenbereich und Spaltenbereich zusammengeführt sind, und ich möchte einen einfachen Rahmen um Teile der Tabelle setzen. Derzeit verwende ich 4 separate CSS-Klassen (oben, unten, links, rechts), die ich an die <td>Zellen anhänge, die sich oben, unten, links und rechts in der Tabelle befinden.

.top {
  border-top: thin solid;
  border-color: black;
}

.bottom {
  border-bottom: thin solid;
  border-color: black;
}

.left {
  border-left: thin solid;
  border-color: black;
}

.right {
  border-right: thin solid;
  border-color: black;
}
<html>

<body>

  <table cellspacing="0">
    <tr>
      <td>no border</td>
      <td>no border here either</td>
    </tr>
    <tr>
      <td class="top left">one</td>
      <td class="top right">two</td>
    </tr>
    <tr>
      <td class="bottom left">three</td>
      <td class="bottom right">four</td>
    </tr>
    <tr>
      <td colspan="2">once again no borders</td>
    </tr>
    <tr>
      <td class="top bottom left right" colspan="2">hello</td>
    </tr>
    <tr>
      <td colspan="2">world</td>
    </tr>
  </table>

</html>

Gibt es eine einfachere Möglichkeit, das zu tun, was ich will? Ich habe versucht, oben und unten auf a anzuwenden, <tr>aber es hat nicht funktioniert. (ps Ich bin neu in CSS, daher gibt es wahrscheinlich eine wirklich grundlegende Lösung dafür, die ich verpasst habe.)

Hinweis: Ich muss mehrere umrandete Abschnitte haben. Die Grundidee besteht darin, mehrere umrandete Cluster zu haben, die jeweils mehrere Zeilen enthalten.

Kyle Cronin
quelle
9
Off-Topic, aber ich wollte nur sagen, Tabellen sind perfekt geeignet und empfohlen, wenn tabellarische Daten
angezeigt

Antworten:

113

Wie wäre es tr {outline: thin solid black;}? Funktioniert für mich mit tr- oder tbody-Elementen und scheint mit den meisten Browsern kompatibel zu sein, einschließlich IE 8+, jedoch nicht zuvor.

Enigment
quelle
Ich habe darum gebeten, einen einzelnen Rand um mehrere Zeilen in einer Tabelle zu setzen und ihn im Wesentlichen visuell in mehrere Abschnitte zu unterteilen, jedoch innerhalb derselben Tabelle, damit Inhalte aus verschiedenen Abschnitten ausgerichtet werden.
Kyle Cronin
3
Verstanden, das brauchte ich auch. Schließen Sie die Reihe von Zeilen, um die Sie einen Rand haben möchten, in ihren eigenen Körper ein, und das obige CSS erstellt einen Rahmen um die Menge von ihnen - dh einen oberen Rand in der oberen Reihe, einen unteren Rand in der unteren Reihe und links und rechte Ränder an allen Zeilen im Körper. Die Ränder befinden sich nicht "auf" diesen Zeilen, sondern auf dem Umriss des Körpers selbst und versuchen nur, den Effekt zu beschreiben.
Enigment
Oh, ich verstehe, mehrere tbodys - das funktioniert und ist etwas, woran ich nicht gedacht hatte. Upvoted :)
Kyle Cronin
Ich würde vorschlagen, die css-Eigenschaft nth-child () zu verwenden, anstatt tbodys zu definieren, es sei denn, Sie haben wirklich ziemlich dynamische Daten. Mit nth-child (), nth-last-child () und not () können Sie beliebige Zeilen / Zellen auswählen (sofern Sie die relativen Indizes der Dinge in der Tabelle kennen). Zum Beispiel können Sie alle Zeilen außer den beiden oberen und unteren Zeilen mit tr: not (: n-tes Kind (-n + 2)): not (: n-tes letztes Kind (1)) auswählen
BT
1
Beachten Sie, dass die Gliederung nicht die Möglichkeit bietet , bestimmte Seiten eines Elements zu begrenzen. Es gibt zum Beispiel kein "Gliederungsoberteil". Dies ist eine begrenzte Lösung
BT
53

Vielen Dank an alle, die geantwortet haben! Ich habe alle hier vorgestellten Lösungen ausprobiert und mehr im Internet nach anderen möglichen Lösungen gesucht. Ich denke, ich habe eine gefunden, die vielversprechend ist:

tr.top td {
  border-top: thin solid black;
}

tr.bottom td {
  border-bottom: thin solid black;
}

tr.row td:first-child {
  border-left: thin solid black;
}

tr.row td:last-child {
  border-right: thin solid black;
}
<html>

<head>
</head>

<body>

  <table cellspacing="0">
    <tr>
      <td>no border</td>
      <td>no border here either</td>
    </tr>
    <tr class="top row">
      <td>one</td>
      <td>two</td>
    </tr>
    <tr class="bottom row">
      <td>three</td>
      <td>four</td>
    </tr>
    <tr>
      <td colspan="2">once again no borders</td>
    </tr>
    <tr class="top bottom row">
      <td colspan="2">hello</td>
    </tr>
    <tr>
      <td colspan="2">world</td>
    </tr>
  </table>

</body>

</html>

Ausgabe:

Geben Sie hier die Bildbeschreibung ein

Statt mit den hinzufügen top, bottom, left, und rightKlassen zu jedem <td>, alles , was ich tun muß, ist hinzuzufügen , top rownach oben <tr>, bottom rownach unten <tr>, und rowzu jedem <tr>dazwischen. Stimmt etwas mit dieser Lösung nicht? Gibt es plattformübergreifende Probleme, die mir bekannt sein sollten?

Kyle Cronin
quelle
Ich habe gerade einen Test über Browser-Shots durchgeführt und es sieht so aus, als ob der IE (alle Versionen) die Attribute für das erste und das letzte Kind nicht mag. : - /
Kyle Cronin
1
Es sieht so aus, als ob IE 7 & 8 das erste Kind unterstützen, aber keines unterstützt das letzte Kind (!) Msdn.microsoft.com/en-us/library/cc351024(VS.85).aspx
mechanisches_fleisch
Das cellspacingAttribut ist in HTML5 veraltet. CSS scheint der richtige table { border-collapse: collapse; border-spacing: 0; }Weg zu sein.
Stefan van den Akker
36

Wenn Sie den border-collapseStil für collapsedie übergeordnete Tabelle festlegen , sollten Sie in der Lage sein, Folgendes zu formatieren tr: (Stile sind für die Demo inline)

<table style="border-collapse: collapse;">
  <tr>
    <td>No Border</td>
  </tr>
  <tr style="border:2px solid #f00;">
    <td>Border</td>
  </tr>
  <tr>
    <td>No Border</td>
  </tr>
</table>

Ausgabe:

HTML-Ausgabe

Sonnenaufgang
quelle
8

Ich habe auch nur damit herumgespielt, und dies schien die beste Option für mich zu sein:

<style>
    tr { 
        display: table;            /* this makes borders/margins work */
        border: 1px solid black;
        margin: 5px;
    }
</style>

Beachten Sie, dass dies die Verwendung von fließenden / automatischen Spaltenbreiten verhindert , da die Zellen nicht mehr mit denen in anderen Zeilen ausgerichtet werden, die Formatierung von Rahmen / Farbe jedoch weiterhin in Ordnung ist. Die Lösung besteht darin , den TRs und TDs eine bestimmte Breite (entweder px oder%) zu geben.

Natürlich können Sie den Selektor erstellen, tr.myClasswenn Sie ihn nur auf bestimmte Zeilen anwenden möchten. Anscheinend display: tablefunktioniert es nicht für IE 6/7, aber es gibt wahrscheinlich andere Hacks (hasLayout?), Die für diese funktionieren könnten. :-(

Simon East
quelle
6
Diese Lösung ist falsch: "display: table" fügt die gesamte Zeile in eine Tabellenzelle ein - Sie verlieren die Formatierung in Bezug auf die anderen Zeilen der Tabelle. Ich habe dies in Firefox und Chromium versucht.
Yaakov Belch
Yaakov, ich denke, Sie beziehen sich darauf, dass flüssige Spaltenbreiten nicht mehr mit anderen Zeilen in der Tabelle übereinstimmen (wie in dieser Geige gezeigt: jsfiddle.net/MrKtw ), aber die Rand- / Farbformatierung funktioniert immer noch in Ordnung. Die Lösung besteht darin, den TRs und TDs eine bestimmte Breite (entweder px oder%) zu geben.
Simon East
Simon, um zu zeigen, was ich meine, habe ich deine Geige gegabelt und geändert. Schauen Sie sich das an: jsfiddle.net/a6DZV --- Ich wende die Formatierung "display: table" nur auf eine Zeile an. Wie Sie sehen, wird diese Zeile effektiv zu einer Zelle der Tabelle. Mit anderen Worten: Sie erhalten dieselbe Ausgabe wie das Verschachteln einzeiliger Tabellen in einer Zelle einer anderen Tabelle (und das Anzeigen des Rahmens dieser inneren Tabelle). Ihre Lösung speichert einige Knoten im DOM, ist jedoch nicht so kompatibel.
Yaakov Belch
3

Hier ist ein Ansatz, bei dem tbody-Elemente verwendet werden, um dies zu erreichen. Sie können den Rand nicht für einen Körper festlegen (genauso wie für einen Tr), aber Sie können die Hintergrundfarbe festlegen. Wenn der Effekt, den Sie erzielen möchten, mit einer Hintergrundfarbe für die Zeilengruppen anstelle eines Rahmens erzielt werden kann, funktioniert dies.

<table cellspacing="0">  
    <tbody>
        <tr>    
            <td>no border</td>    
            <td>no border here either</td>  
        </tr>  
    <tbody bgcolor="gray">
        <tr>    
            <td>one</td>    
            <td>two</td>  
        </tr>  
        <tr>    
            <td>three</td>    
            <td>four</td>  
        </tr>  
    <tbody>
        <tr>    
             <td colspan="2">once again no borders</td>  
        </tr>  
    <tbody bgcolor="gray">
        <tr>    
             <td colspan="2">hello</td>  
        </tr>
    <tbody>
    <tr>    
         <td colspan="2">world</td>  
    </tr>
</table>
sipwiz
quelle
2

Gruppieren Sie Zeilen mithilfe des <tbody>Tags und wenden Sie dann den Stil an.

<table>
  <tr><td>No Style here</td></tr>
  <tbody class="red-outline">
    <tr><td>Style me</td></tr>
    <tr><td>And me</td></tr>
  </tbody>
  <tr><td>No Style here</td></tr>
</table>  

Und das CSS in style.css

.red-outline {
  outline: 1px solid red;
}
csi
quelle
1

Die einzige andere Möglichkeit, die ich mir vorstellen kann, besteht darin, jede der Zeilen, um die Sie einen Rand benötigen, in eine verschachtelte Tabelle einzuschließen. Dies erleichtert die Erstellung des Rahmens, führt jedoch möglicherweise zu anderen Layoutproblemen. Sie müssen die Breite für Tabellenzellen usw. manuell festlegen.

Abhängig von Ihren anderen Layoutanforderungen ist Ihr Ansatz möglicherweise der beste, und der hier vorgeschlagene Ansatz ist nur eine mögliche Alternative.

<table cellspacing="0">  
    <tr>    
        <td>no border</td>    
        <td>no border here either</td>  
    </tr>  
    <tr>
        <td>
             <table style="border: thin solid black">
                  <tr>    
                        <td>one</td>    
                        <td>two</td>  
                  </tr>  
                  <tr>    
                      <td>three</td>    
                      <td>four</td>  
                  </tr>  
             </table>
         </td>
    </tr>
    <tr>    
         <td colspan="2">once again no borders</td>  
    </tr>  
    <tr>
        <td>
             <table style="border: thin solid black">
                  <tr>    
                        <td>hello</td>  
                   </tr>
             </table>
         </td>
    </tr>
    <tr>    
         <td colspan="2">world</td>  
    </tr>
</table>
sipwiz
quelle
Danke für deine Antwort; Sie haben jedoch Recht mit den Layoutproblemen - ich würde es vorziehen, wenn Spalten ohne manuelle Ausführung in einer Reihe angeordnet werden. Was ist mit dem Anwenden einer Klasse auf ein <tr> -Tag - ist das möglich?
Kyle Cronin
Wenn Sie eine Tabelle mit "Tabellenlayout: fest" verwenden und die Breite jeder Spalte explizit festlegen (indem Sie <col> verwenden oder nur die Breite der Zellen in der ersten Zeile festlegen), werden die Spalten unabhängig vom Inhalt ausgerichtet. Sie müssen die Tabellen nicht einmal verschachteln, drei separate Tabellen würden das Beispiel gut machen.
Bobince
1

Basierend auf Ihrer Anforderung, dass Sie einen Rand um einen beliebigen Block von MxN-Zellen setzen möchten, gibt es wirklich keinen einfacheren Weg, dies ohne Verwendung von Javascript zu tun. Wenn Ihre Zellen mit fixiert sind, können Sie Floats verwenden, dies ist jedoch aus anderen Gründen problematisch. Was Sie tun, mag langweilig sein, aber es ist in Ordnung.

Ok, wenn Sie an einer Javascript-Lösung mit jQuery (meinem bevorzugten Ansatz) interessiert sind, erhalten Sie diesen ziemlich beängstigenden Code:

<html>
<head>

<style type="text/css">
td.top { border-top: thin solid black; }
td.bottom { border-bottom: thin solid black; }
td.left { border-left: thin solid black; }
td.right { border-right: thin solid black; }
</style>
<script type="text/javascript" src="jquery-1.3.1.js"></script>
<script type="text/javascript">
$(function() {
  box(2, 1, 2, 2);
});

function box(row, col, height, width) {
  if (typeof height == 'undefined') {
    height = 1;
  }
  if (typeof width == 'undefined') {
    width = 1;
  }
  $("table").each(function() {
    $("tr:nth-child(" + row + ")", this).children().slice(col - 1, col + width - 1).addClass("top");
    $("tr:nth-child(" + (row + height - 1) + ")", this).children().slice(col - 1, col + width - 1).addClass("bottom");
    $("tr", this).slice(row - 1, row + height - 1).each(function() {
      $(":nth-child(" + col + ")", this).addClass("left");
      $(":nth-child(" + (col + width - 1) + ")", this).addClass("right");
    });
  });
}
</script>
</head>
<body>

<table cellspacing="0">
  <tr>
    <td>no border</td>
    <td>no border here either</td>
  </tr>
  <tr>
    <td>one</td>
    <td>two</td>
  </tr>
  <tr>
    <td>three</td>
    <td>four</td>
  </tr>
  <tr>
    <td colspan="2">once again no borders</td>
  </tr>
</tfoot>
</table>
</html>

Ich nehme gerne Vorschläge zu einfacheren Möglichkeiten an ...

Cletus
quelle
1
Scheint, als würden Sie nur Klassen zu den td-Tags hinzufügen? Warum konnte dies nicht mit einem serverseitigen Skript durchgeführt werden, das statisch generiert wurde, oder im schlimmsten Fall nur von Hand? Sieht für mich nach JavaScript-Missbrauch aus.
Thomas
3
Eigentlich fragte das Poster nach einer Javascript-Lösung. Sie können nicht sagen, dass es sich um Javascript-Missbrauch handelt, da nicht genügend Informationen vorhanden sind. Werden die Rahmen beispielsweise hinzugefügt, weil der Benutzer darauf klickt? Wenn ja, ist eine Serverlösung falsch.
Cletus
Entschuldigung für den Mangel an Informationen. Dies wird serverseitig generiert, daher kann ich die Klassen zwar manuell hinzufügen, aber mir gefällt, wie die JS-Lösung eine einfachere Schnittstelle bietet. Also, obwohl ich wahrscheinlich nicht mit dem JS gehen werde, ist es eine gute Lösung zu sehen.
Kyle Cronin
0

Der Trick liegt in der Gliederungseigenschaft dank der Antwort von Enigment mit nur geringen Änderungen

Verwenden Sie diese Klasse

.row-border{
    outline: thin solid black;
    outline-offset: -1px;
}

dann im HTML

<tr>....</tr>
<tr class="row-border">
    <td>...</td>
    <td>...</td>
</tr>

und das Ergebnis ist Geben Sie hier die Bildbeschreibung ein Hoffnung, dass dies Ihnen hilft

Basheer AL-MOMANI
quelle
-5

Eine einfachere Möglichkeit besteht darin, die Tabelle zu einem serverseitigen Steuerelement zu machen. Sie könnten etwas Ähnliches verwenden:

Dim x As Integer
table1.Border = "1"

'Change the first 10 rows to have a black border
 For x = 1 To 10
     table1.Rows(x).BorderColor = "Black"
 Next

'Change the rest of the rows to white
 For x = 11 To 22
     table1.Rows(x).BorderColor = "White"
 Next
Curtis
quelle
1
OP bittet um einen einfacheren Weg, dies zu tun
Orique
2
Seien Sie vorsichtig, OP bittet auch um eine einfachere Möglichkeit, dies in HTML / CSS zu tun. Ich sehe nirgendwo in seiner Frage das VB- oder VBA-Schlüsselwort. Ich schlage vor, Sie schauen in unseren Hilfebereich : stackoverflow.com/help/how-to-answer Viel Glück.
ForceMagic