How to display borders in thead with border-collapse? - html

I would like to collapse only the out-side border, not inside of the thead:
table, tr {
border: 1px solid black;
padding: 7px;
border-collapse: collapse;
}
th {
background: #ccccff;
}
<table>
<thead>
<tr>
<th>Data 1</th>
<th>Data 2</th>
</tr>
</thead>
</table>
will not show the borders between the th like Data 1 | Data 2, why? (And how to add these the border between the th elements)?

Remove border: 1px solid black from table, tr. And set the border for the right side border-right: 1px solid black. Also, using the :last-of-type pseudo-class, remove the border for the last element.
table, tr {
/*border: 1px solid black;*/
padding: 7px;
border-collapse: collapse;
}
th {
background: #ccccff;
border-right: 1px solid black;
}
th:last-of-type {
border-right: unset;
}
<table>
<thead>
<tr>
<th>Data 1</th>
<th>Data 2</th>
<th>Data 3</th>
<th>Data 4</th>
<th>Data 5</th>
<th>Data 6</th>
<th>Data 7</th>
<th>Data 8</th>
<th>Data 9</th>
<th>Data 10</th>
</tr>
</thead>
</table>

border-collapse doesn't have the effect you think. It just prevents gaps between the borders of each cell. This is what happens without border-collapse:
table {
border: 1px solid black;
padding: 7px;
border-collapse: none;
}
th,td {
border: 1px solid blue;
}
<table>
<thead>
<tr>
<th>Data 1</th>
<th>Data 2</th>
</tr>
</thead>
</table>
The other problem is that you are adding the border to the tr - this is just the row, it doesn't apply to the cells inside the row. Also FYI, adding a border to the table in CSS only adds the border around the outside of the whole table.
To apply borders to the cells, you need to add the border CSS to the th elements (and td for the rest of your table), e.g.:
th, td {
border: 1px solid blue;
}
Working Snippet with examples of just rows with borders and th/tds with borders:
table,
tr {
border: 1px solid black;
padding: 7px;
border-collapse: collapse;
text-align:center;
}
th {
border: 1px solid blue;
}
tr.showborder td {
border: 1px solid red;
}
<table>
<thead>
<tr>
<th>Data 1</th>
<th>Data 2</th>
<th>Data 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>this ROW</td>
<td> has a</td>
<td>border</td>
</tr>
<tr>
<td>this ROW</td>
<td> also has a</td>
<td>border</td>
</tr>
<tr class="showborder">
<td>The cells in </td>
<td>this row all</td>
<td>have borders</td>
</tr>
<tr class="showborder">
<td>The cells in </td>
<td>this row all</td>
<td>have borders</td>
</tr>
</tbody>
</table>

Related

fixed column tables are getting border issue with horizontal scrolling

The border disappears when scrolling. I want the border to appear. How can I do this? Or how can I start the scroll only from the scrolled part?
HTML - Table Structure
<div class="wrapper">
<table>
<thead>
<th class='fix'>Fixed</th>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
<th>Col 5</th>
<th class='fix'>Fixed</th>
</thead>
<tbody>
<tr>
<td class='fix'>First Content</td>
<td>A1</td>
<td>A2 (with longer content)</td>
<td>A3</td>
<td>A4</td>
<td>A5</td>
<td class='fix'>Last Content</td>
</tr>
</tbody>
</table>
</div>
CSS - Table CSS
.wrapper {
overflow-x:scroll;
width:100%;
}
table {
table-layout: fixed;
width: 100%;
border-collapse: collapse;
background: white;
}
thead {
font-family: arial
}
tr {
border-bottom: 1px solid #ccc;
}
td, th {
vertical-align: top;
text-align: left;
width:100px;
padding: 5px;
border: 1px solid red;
}
.fix {
position:sticky;
background: white;
}
.fix:first-child {
left:0;
width:120px;
}
.fix:last-child {
right:0;
width:120px;
}
Play with code: https://jsbin.com/marezen/1/edit?html,css,output
In order to have fixed table borders you need to:
remove border-collapse from css
table {
table-layout: fixed;
width: 100%;
/*border-collapse: collapse;*/
background: white;
}
Also add cellspacing="0" to remove the cellspacing
<table cellspacing="0">
for having same borders like your example, combined with my solution:
CSS-
.wrapper {
overflow-x:scroll;
width:100%;
}
table {
table-layout: fixed;
width: 100%;
/* border-collapse: collapse; */
background: white;
border-top:1px solid red;
/* border-left:1px solid red; */
}
thead {
font-family: arial
}
tr {
/* border-bottom: 1px solid #ccc; */
}
td, th {
vertical-align: top;
text-align: left;
width:100px;
padding: 5px;
/* border: 1px solid red; */
border-right:1px solid red;
border-bottom:1px solid red;
}
.fix {
position:sticky;
background: white;
border-left:1px solid red;
}
.fix:first-child {
left:0;
width:120px;
}
.fix:last-child {
right:0;
width:120px;
}
td:nth-child(6),
th:nth-child(6){
border-right:none;
}
HTML-
<div class="wrapper">
<table cellspacing="0">
<thead>
<th class='fix'>Fixed</th>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
<th>Col 5</th>
<th class='fix'>Fixed</th>
</thead>
<tbody>
<tr>
<td class='fix'>First Content</td>
<td>A1</td>
<td>A2 (with longer content)</td>
<td>A3</td>
<td>A4</td>
<td>A5</td>
<td class='fix'>Last Content</td>
</tr>
<tr>
<td class='fix'>First Content (with longer content)</td>
<td>B1</td>
<td>B2</td>
<td>B3</td>
<td>B4</td>
<td>B5</td>
<td class='fix'>Last Content</td>
</tr>
<tr>
<td class='fix'>First Content</td>
<td>C1</td>
<td>C2</td>
<td>C3</td>
<td>C4</td>
<td>C5</td>
<td class='fix'>Last Content (with longer content)</td>
</tr>
</tbody>
</table>
</div>
The solution is to add border-left to the wrapper. Then I removed the border property from td, tr and instead added border selection to them like border-top in order to remove the wrapper's border overlapping those borders.
https://jsbin.com/niluyefacu/edit?html,css,output

