combination of border-collapse:collapse and transform:translate - html

I have the following problem: When I translate the header cells from a table and the table is set to border-collapse:collapse then the cells will be moved but not their borders. I created a test:
Markup:
<table>
<thead>
<th>Test 1</th>
<th>Test 2</th>
<th>Test 3</th>
</thead>
<tbody>
<tr>
<td>asdasd</td>
<td>adasdasd</td>
<td>adasdasd</td>
</tr>
</tbody>
</table>
Style:
table{
border-spacing: 0;
border-collapse: collapse;
background: #efefef;
}
th {
background:#ccc;
border-right: 1px #000 solid;
transform: translate(-10px, 0);
}
http://jsfiddle.net/rs0h9tbu/2
If I change border-collapse to separat everything works fine.
Is it a bug, or can anybody explain that behaviour?

This is the behaviour of the collapsing border model. When border-collapse is set to collapse, then the cells share the border with that of the edge element which is the table. If it is set to separate, then the cells have their own border.
From this ref: https://developer.mozilla.org/en/docs/Web/CSS/border-collapse
The border-collapse CSS property determines whether a table's borders
are separated or collapsed. In the separated model, adjacent cells
each have their own distinct borders. In the collapsed model, adjacent
table cells share borders.
And from this spec: http://www.w3.org/TR/CSS2/tables.html#border-conflict-resolution
In the collapsing border model, borders at every edge of every cell
may be specified by border properties on a variety of elements that
meet at that edge (cells, rows, row groups, columns, column groups,
and the table itself)
This is why when you translate the cells, only the cells move because they are not having their own borders and only sharing the borders of the edge-element (i.e. table).
If you really really need to transform and move the th cells, then keep the border-collapse as separate and control the borders on td/th individually.
Something like this:
table {
border-spacing: 0px;
border: 1px solid #333;
background: #efefef;
border-collapse: separate;
}
th,td { border: 1px solid #333; }
td { border-right: 0px; }
td:first-child { border-left: 0px; }
tbody > tr:last-child > td { border-bottom: 0px; }
th { background: #ccc; transform: translate(50px, 50px); }
<table>
<thead>
<tr>
<th>Test 1</th>
<th>Test 2</th>
<th>Test 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>asdasd</td>
<td>adasdasd</td>
<td>adasdasd</td>
</tr>
</tbody>
</table>

Related

Border-collapse and colspan in IE11

I have a simple example table with 3 rows and 5 columns styled with a border-collapse: collapse border.
The problem here is that I have a colspan=4 td in the second row, with IE11 (11.0.9600.17691) not showing the right border of that row.
You can see this example here: http://jsfiddle.net/j6u026oz/2/
I've tried putting an extra right border to the tr and th elements but it doesn't work.
Adding an extra th next to the colspan=4 element could solve this issue but I'd prefer to solve this problem with CSS if it's possible, as touching the HTML structure would imply a lot of changes in the project I'm working in.
Thank you!
You could add the extra column by CSS, using ::after pseudo-element:
Updated example
table {
border-collapse: collapse;
border: 1px solid black;
}
tbody > tr:first-child:after {
content: "";
display: table-cell;
}
<table>
<thead>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
<th>E</th>
</tr>
</thead>
<tbody>
<tr>
<th colspan="4">colspan4</th>
</tr>
<tr>
<td>td1</td>
<td>td2</td>
<td>td3</td>
<td>td4</td>
<td>td5</td>
</tr>
</tbody>
</table>
remove
border-collapse: collapse;
from your css file.
use the code as below
table{
border: 1px solid black;
}
Use "outline" instead of "border".
table{
border-collapse: collapse;
border: 1px solid black;
outline: 1px solid red; /* ---- this lil' guy ---- */
}

How does one make one table column header taller than the rest?

I have a table of data, with some columns more important than the others and need a way to visually distinguish them.
<table>
<thead>
<tr>
<th>A header</th>
<th class="important" colspan="2">An important header!</th>
<th class="important" >Also important</th>
<th>Boring header</th>
</tr>
<tr>
<th>Sub header</th>
<th>Part 1</th>
<th>Part 2</th>
<th>Sub header</th>
<th>Sub header</th>
</tr>
</thead>
<tbody>
<!-- lots of data here -->
</tbody>
</table>
What I want to do is make them some of the columns/headers a little taller than the rest, like this:
I've tried setting the height of the <th> cell, but that doesn't work properly. There are some elements inside the headers and trying to create a :before pseudo element, and then fixing its height isn't seeming to work.
I even tried adding <col> definitions, but they seemed to have trouble with the colspan cell I hate, but I could have been doing it wrong.
<table>
<col> <!-- I can style this maybe? -->
<thead>
In the first instance I'd prefer a CSS solution, and can easily add classes or ids as needed. I'd rather not add additional markup, but will relent if required. Using Javascript to extra inject elements is not an option!
Any ideas on how to create a table header cell that is taller than the rest of the cells using CSS?
The table sizing algorithm will force all the table cells in a row to take on the same height, no way around that.
One way of doing it requires extra markup. Wrap your content in a wrapper and take it out of the normal content flow using absolute positioning. You will need to adjust any border properties on the table cells and add them to the child wrapper blocks.
Finally, you need to a top margin/padding to the table to provide room for the extra tall headers.
At least it is a proof of concept, perhaps a place to start.
table {
margin-top: 75px;
}
th {
border: 1px dotted gray;
position: relative;
}
.important div {
height: 75px;
position: absolute;
width: inherit;
bottom: 0;
border: 1px dotted gray;
}
<table>
<thead>
<tr>
<th>A header</th>
<th class="important" colspan="2"><div>An important header!</div></th>
<th class="important" >Also important</th>
<th>Boring header</th>
</tr>
<tr>
<th>Sub header</th>
<th>Part 1</th>
<th>Part 2</th>
<th>Sub header</th>
<th>Sub header</th>
</tr>
</thead>
<tbody>
<!-- lots of data here -->
</tbody>
</table>
The idea is to remove the top-left and top-right cell borders and create them by using pseudo elements. Markups remain the same, even class="important" won't be needed.
http://jsfiddle.net/of79mcoj/
table {
border-collapse: collapse;
}
th {
border: 1px solid black;
padding: 30px 20px;
}
tr:first-child th:first-of-type,
tr:first-child th:last-of-type {
position: relative;
border-top: 0;
padding-top: 60px;
}
tr:first-child th:first-of-type {
border-left: 0;
}
tr:first-child th:last-of-type {
border-right: 0;
}
tr:first-child th:first-of-type::before,
tr:first-child th:last-of-type::before {
content: "";
display: block;
position: absolute;
border: 1px solid black;
border-bottom: 0;
left: 0;
bottom: 0;
width: 100%;
height: 70%;
}
tr:first-child th:first-of-type::before {
border-right: 0;
}
tr:first-child th:last-of-type::before {
border-left: 0;
}
Well, I can only think of absolute positioning a pseudo element, and set line-height to 0 to achieve what you want, won't work on IE 7 though
have a look here Fiddle (haven't tested on IE 8)
th.important {
border-top: 0;
vertical-align: top;
line-height: 0;
}
th.important:before {
height: 30px;
content: "";
display: block;
position: absolute;
top:-30px;
left:-1px;
right: -1px;
border: 1px solid #000;
border-bottom: 0;
}
Notice: I have to apply some margin on the table so that the absolute pseudo elements are in view.

Why do the CSS property border-collapse and empty-cells conflict?

I can use the CSS property border-collapse to combine the borders of adjacent table cells. And I can use empty-cells to hide table cells that have no content. But when I use both, the empty-cells property has no effect and empty cells are always visible. At least there's a border around each of them, even where multiple adjacent rows and columns are empty.
Here's an example:
<!doctype html>
<html>
<head>
<style>
table
{
border-collapse: collapse;
border-spacing: 0;
}
th,
td
{
empty-cells: hide;
border: solid 1px black;
padding: 2px 4px;
}
</style>
</head>
<body>
<table>
<tr>
<th></th>
<th></th>
<th>Header 3</th>
</tr>
<tr>
<th></th>
<th></th>
<th>Header 3</th>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td></td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td></td>
</tr>
</table>
</body>
</html>
As #Bolt explained why this happens, I will provide a solution for this, you can use the below snippet in your CSS to hide the empty cells
th:empty, td:empty {
border: 0;
}
Demo
Using :empty pseudo, I set the border: 0; so physically the element is present on the page, we just target the styles of the empty cells and set the borders to 0.
I didn't used display: none; as it will spoil your table layout, so using the above snippet is enough if you want to keep the border collapsed.
Note: The selector am using is a general selector and will target globally, if you want to target the element specifically, consider using a class instead like
.table_class_name th:empty,
.table_class_name td:empty {
/* Styles goes here */
}
This is a trick that I found, you can use border-collapse as separate. then you define border-spacing to 0px into your table then define the padding in your td to 0px.
table
{
empty-cells: hide;
border-collapse: separate;
border-spacing: 0px;
}
td
{
border: thin solid black;
text-align: right;
padding: 0px;
}
th
{
border: thin solid black;
background-color: yellow;
}

How to highlight 4 borders of a table cell with border-collapse collapse

I want to highlight the borders of cells having the class active.
The problem is the table's border-collapse property is set to collapse, which will hide the top and left border of cells(except for left most and top row cells). This is causing an issue whereby the highlight class(active) is not highlighting the top and left borders.
You can find the problem here.
HTML
<div style="padding: 10px">
<table>
<tr>
<td>1.1</td>
<td>1.2</td>
<td>1.3</td>
<td>1.4</td>
<td>1.5</td>
</tr>
<tr>
<td>2.1</td>
<td>2.2</td>
<td class="active">2.3</td>
<td>2.4</td>
<td>2.5</td>
</tr>
<tr>
<td>3.1</td>
<td>3.2</td>
<td>3.3</td>
<td>3.4</td>
<td>3.5</td>
</tr>
<tr>
<td>4.1</td>
<td>4.2</td>
<td>4.3</td>
<td>4.4</td>
<td>4.5</td>
</tr>
<tr>
<td>5.1</td>
<td>5.2</td>
<td>5.3</td>
<td>5.4</td>
<td>5.5</td>
</tr>
</table>
</div>
CSS
table {
table-layout: fixed;
border-spacing: 0;
border-collapse: collapse;
}
td {
border: 1px solid lightgrey;
height: 60px;
width: 60px;
text-align: center;
vertical-align: middle;
}
td.active {
border: 1px solid blue;
}
td.brdr-b-hide {
border-bottom: none;
}
td.brdr-r-hide {
border-right: none;
}
Javascript
$('table').on('click', 'td', function(e){
var target = $(e.currentTarget);
if(e.ctrlKey && target.hasClass('active')){
target.removeClass('active');
} else if(e.ctrlKey) {
target.addClass('active');
} else {
$('table td.active').removeClass('active');
target.addClass('active');
}
});
One of the solutions I'm working on is to hide the border-right of the cell in the left of the active cell and the border-bottom of the cell at the top.
I'm not so happy with the solution since the active class is applied and removed when a cell is clicked. Here my solution need to find the prev cell and the top cell and apply/remove the corresponding classes to/from them.
You can find the proposed solution here.
My question is, is there a better way to handle this problem?
Define border-style:double. Write like this:
td.active {
border: 1px solid blue;
border-style:double;
}
Check this http://jsfiddle.net/2ahfP/18/
Try this instead:
td.active {
outline: 1px solid blue;
}
The difference between outline and border is that outline won't add to the elements total width or height. Also the border-collapse property won't affect the outline.

TH not overriding table border (CSS+HTML)

I want the headings of the table to have a red solid border and the rest of the table a dotted black border.
Using the code below, all is correct but the left and right side of the TH being black dotted. Is there any way to override the <table> borders within a TH style declaration?
This is what I want to achieve:
<style type="text/css">
table {
border-style:none dotted dotted dotted;
border-collapse: collapse;
}
table th {
border: 2px solid red;
}
</style>
<table >
<thead>
<tr>
<th>title 1</th>
<th>title 2</th>
<th>title 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>text</td>
<td>text</td>
<td>text</td>
</tr>
<tr>
<td>text</td>
<td>text</td>
<td>text</td>
</tr>
<tr>
<td>text</td>
<td>text</td>
<td>text</td>
</tr>
</tbody>
</table>
A simple solution is to set the th border width equal to or larger than the table border width, if this is acceptable. For example, add
table { border-width: 2px; }
to make them equal. In your example, the width is the initial value, medium, which normally maps to 3px or 4px in browsers.
Otherwise, a different strategy is needed (see Zolthan Toth’s answer), a strategy where no left or right border is set on the table element.
The reason is that according to the [border conflict resolution][1] rules, the wider border wins (and for equal-width borders, solid beats dotted).
Try this - http://jsfiddle.net/eaTLp/
table {
border-style:none none dotted;
border-collapse: collapse;
}
table th {
border: 2px solid red;
}
table td:first-child {
border-left: dotted;
}
table td:last-child {
border-right: dotted;
}
​
You're giving the dotted border only to the bottom of the table. On the left and right you're selecting the first and last <td> in every row by :first-child and :last-child and assign them the left and right border respectively.