Non Uniform Dashed Border in Table Cells - html

I have applied CSS border-bottom:1px dashed #494949; on several consecutive cells of a single row of an HTML table, but the border is not uniform. The dashes at the end of each cell appear little longer. Dotted border is also not uniform. I am also using border-collapse:collapse;
Here is the screenshot:
Is there any way I can get uniform dashed border?

The way I fixed this problem on my app was by adding an extra row with the same colspan as the row with the dashed border. The border will be uniform to the length of the span:
<table>
<!--row with dashed border-->
<tr>
<td style = "border-bottom: 1px dashed green;" colspan="3"></td>
</tr>
<!--added row so dotted border looks uniform-->
<tr>
<td style="height: 5px;" colspan="3"></td>
</tr>
<!--existing rows with lots of columns-->
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>

Browsers have oddities in rendering dashed borders. You can fight against them by removing cell spacing and cell padding and setting the border on a tr element and not on cells, e.g.
table { border-collapse: collapse; }
td { padding: 0; }
tr { border-bottom:1px dashed #494949; }
But this still seems to fail on IE 9 (at cell junctions), and old browsers ignore borders set on table rows.
Consider using a solid gray border instead. It works consistently and might be visually acceptable, maybe even better.

Hard to say for sure what's going on without a screenshot or demo, but it sounds like they appear to be longer at the transition to the next cell because the last dash is touching the first dash in the next cell.
In that case, try to put the border on the entire row instead of the individual cells.

I'm not sure but it looks like rendering issue. Even using a background-image instead of border-bottom will have same kind of issue.

Your best bet in this case would be to create a repeating image file, the height of which is the height of the table row. Set it as the table background, and make sure it repeats. I've tested it, and it works. Note that in the PNG file created for this example, the dashes are each 3px long, and there are three blank trailing pixels on the right, for final dimensions of 30px (width) x 29px (height).
Here's the code:
.borderTable {
background: url(http://www.windycitywebsites.com/wp-content/uploads/2012/03/dash_png.png);
background-repeat: repeat;
}
.borderTable td {
height: 29px;
}
<table class="borderTable" width="350" border="0" cellspacing="0" cellpadding="0">
<tr class="stuff">
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr class="stuff">
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
</table>

DIZAD's answer has almost worked for me, but adding borders to the td still resulted in weird dashed borders. Adding the border to a div inside the td fixed it for me.
const RowBorder = styled('div')`
border-top: 1px dashed black;
width: 100%;
`;
return (
<table>
<thead>
<tr>
<td colSpan="6">
<RowBorder />
</td>
</tr>
<tr>
<td>Col1</td>
<td>Col2</td>
<td>Col3</td>
<td>Col4</td>
<td colSpan="2">Col5</td>
</tr>
<tr>
<td colSpan="6">
<RowBorder />
</td>
</tr>
</thead>
<tbody>{rows}</tbody>
</table>
)

Nine years on, and this is still giving people a headache!
This method works from IE11+ and all other major browsers without having to create an empty row just for a border:
table {
width: 100%;
border-collapse: collapse;
position: relative; /* Required #1 */
}
td {
height: 60px;
text-align: center;
background: #EEE;
border: 1px solid #CCC;
}
tr:nth-child(even) td {
background: #DDD;
}
td:nth-child(1) {
padding: 0; /* Required #2 */
width: 30%;
}
/* Required #3 */
td:nth-child(1)::after {
display: block;
content: ' ';
width: 100%;
margin-bottom: -1px;
position: absolute;
border-bottom: 2px dashed;
}
td:nth-child(2) {
width: 50%;
}
td:nth-child(3) {
width: 20%;
}
/* Required #4 */
span {
display: flex;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
}
<table>
<tr>
<td><span>Row 1, Cell 1</span></td>
<td>Row 1, Cell 2</td>
<td>Row 1, Cell 3</td>
</tr>
<tr>
<td><span>Row 2, Cell 1</span></td>
<td>Row 2, Cell 2</td>
<td>Row 2, Cell 3</td>
</tr>
<tr>
<td><span>Row 3, Cell 1</span></td>
<td>Row 3, Cell 2</td>
<td>Row 3, Cell 3</td>
</tr>
</table>
This works because the border is attached to a psuedo element with a position of absolute that takes its width from the table, rather than being bind purely to the cell.
There are four main areas to be aware of (commented in the CSS):
The table has position: relative so the line adapts to that width; unfortunately you can't apply it on a table row.
The first cell of each row should not have any padding, otherwise the line may not be flush with the bottom of the row; if you require padding, then this can be defined in #4.
This creates the line itself; it's basically a pseudo element of position: absolute, with a width: 100% to stretch across the table. I have also added a negative margin half the size of the border so it sits nicely in between the two rows. You may also notice that there are no top/left/right/bottom properties; this is so that the element remains where it was before the absolute positioning.
This is the element inside the first cell of each row; the main thing is to add height: 100% so it forces the line created at #3 to be at the bottom of the row. After that is considered, you can style it however you like.
The standard border inside the td is not required; I've included that to demonstrate where the cells are.

Related

How do I get 2 table cells to be the same length with different amounts of text?

I am trying to create a key for a data table I made.
I want the key to be dynamically sized to take up the rightmost 20% of the screen. I also want all the table cells to be the same length and stretch across the entire key (20% /2 = 10% of the screen).
If the text is longer than 10% of the screen (or 50% of the table), I want it to be clipped at the end of the first line so that it doesn't distort the key.
I am going to style the empty td's in css and give them background colors, and the other td's will describe what that color represents in my data table (like a key on a map). My problem is, when I try to run this code, the empty td shrinks in order to show the text of the other td in the row.
How do I prevent this and force both of the td's to always be the same length?
.key {
float: right;
border-style: double;
width: 20vw;
white-space: nowrap;
overflow: hidden;
}
.key td {
width: 10vw;
border: 1px solid #003C63;
}
<div class="key">
<table>
<tr>
<td></td>
<td> = all times</td>
</tr>
<tr>
<td></td>
<td> = some times</td>
</tr>
<tr>
<td></td>
<td> = no times</td>
</tr>
</table>
</div>
You have to set the width of the table (not the div wrapping it) and the table-layout: fixed style.
I simplified your code by removing the div and add the key class directly to the table element.
.key {
float: right;
border-style: double;
width: 20vw;
table-layout: fixed; /* <------- added */
white-space: nowrap;
overflow: hidden;
}
.key td {
width: 10vw;
border: 1px solid #003C63;
}
<table class="key">
<tr>
<td></td>
<td> = all times</td>
</tr>
<tr>
<td></td>
<td> = some times</td>
</tr>
<tr>
<td></td>
<td> = no times</td>
</tr>
</table>
For further explication, check out this Stack Overflow post: https://stackoverflow.com/a/17358739/6691953

space before a table ONLY IF the table is printed

I'm creating a report card for grades K-6 which prints certain tables based on the student's grade. For example, a 5th grader wouldn't have "Reading Stage" displayed on the report card, but a 1st grader would. I've got the styles formatted correctly to conditionally print the tables, but it's the spacing in between the tables I'm struggling with.
I want there to be a standard amount of space between tables, so I've tried things like adding a blank row as the first row of the table, or adding margin-top=50pt. Everything I've tried results in space added for ALL tables, even the hidden ones, so there is sometimes 200 points of dead space between tables. Not good.
I need a (creative) way to conditionally add space ONLY IF the table is going to be printed.
I'm unsure as to how you're hiding your tables. If you hide them via the HTML5 hidden attribute or display: none, no top margin would interfere with your layout.
If for some reason you can't hide your content in one of these ways, CSS negation could be helpful. In this example, I'm saying that all tables not of a certain class should have margin-top: 1em.
table:not(.skip) {
margin-top: 1em;
}
.skip {
position: relative;
background-color: yellow;
}
.skip::after {
position: absolute;
top: 3px;
left: 150%;
content: ' <-- no margin-top';
white-space: nowrap;
}
<table>
<tr>
<td>table</td>
</tr>
</table>
<table class="skip">
<tr>
<td>table</td>
</tr>
</table>
<table>
<tr>
<td>table</td>
</tr>
</table>
<table class="skip">
<tr>
<td>table</td>
</tr>
</table>
<table>
<tr>
<td>table</td>
</tr>
</table>
I know the above has already answered but were you aware of #media print css? You could add some conditional print css that would only be applied when you are printing.
// only for testing, you can print normally without this. It is just for stackoverflow testing...
$("#testPrint").on("click", function() {
window.print();
});
#media print {
/* styles go here */
.myTables {
background: orange !important;
margin: 100px !important;
border: 1px solid black !important;
width: 500px;
}
}
.myTables {
background: pink;
border-collapse: collapse;
border: 1px dashed black;
padding: 5px;
margin: 5px;
text-align: center;
}
<!-- you dont need this javascript either -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<div id="wrapper">
<table class='myTables'>
<tr>
<td>test1</td>
<td>test2</td>
</tr>
</table>
<table class='myTables'>
<tr>
<td>test1</td>
<td>test2</td>
</tr>
</table>
<table class='myTables'>
<tr>
<td>test1</td>
<td>test2</td>
</tr>
</table>
</div>
<button id="testPrint">TEST PRINT</button>

div inside table row not expanding 100%

I am appending a div in a table after table row,Its is not expending 100%,but always stick to first td.
<div style="width:100%;border:1px solid red;height:30px;">Test Div</div>
Note: i can place my div inside td by using colspan,but i have dynamic no of table columns,so i think i can't use colspan
Can you guys have please look at this ?
Logically you can not append DIV in between rows of table. If you want to have a div having 100% of width then use colspan property on TD and then add div in it.
Below is example as per your table structure, you need to have a new row as shown below instead of only DIV :
<tr>
<td colspan=6>
<div style="width:100%;border:1px solid red;height:30px;">Test Div</div>
</td>
</tr>
As pointed out by Nishesh Pratap, the right way to do it is to add dynamic colspan value.
But if you really want to go the CSS way only, you can play with the white-space rule. It will allow your text to overflow above the next TDs.
Keep in mind that this rule will also allow the text to overflow outside the table.
.forbidWrap{
white-space: nowrap;
border: 1px solid blue;
display: inline-block;
}
table{
table-layout: fixed;
width: 600px;
border-collapse: collapse;
text-align: left;
position: relative;
}
th{
background-color: #666;
color: white;
}
td{
border-bottom: 1px solid #ccc;
}
<table>
<tr>
<th>head</th>
<th>head</th>
<th>head</th>
<th>head</th>
</tr>
<tr>
<td>
<div class="forbidWrap">
The content of this div will overflow on other columns
</div>
</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>7282</td>
<td>782</td>
<td>785</td>
<td>1589</td>
</tr>
</table>

Why are table borders not collapsing when caption is positioned?

In this fiddle http://jsfiddle.net/jnddfyeq/ I have two tables with border-collapse: collapse. In the first one everything works as expected. In the second one I position the caption with position: absolute and now the borders between the thead and tbody do not collapse.
This happens in Firefox 38 and IE8 (not in a fiddle.) I have not tested other browsers. Is this behavior standard? If so why?
UPDATE: Same thing happens in Safari.
It's not really that the borders don't collapse. It seems that what's happening is that even if the caption is displayed out of the table, there is still an invisible cell being added to the table.
The specification mention that this can happen, it's not exactly clear what should happen in this case, but it's clear that a table follows a pretty strict layout structure and that it will compensate in the background when messing with that layout. See:
Note. Positioning and floating of table cells can cause them not to be
table cells anymore, according to the rules in section 9.7. When
floating is used, the rules on anonymous table objects may cause an
anonymous cell object to be created as well.
Here: http://www.w3.org/TR/CSS2/tables.html#table-layout
If you look at the computed style of your absolute caption you'll see it's not a cell anymore, so it's probably replaced by an anonymous cell. And I guess that since table head are always at the top by definition, this anonymous cell is placed automatically below it, in the table body group. If you set coordinates to 0, you'll see exactly where it ends up. And if you play with borders, you'll see also what happens.
See snippet:
console.log('first caption:', window.getComputedStyle(document.getElementsByTagName('caption')[0]).display, '\nabsolute caption:',
window.getComputedStyle(document.getElementsByTagName('caption')[1]).display)
body
{
margin: 0;
}
table {
border-collapse: collapse;
margin-bottom: 1em;
border-spacing: 12px;
background-color: yellow;
margin-left: 0px;
}
th {
padding: 0.5em;
border: 10px dotted green;
background: #8cf;
}
td {
padding: 0.5em;
border: 15px dotted red;
background: #8cf;
}
caption.abs {
position: absolute;
left: 0;
}
tr
{
background-color: pink;
}
table.realnoncollapse {
border-collapse: separate;
margin-bottom: 1em;
border-spacing: 12px;
background-color: yellow;
}
<table>
<caption>Chill Table</caption>
<thead>
<tr id="tr1">
<th>Chiller</th>
<th>Chillness</th>
</tr>
</thead>
<tbody>
<tr>
<td>The Dude</td>
<td>Way chill</td>
</tr>
<tr>
<td>This Guy</td>
<td>Pretty chill</td>
</tr>
</tbody>
</table>
<table>
<caption class="abs">No chill</caption>
<thead>
<tr >
<th>Chiller</th>
<th>Chillness</th>
</tr>
</thead>
<tbody>
<tr>
<td>The Dude</td>
<td>Way chill</td>
</tr>
<tr>
<td>This Guy</td>
<td>Pretty chill</td>
</tr>
</tbody>
</table>
<table class="realnoncollapse">
<caption class="abs">No chill</caption>
<thead>
<tr >
<th>Chiller</th>
<th>Chillness</th>
</tr>
</thead>
<tbody>
<tr>
<td>The Dude</td>
<td>Way chill</td>
</tr>
<tr>
<td>This Guy</td>
<td>Pretty chill</td>
</tr>
</tbody>
</table>

Table cell highlighting (adjucent cells) - misleading

I've to highlight multiple cells by adding a class called active to td. This class will change the border colour to highlight the cell.
The problem here is if the top, right, bottom and left cells of a particular cell is selected then the center cell will appear to be highlighted even though it is not actually highlighted.
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 class="active">3.2</td>
<td>3.3</td>
<td class="active">3.4</td>
<td>3.5</td>
</tr>
<tr>
<td>4.1</td>
<td>4.2</td>
<td class="active">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;
border-style:double
}
Here cells 2.3, 3.2, 3.4 and 4.3 are highlighted but 3.3 is not highlighted, but visually it appears to be highlighted.
Can anybody suggest a way to solve this problem?
You can use
table {
table-layout: fixed;
border-spacing: 2px;
border-collapse: separate;
}
however it will pad the cells. If you don't want your cells to pad you can alternatively use a background to highlight the cells.
Demo:
table with cell padding
table with cell highlight