Unwanted shifting using fixed column and rowspan in table

I have a table that uses rowspan for one of the table headers. This table also switches to a fixed column style on smaller sizes. The issue I'm running into is on smaller sizes, when the th with the rowspan becomes fixed, it messes up the structure of the remaning th.
A solution I thought of was to just have an empty th above Foods so I didn't have to use a rowspan, but due to ADA requirments, that's not an option.
Here's some code: CODEPEN
This is the large screen view - you can see there's a Foods column as well as two groups, each of which containing two columns.
Here's a view of when it goes to the fixed column layout. You can see that Group 1 - Col 1 now takes the place where Foods used to be, and the entire 2nd shifted.
HTML:
<div class="wrap">
<table>
<thead>
<tr>
<th rowspan="2" class="fixed">Foods</th>
<th colspan="2">Group 1</th>
<th colspan="2">Group 2</th>
</tr>
<tr>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
</tr>
</thead>
<tbody>
<tr>
<td class="fixed">Tacos</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
</tr>
<tr>
<td class="fixed">Pizza</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
</tr>
</tbody>
</table>
</div>
CSS:
table {
border: solid 1px black;
border-spacing: 0;
border-collapse: collapse;
width: 900px;
}
th {
vertical-align: bottom;
padding: 5px 10px;
border-left: solid 1px grey;
}
th[colspan="2"] {
border-bottom: solid 1px grey;
}
td {
border-top: solid 1px grey;
}
tbody tr:nth-child(odd) td {
background: grey;
}
.fixed {
border-left: none;
}
#media (max-width: 600px) {
.fixed {
position: absolute;
width: 50px;
left: 0;
}
.wrap {
overflow-x: scroll;
overflow-y: visible;
margin-left: 50px;
}
}
I am not really sure about the issue but it seems to be related to the use of position:fixed. You are removing the elements from the flow so it's like they no more belong to the table making the table algorithm behave strange.
An idea of fix is to consider a extra element that you make visible on small screen to avoid this issue. Basically this element will correct the table layout when you make some of the element position:fixed
* {
text-align: center;
font-weight: normal;
}
table {
border: solid 1px black;
border-spacing: 0;
border-collapse: collapse;
width: 900px;
}
th {
vertical-align: bottom;
padding: 5px 10px;
border-left: solid 1px grey;
}
th[colspan="2"] {
border-bottom: solid 1px grey;
}
td {
border-top: solid 1px grey;
}
tbody tr:nth-child(odd) td {
background: grey;
}
.fixed {
border-left: none;
}
.fix {
padding:0;
border:none;
}
#media (min-width:700px) {
.fix {
display:none;
}
}
#media (max-width: 700px) {
.fixed {
position: absolute;
width: 50px;
left: 0;
}
.wrap {
overflow-x: scroll;
overflow-y: visible;
margin-left: 50px;
}
}
<div class="wrap">
<table>
<thead>
<tr>
<th rowspan="2" class="fixed">Foods</th>
<th colspan="2">Group 1</th>
<th colspan="2">Group 2</th>
</tr>
<tr>
<th class="fix"></th>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
</tr>
</thead>
<tbody>
<tr>
<td class="fixed">Tacos</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
</tr>
<tr>
<td class="fixed">Pizza</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
</tr>
</tbody>
</table>
</div>
To avoid extra element you can consider pseudo element:
* {
text-align: center;
font-weight: normal;
}
table {
border: solid 1px black;
border-spacing: 0;
border-collapse: collapse;
width: 900px;
}
th {
vertical-align: bottom;
padding: 5px 10px;
border-left: solid 1px grey;
}
th[colspan="2"] {
border-bottom: solid 1px grey;
}
td {
border-top: solid 1px grey;
}
tbody tr:nth-child(odd) td {
background: grey;
}
.fixed {
border-left: none;
}
thead > tr:last-child::before {
content:"";
display:table-cell;
padding:0;
border:none;
}
#media (min-width:700px) {
thead > tr:last-child::before {
display:none;
}
}
#media (max-width: 700px) {
.fixed {
position: absolute;
width: 50px;
left: 0;
}
.wrap {
overflow-x: scroll;
overflow-y: visible;
margin-left: 50px;
}
}
<div class="wrap">
<table>
<thead>
<tr>
<th rowspan="2" class="fixed">Foods</th>
<th colspan="2">Group 1</th>
<th colspan="2">Group 2</th>
</tr>
<tr>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
</tr>
</thead>
<tbody>
<tr>
<td class="fixed">Tacos</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
</tr>
<tr>
<td class="fixed">Pizza</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
</tr>
</tbody>
</table>
</div>

