Ich weiß nicht, warum mein Rahmenstil nicht mit position: sticky;
Attributen funktioniert . Ich möchte Rahmenstile für meine klebrige Tabellenüberschrift festlegen. Aber ich möchte nicht die transparente Hintergrundfarbe verwenden. Wie kann ich das erreichen? Hier sind Beispielcodes für mein Problem und JSFiddle Link
#wrapper {
width: 400px;
height: 200px;
overflow: auto;
}
table {
width: 100%;
text-align: center;
border-collapse: collapse;
}
table tr th,
table tr td {
border: 2px solid;
}
table thead th {
position: -webkit-sticky;
position: sticky;
top: 0;
background-color: #edecec;
}
<div id="wrapper">
<table>
<thead>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
<th>E</th>
</tr>
</thead>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>2</td>
<td>2</td>
<td>2</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>3</td>
<td>3</td>
<td>3</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>4</td>
<td>4</td>
<td>4</td>
<td>4</td>
</tr>
<tr>
<td>5</td>
<td>5</td>
<td>5</td>
<td>5</td>
<td>5</td>
</tr>
<tr>
<td>6</td>
<td>6</td>
<td>6</td>
<td>6</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>7</td>
<td>7</td>
<td>7</td>
<td>7</td>
</tr>
<tr>
<td>8</td>
<td>8</td>
<td>8</td>
<td>8</td>
<td>8</td>
</tr>
<tr>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
<tbody>
</tbody>
</table>
</div>
Unten sind Screenshots für das, was ich will und wer meine Frage nicht klar genug stellt.
Sie können sehen, dass Inline- Rahmenstile von th
nicht funktionieren ( entfernen Sie das position
Attribut von CSS und Sie werden Boder sehen. ).
Nach ein wenig nach unten scrollen. Sie werden sehen, dass alle Rahmenstile verschwunden sind.
table tr th, table tr td
Selektor angegeben. Die Syntax sollte wie folgt lautenborder: <unit> <border-style> <color>
<color>
Teil ist nicht heilend. Standard ist#000000
AFAIK.Antworten:
Das Problem tritt aufgrund der Verwendung von auf
border-collapse: collapse
. Wenn Browser die Ränder reduzieren, müssen der obere und der untere Rand des<th>
Rahmens auf die umgebenden Elemente angewendet werden - der obere Rand des<table>
und der untere Rand des Folgenden<tr>
.Wenn Sie
border-collapse: separate
Ihre Ränder verwenden und gestalten, um auf einer Seite zu sitzen, werden die Ränder wirklich mit dem verbunden<th>
, bleiben wie erwartet fixiert und erscheinen kollabiert.Hier sind Beispielstile, die auf Ihr HTML-Snippet angewendet werden können.
#wrapper { width: 400px; height: 200px; overflow: auto; } table { width: 100%; text-align: center; border-collapse: separate; /* Don't collapse */ border-spacing: 0; } table th { /* Apply both top and bottom borders to the <th> */ border-top: 2px solid; border-bottom: 2px solid; border-right: 2px solid; } table td { /* For cells, apply the border to one of each side only (right but not left, bottom but not top) */ border-bottom: 2px solid; border-right: 2px solid; } table th:first-child, table td:first-child { /* Apply a left border on the first <td> or <th> in a row */ border-left: 2px solid; } table thead th { position: sticky; top: 0; background-color: #edecec; }
quelle
Sie müssen
box-shadow
Eigenschaft anstelle vonborder-top
/ verwendenborder-bottom
. Außerdem müssen Sie die oberen / unteren Ränder für den Kopf und die erste Tabellenzeile löschen.#wrapper { width : 400px; height : 200px; overflow : auto; } table { width : 100%; text-align : center; border-collapse : collapse; } table tr th, table tr td { border : 2px solid; } table thead th { position: -webkit-sticky; position : sticky; top : 0; background-color : #edecec; } /* here is the trick */ table tbody:nth-of-type(1) tr:nth-of-type(1) td { border-top: none !important; } table thead th { border-top: none !important; border-bottom: none !important; box-shadow: inset 0 2px 0 #000000, inset 0 -2px 0 #000000; padding: 2px 0; } /* and one small fix for weird FF behavior, described in /programming/7517127/ */ table thead th { background-clip: padding-box }
<body> <div id="wrapper"> <table> <thead> <tr> <th>A</th> <th>B</th> <th>C</th> <th>D</th> <th>E</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>1</td> <td>1</td> <td>1</td> <td>1</td> </tr> <tr> <td>2</td> <td>2</td> <td>2</td> <td>2</td> <td>2</td> </tr> <tr> <td>3</td> <td>3</td> <td>3</td> <td>3</td> <td>3</td> </tr> <tr> <td>4</td> <td>4</td> <td>4</td> <td>4</td> <td>4</td> </tr> <tr> <td>5</td> <td>5</td> <td>5</td> <td>5</td> <td>5</td> </tr> <tr> <td>6</td> <td>6</td> <td>6</td> <td>6</td> <td>6</td> </tr> <tr> <td>7</td> <td>7</td> <td>7</td> <td>7</td> <td>7</td> </tr> <tr> <td>8</td> <td>8</td> <td>8</td> <td>8</td> <td>8</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> </tbody> </table> </div> </body>
quelle
.wrapper thead th { border: none; }
Da die klebrige Positionierung zwischen relativ und fest schwankt, kann ich mir nur vorstellen, Pseudo-Klassen zu nutzen, um diesen Out-of-Box zu umgehen.
Ich bin mir sicher, dass es eine elegantere Art gibt, dies zu erreichen, aber ich würde nur die Klassen
:after
und:before
pseudo ändern , um die Grenze mit absoluter Positionierung zu versehen.#wrapper { width: 400px; height: 200px; overflow: auto; } table { width: 100%; text-align: center; border-collapse: collapse; } table tr th, table tr td { border: 2px solid; } table thead th { position: -webkit-sticky; position: sticky; top: -1px; background-color: #edecec; } th:after, th:before { content: ''; position: absolute; left: 0; width: 100%; } th:before { top: 0; border-top: 3px solid blue; } th:after { bottom: 0; border-bottom: 3px solid blue; }
<div id="wrapper"> <table> <thead> <tr> <th>A</th> <th>B</th> <th>C</th> <th>D</th> <th>E</th> </tr> </thead> <tr> <td>1</td> <td>1</td> <td>1</td> <td>1</td> <td>1</td> </tr> <tr> <td>2</td> <td>2</td> <td>2</td> <td>2</td> <td>2</td> </tr> <tr> <td>3</td> <td>3</td> <td>3</td> <td>3</td> <td>3</td> </tr> <tr> <td>4</td> <td>4</td> <td>4</td> <td>4</td> <td>4</td> </tr> <tr> <td>5</td> <td>5</td> <td>5</td> <td>5</td> <td>5</td> </tr> <tr> <td>6</td> <td>6</td> <td>6</td> <td>6</td> <td>6</td> </tr> <tr> <td>7</td> <td>7</td> <td>7</td> <td>7</td> <td>7</td> </tr> <tr> <td>8</td> <td>8</td> <td>8</td> <td>8</td> <td>8</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tr> <td>9</td> <td>9</td> <td>9</td> <td>9</td> <td>9</td> </tr> <tbody> </tbody> </table> </div>
quelle
<td style="position: sticky; top: 0; left: 0; right: 0; padding: 4px 3px; background-color: #d3d3d3; box-shadow: inset 0 1px 0 black, inset 0 -1px 0 black;"> </td>
Verwenden Sie diese 100% gearbeitet
quelle
Einige der vorhandenen Antworten wurden ausprobiert, aber wie bereits erwähnt, führen sie zu einer Lücke von einem Pixel zwischen den Rändern.
Problemumgehung durchgeführt, obwohl JavaScript erforderlich ist. Es platziert ein
<div>
in jedem<th>
, bei Größenänderung passt<div>
es zum<th>
. Der<th>
Rand wird dann stattdessen auf die angewendet<div>
.Beachten Sie, dass dies zum Zeitpunkt des Schreibens
position: sticky
nicht in Chromium<thead>
funktioniert, sondern in Firefox. Dasposition: sticky
zugehörige CSS wirkt sich jedoch nicht auf die Seite aus, wenn das JavaScript nicht ausgeführt wird.Klicken Run code snippetSie in Ihrem Browser, um zu sehen, ob es funktioniert.
function onResize() { $("thead th div").each(function () { var width = $(this).parent().outerWidth() - 2; // -2 * border-width $(this).css("width", width + "px"); }); } $("thead th").each(function () { $(this).append($("<div>")); }); $(window).on("resize", onResize); onResize();
table { width: 100%; border-collapse: collapse; } th { text-align: left; } th, td { padding: 12px 20px; border: 1px solid rgba(0, 0, 0, 0.125); } table thead { position: sticky; top: 0; background: #FFF; } /* Used as a workaround for position: sticky not rendering the border */ thead th div { width: 30px; margin: 0 -20px; /* -20px to negate the 20px from the padding */ position: absolute; top: 0; bottom: 0; z-index: -1; border-right: 1px solid rgba(0, 0, 0, 0.125); border-bottom: 1px solid rgba(0, 0, 0, 0.125); }
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <table> <thead> <tr> <th>A</th> <th>B</th> <th>C</th> <th>D</th> </tr> </thead> <tbody> <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr> <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr> <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr> <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr> <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr> <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr> <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr> <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr> <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr> <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr> <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr> <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr> <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr> <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr> <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr> <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr> </tbody> </table>
Wickeln Sie das vorherige JavaScript wie folgt ein, um es auf Firefox zu beschränken.
if (navigator.userAgent.toLowerCase().indexOf("firefox") > -1) { // ... }
Screenshot (Firefox 71):
quelle
Jetzt kann ich die
psuedo classes
Rahmenstile wie vom Benutzer @soulshined vorgeschlagen festlegen. Belows sind CSS-Änderungen an der Arbeit und hier ist JSFiddle Link . Bereits auf Chrom und Firefox getestet.#wrapper { width: 400px; height: 200px; overflow: auto; padding: 1px; } table { width: 100%; text-align: center; border-collapse: collapse; } table tr th { border: 1px solid green; } table tr th:first-child { border-left: 1px solid green; } table tr td { border: 1px solid green; } table thead th { position: -webkit-sticky; position: sticky; top: 0; background-color: #edecec; } th::before { content: ''; position: absolute; left: 0; width: 100%; height: 100%; border-right: 1px solid green; display: block; top : 1px; } th::after { content: ''; position: absolute; left: 0; width: 100%; height: 100%; border-bottom: 1px solid green; border-top: 1px solid green; display: block; top : -1px; }
quelle
Verwenden
::after
Pseudo-Selektor, um beispielsweise den rechten Rand zu emulierenBeispiel:
th::after { content: ''; position: absolute; top: 0; right: 0; height: 100%; border-right: 1px solid #e7e7e7; }
quelle
html{ padding: 0px; margin: 0px; } body{ padding: 0px; margin: 0px; width:100%; } th,td{ padding:10px; border: 0.1px solid #e8e0e0; padding-right:10px; } th{ text-align: center; background: #f3f3f3; background-clip: padding-box; } thead th:first-child { left: 0; z-index: 1; } tbody th:first-child { text-align: center; position: -webkit-sticky; /* for Safari */ position: sticky; left: 0; } tbody th,thead th:first-child { /* display:flex; */ /* text-align: center; align-items: center; align-self: center; */ width:30px; min-width: 30px; max-width: 30px; word-break: break-all; } .fixed_header{ width: 100%; /* height: 500px; */ table-layout: fixed; border-collapse: collapse; } /* .fixed_header tbody{ overflow: auto; } */ /* fixed header */ thead th { /* for Safari */ text-align: center; position: -webkit-sticky; position: sticky; top: 0; } .fixed_header th, .fixed_header td { padding:10px; /* text-align: left; */ width: 90px; } .fixed_header td{ /* padding:10px; */ /* word-break: break-all; */ /* max-width: 200px; */ } .table_container{ /* position: fixed; */ position: relative; width:100% ; min-height: 500px; overflow: auto; background:cornsilk; }
<table class="fixed_header"> <thead> <tr> <th></th> <th>Col 1</th> <th>Col 2</th> <th>Col 3</th> <th>Col 4</th> <th>Col 5</th> <th>Col 1</th> <th>Col 2</th> <th>Col 3</th> <th>Col 4</th> <th>Col 5</th> <th>Col 1</th> <th>Col 2</th> <th>Col 3</th> <th>Col 4</th> <th>Col 5</th> <th>Col 1</th> <th>Col 2</th> <th>Col 3</th> <th>Col 4</th> <th>Col 5</th> </tr> </thead> <tbody> <tr> <th>1</th> <td>row 1-1</td> <td>row 1-2</td> <td>row 1-3</td> <td>row 1-4</td> <td>row 1-1</td> <td>row 1-2</td> <td>row 1-3</td> <td>row 1-4</td> <td>row 1-1</td> <td>row 1-2</td> <td>row 1-3</td> <td>row 1-4</td> <td>row 1-1</td> <td>row 1-2</td> <td>row 1-3</td> <td>row 1-4</td> <td>row 1-1</td> <td>row 1-2</td> <td>row 1-3</td> <td>row 1-4</td> </tr> </tbody> </table> </div>
quelle
Dies ist meiner Meinung nach die einfachste Antwort.
Die akzeptierte Antwort bietet keine Lösung für einen 1px-Rand.
Hinweis: Dies ist eine Problemumgehung. Ergreifen Sie mich also nicht.
Wenn Sie das
border-top
aus dem Tabellenkopf entfernen , muss die Tabelle nicht reduziert werden, sodass kein Speicherplatz für die zugrunde liegenden Zellen erstellt wird. Ersetze dasborder-top
durch einen Rand des gleichen Stils in einem Holding-DIV.CSS:
table thead tr:nth-child(1) th { position: sticky; border-top:0; } .table_holder { border-top:1px solid black; }
html:
<div id="table_holder"> <table> ... </table> </div>
quelle
Wie wäre es ersetzt
border
mitoutline
? Ich wage zu sagen, dass gerade für Tabellenelemente dieoutline
Handlungen fast die gleichen sind wieborder
. Ich weiß, dass es sich nicht um ein Out-of-the-Box-Modell usw. handelt, aber optisch ist es hier identisch. Versuche dies:table tr th, table tr td { border: 0; outline: 2px solid; }
Denken Sie daran,
outline
wird immer um das ganze Element gerendert, es gibt nichts Vergleichbaresoutline-left
, es ist also keine Silberkugel. Weitere Informationen finden Sie in der Übersicht zu MDN .UPDATE : Nun, ich habe ein Detail übersehen, der Umriss ist nicht richtig an den
tbody
Rändern ausgerichtet . Sie müssen eiter tauschenborder
undoutline
für den gesamten Tisch oder verwendentransform
und stupsenthead
, aber vielleicht ist es kein guter Weg (es hängt natürlich davon ab).quelle
Verwenden Sie
table thead th
anstelle vontable thead
. Dies ist eine Demo. https://jsfiddle.net/nhatphamcdn/9dhqchtu/quelle
thead
Stil passiert ist .