how to make a space-keeping column use css and table tag

What is the most elegant way to remove the up down border?
table {
border: 1px solid #CCC;
border-collapse: collapse;
text-align: center;
}
.noborder {
border: none;
width: 50px;
}
<br>
<table border='1' width='500'>
<tr>
<th>Product</th>
<th>Description</th>
<th>Price</th>
<th>Quantity</th>
<th class="noborder"> </th>
<th>Delete</th>
</tr>
<tr>
<td>AA</td>
<td>BB</td>
<td>CC</td>
<td>DD</td>
<td class="noborder"> </td>
<td>FF</td>
</tr>
</table>
JSfiddle Demo
You need to apply border for the th and td elements and not for the entire table. Setting border for the table will not be affected by the noborder class applied on the child elements.
Updated JSfiddle
table {
border-collapse: collapse;
text-align: center;
}
.noborder {
border: none;
width: 50px;
}
th,
td {
border: 1px solid #CCC;
}
<br>
<table width='500'>
<tr>
<th>Product</th>
<th>Description</th>
<th>Price</th>
<th>Quantity</th>
<th class="noborder"> </th>
<th>Delete</th>
</tr>
<tr>
<td>AA</td>
<td>BB</td>
<td>CC</td>
<td>DD</td>
<td class="noborder"> </td>
<td>FF</td>
</tr>
</table>
I'd say specify only the borders you need.
If you don't want the top and bottom... only set the left and right border.
table {
border-left: 1px solid #000;
border-left: 1px solid #000;
}
If you're trying to remove only the top and bottom of that blank column, you could try setting the border for each column separately, thus allowing the removal of the desired border.
td {
border: 1px solid #000;
}
#blank-td {
border: none /* or even 1px solid #fff */;
}
Just mess around with it
More info: http://www.w3schools.com/css/css_border.asp

Table Row Border - Half In, Half Out

I'm trying to style table with what I thought would be a fairly simple style to achieve but have run in to a little issue.
The table will show a coloured indicator on the left hand side of each row so I'm using border-left: 5px solid red; to add it. However, although the border applies - half of it is inside the row and half outside. I've tried adding border-collapse: collapse to no avail, I'm also using box-sizing: border-box but still have the same issue.
Finally, I've also tried adding the border to the first-child cell (td) but the same issue appears.
I've set up an example of what's happening - I've put in an oversized border to highlight the issue:
http://www.cssdesk.com/TVa67
Has anyone run into this before or have any solutions?
body {
background: blue;
}
table {
border-collapse: collapse;
box-sizing: border-box;
table-layout: fixed;
width: 100%;
}
th,
td {
background-color: #fff;
padding: 10px 15px 8px;
}
th {
border-bottom: 1px solid blue;
font-weight: normal;
text-align: left;
}
td {
border-bottom: 1px solid gray;
}
tr.low {
border-left: 25px solid red;
}
<table style="
border-collapse: collapse;
">
<tbody>
<tr>
<th>#</th>
<th>Status</th>
<th>Title</th>
<th>Project</th>
<th>Assigned To</th>
<th>Age</th>
</tr>
<tr class="low">
<td>1</td>
<td>New</td>
<td>This is an example ticket</td>
<td>Something</td>
<td>Something</td>
<td>2 days ago</td>
</tr>
</tbody>
</table>
However, although the border applies - half of it is inside the row
and half outside
This behaviour is expected and is as per specs. Refer to: http://www.w3.org/TR/CSS2/tables.html#collapsing-borders where it says:
Borders are centered on the grid lines between the cells...
It also illustrates that with a diagram with description.
Has anyone run into this before or have any solutions?
Yes, it can be easily demonstrated as in this fiddle: http://jsfiddle.net/abhitalks/xs7L9wn1/1/ and the below Snippet:
* { box-sizing: border-box; }
table {
border-collapse: collapse;
border: 1px solid gray;
table-layout: fixed; width: 70%;
margin: 0 auto;
}
th, td {
border: 1px solid gray;
padding: 6px;
text-align: center;
}
tbody > tr:nth-child(1) > td:first-child { border-left: 16px solid red; }
tbody > tr:nth-child(2) > td:first-child { border-left: 8px solid green; }
tbody > tr:nth-child(3) > td:first-child { border-left: 24px solid blue; }
tbody > tr:nth-child(1) > td:last-child { border-left: 16px solid red; }
tbody > tr:nth-child(2) > td:last-child { border-left: 8px solid green; }
tbody > tr:nth-child(3) > td:last-child { border-left: 24px solid blue; }
<table>
<thead>
<tr>
<th>#</th>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Caption</td>
<td>Description</td>
</tr>
<tr>
<td>2</td>
<td>Caption</td>
<td>Description</td>
</tr>
<tr>
<td>3</td>
<td>Caption</td>
<td>Description</td>
</tr>
</tbody>
</table>
Solution:
Just add a transparent border of the same width to all rows. That way the border-width will be same and it will neatly align. (Update: added a white border-left to first column to hide the hanging border on highlighted cell. As pointed out by your comment.)
th, td { border-left: 15px solid transparent; }
tr > td:first-child, tr > th:first-child { border-left: 5px solid #fff; }
tr.low > td:first-child { border-left: 5px solid red; }
Example Fiddle: https://jsfiddle.net/abhitalks/s9taanz7/5/
Snippet:
* { box-sizing: border-box; }
body { background-color: blue; }
table {
border-collapse: collapse;
table-layout: fixed; width: 100%;
}
th, td {
background-color: #fff;
padding: 10px 15px 8px 8px;
border-left: 5px solid transparent;
border-bottom: 1px solid gray;
}
th {
border-bottom: 1px solid blue;
font-weight: normal; text-align: left;
}
tr > td:first-child, tr > th:first-child { border-left: 10px solid #fff; }
tr.low > td:first-child { border-left: 10px solid red; }
<table>
<thead>
<tr>
<th>#</th>
<th>Status</th>
<th>Title</th>
<th>Project</th>
<th>Assigned To</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr class="">
<td>1</td>
<td>New</td>
<td>This is an example ticket</td>
<td>Something</td>
<td>Something</td>
<td>2 days ago</td>
</tr>
<tr class="low">
<td>2</td>
<td>New</td>
<td>This is an example ticket</td>
<td>Something</td>
<td>Something</td>
<td>2 days ago</td>
</tr>
<tr class="">
<td>3</td>
<td>New</td>
<td>This is an example ticket</td>
<td>Something</td>
<td>Something</td>
<td>2 days ago</td>
</tr>
</tbody>
</table>
However, this approach will have a side-effect of hidden border-bottom because the border-left overlaps it.
Solution 2:
You could have an extra cell on the left to use as indicator. You can then control this by use of colgroup. This approach is neater than above and also requires you to have the width specified only once in css.
Example Fiddle 2: http://jsfiddle.net/abhitalks/z7u1nhwt/1/
Snippet 2:
* { box-sizing: border-box; }
body { background-color: blue; }
table {
border-collapse: collapse;
table-layout: fixed; width: 100%;
}
th, td {
background-color: #fff;
padding: 10px 15px 8px 8px;
border-bottom: 1px solid gray;
}
th {
border-bottom: 1px solid blue;
font-weight: normal; text-align: left;
}
.col1 { width: 10px; }
tr.low > td:first-child {
background-color: #f00;
}
<table>
<colgroup>
<col class="col1" />
<col class="coln" span="6" />
</colgroup>
<thead>
<tr>
<th></th>
<th>#</th>
<th>Status</th>
<th>Title</th>
<th>Project</th>
<th>Assigned To</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr class="">
<td></td>
<td>1</td>
<td>New</td>
<td>This is an example ticket</td>
<td>Something</td>
<td>Something</td>
<td>2 days ago</td>
</tr>
<tr class="low">
<td></td>
<td>2</td>
<td>New</td>
<td>This is an example ticket</td>
<td>Something</td>
<td>Something</td>
<td>2 days ago</td>
</tr>
<tr class="">
<td></td>
<td>3</td>
<td>New</td>
<td>This is an example ticket</td>
<td>Something</td>
<td>Something</td>
<td>2 days ago</td>
</tr>
</tbody>
</table>
And of course, you can also try the approach of using pseudo-element as proposed by #misterManSam, depending on ease of implementation for you.

Inner and Outer Borders with Alternating row color

How can I, given the current css coding below, be able to do the following:
Fix the table such that there is an INNER border only of 1px solid FFF in the table headers.
Fix the table header such that the missing right border is completed.
Put a top border of 1px solid #6B6B6B after the table headers (as it appears to be missing, and I dont know how to fix it, I am also using IE 9)
Alternate the row color (white) starting at the first row (not the table header), then in the 2nd row it would be (gray).
I am just new to css and am not familiar with advanced programming.
Heres a fiddle: http://jsfiddle.net/3CzbV/
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
table {
border-collapse: collapse;
border: 1px solid #6B6B6B;
}
table th {
color: red;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#cccccc, endColorstr=#ffffff);
}
table td {
color: blue;
}
table td, table th {
border: 1px solid #6B6B6B;
}
table tr:first-child th {
border-top: 0;
}
table tr:last-child td {
border-bottom: 0;
}
table tr td:first-child,
table tr th:first-child {
border-left: 0;
}
table tr td:last-child,
table tr th:last-child {
border-right: 0;
}
</style>
</head>
<body>
<table>
<tr>
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
<th>Heading 4</th>
</tr>
<tr>
<td>Cell (1,1)</td>
<td>Cell (2,1)</td>
<td>Cell (3,1)</td>
<td>Cell (4,1)</td>
</tr>
<tr>
<td>Cell (2,1)</td>
<td>Cell (2,2)</td>
<td>Cell (3,2)</td>
<td>Cell (4,2)</td>
</tr>
<tr>
<td>Cell (3,1)</td>
<td>Cell (2,3)</td>
<td>Cell (3,3)</td>
<td>Cell (4,3)</td>
</tr>
</table>
</body>
</html>
First you should add the <thead> and <tbody> elements/tags or possibly even a <tfoot>
HTML Markup
<div>
<table>
<thead>
<tr>
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
<th>Heading 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell (1,1)</td>
<td>Cell (2,1)</td>
<td>Cell (3,1)</td>
<td>Cell (4,1)</td>
</tr>
<tr>
<td>Cell (2,1)</td>
<td>Cell (2,2)</td>
<td>Cell (3,2)</td>
<td>Cell (4,2)</td>
</tr>
<tr>
<td>Cell (3,1)</td>
<td>Cell (2,3)</td>
<td>Cell (3,3)</td>
<td>Cell (4,3)</td>
</tr>
</tbody>
</table>
</div>
The Styles
div{
background-color: grey;
margin: 20px;
padding: 10px;
}
table {
border-collapse: collapse;
border: 1px solid #6B6B6B;
margin: 20px;
}
/* 1.Fix the table such that there is an INNER border only of 1px solid FFF in the table headers*/
/* 2.Fix the table header such that the missing right border is completed */
table thead tr th {
border: 1px solid #FFF;
/* 3.Put a top border of 1px solid #6B6B6B after the table headers */
border-bottom: 1px solid #6B6B6B;
}
table tbody tr:nth-child(odd) {
background-color: white;
}
Fiddle
So first of all, here's the fiddle http://jsfiddle.net/EVjJU/2/
/*color different tbody rows*/
tbody tr:nth-child(odd) {
background-color: #ffffff;
}
tbody tr:nth-child(even) {
background-color: #cccccc;
}
/*first tbody row with a top border*/
tbody tr:first-child td {
border-top: 5px #ffffff solid;
}
/*there is no right border missing to my knowledge?*/
/*thead inner border or 1px white*/
thead th {
border-right: 1px #ffffff solid;
}
I didn't quite understand the missing right border in header part, could you elaborate on that?