I am trying to position a span element relative to the upper-right corner of a table object.
This table may be wider or move around based on what the user does on the tool, so I was looking for something simpler than the jQuery.position method. I was hoping to do something elegant with CSS.
I've built a small example of my dilemma in jsfiddle: http://jsfiddle.net/xerf/ZSGfc/
<div>
<table>
<thead>
<tr>
<th colspan="3">Title</th>
</tr>
</thead>
<tbody>
<tr>
<td>Stuff 1</td>
<td>Stuff 2</td>
<td>Stuff 3</td>
</tr>
<tr>
<td>Stuff 1</td>
<td>Stuff 2</td>
<td>Stuff 3</td>
</tr>
<tr>
<td>Stuff 1</td>
<td>Stuff 2</td>
<td>Stuff 3</td>
</tr>
</tbody>
</table>
<span>×</span>
</div>
Below are the CSS Styles
body
{
font-family:sans-serif;
}
table
{
border-collapse: collapse;
border: 1px solid black;
margin: 20px;
}
th
{
padding: 6px;
}
td
{
padding: 3px;
border: 1px solid black;
}
UPDATE: Added some images to show required positions:
Needs to be where the red Square appears above
I wrapped your span in a div and placed it in the <th> with your title:
<th colspan="3"><div id="container">Title
<span>×</span></div></th>
css:
#container{
width:auto;
height:auto;
position:relative;
}
span{
position:absolute;
right:0px;
top:0px;
Here is a demo: http://jsfiddle.net/ZSGfc/6/
A very simple way would be to simply add another row to the very top of the table, removing its left, top and right borders. Then move your span so that it is contained by this new row and align the text to the right.
I would recommend using the div or adding another div that will control the width of the table, and then have the table inherit the width of that div. From there make the div's position property set to relative. Then you can absolutely position the span on the div.
Something similar to this fiddle. With some tweaking.
Try this:
div{
position:relative;
width: XXXpx;
}
table{
width: XXXpx;
}
span{
position: absolute;
top: 0px;
right: 0px;
}
an additional table cell on top with colspan="3" and text-align:right would work.
Related
I'm building a table for my website, and I'm trying to place a logo inside of a data cell. The issue is that whenever I add the picture, the margins go really weird and I can't figure out why spacing is added. I tried to remove the padding and margins on the image, and the cell itself, but nothing fixes it.
Before image:
After image:
HTML:
<table class="table">
<thead class="tablehead">
<tr>
<th>Language</th>
<th>Year Initiated</th>
<th>Projects</th>
</tr>
</thead>
<tbody class="tablebody">
<tr>
<td><img src = "images/Java_Logo.png" class="tableimage"></td>
<td>2015</td>
<td>ENTER LINK</td>
</tr>
<tr>
<td>C#</td>
<td>2016</td>
<td>ENTER LINK</td>
</tr>
<tr>
<td>Python</td>
<td>2018</td>
<td>ENTER LINK</td>
</tr>
<tr>
<td>HTML and CSS</td>
<td>2018</td>
<td>ENTER LINK</td>
</tr>
</tbody>
</table>
CSS:
.table{
margin: auto;
}
.tablehead{
font-family: permanent marker;
font-size: 24px;
}
.tablebody{
font-family: body;
font-size: 20px;
}
.tableimage{
width: 15%;
padding:0px;
margin: 0px;
}
th, td{
border-bottom: 1px rgb(146, 40, 40) solid;
padding: 10px;
margin: 0;
}
I've also already tried multiple different images, so this does not seem to be the issue. I'd like all three columns to take up 1/3 of the space each.
Another option is to use this, which changes the behavior of the table overall. (Set your preferred width, or nothing at all):
table {table-layout: fixed; width: 50%;}
You only need to specify a width for the table cells. Try adding this to your CSS:
th, td {
width: 33%;
}
The table must some other css affecting it. When I put your code into JSFiddle, it seems to work the way you want. See example: https://jsfiddle.net/ruben/xg2joc1y/5/
You could try adding some css to your image:
.table img {
display: inline;
}
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>
Alright, so I have two tables set up, one outside the other. In order to make it display properly, I had to put the inner table within tags. Problem is, I want the inner table to completely overlap the outer table's borders on the top, left, and right. Here, look at this JSFiddle:
http://jsfiddle.net/26Fnm/15/
html:
<body>
<table class="main-body round">
<tr><td class="nopad">
<table class="header round">
<tr>
<td class="header">Test Text 1</td>
</tr>
<tr>
<td class="header2">This is a longer test text two.</td>
</tr>
</table>
</td></tr>
<tr>
<td>Line 1</td>
</tr>
<tr>
<td>Line 2</td>
</tr>
<tr>
<td>Line 3</td>
</tr>
<tr>
<td>Line 4</td>
</tr>
</table>
</body>
CSS:
body table.round
{
border:2px solid;
border-radius:25px;
}
.main-body td.header
{
text-align:left;
padding-left:50px;
color:white;
font-size:50px;
}
.main-body td.header2
{
text-align:right;
padding-right:30px;
color:white;
font-size:30px;
}
.nopad
{
border-spacing: 0px;
padding: 0px;
}
table.header
{
background-color:#151515;
width:100%;
}
.main-body
{
border-spacing: 0px;
border-collapse: separate;
color: #202020;
margin-left: auto;
margin-right: auto;
width: 600px;
background-color: #d2ffdc;
box-shadow: 10px 10px 10px #101010;
}
#navi
{
}
You can see, in the upper left and right corners, a bit of the green coming out between the two tables' borders. Not only do I want that to be gone, I want those two borders, on the top, left, and right, to essentially be one border, they are so overlapped. Like if I were to copy paste those two tables on top of each other, and they were exactly the same width. I've tried border-spacing, I've tried no padding, no margin, changing the size of the borders. Nothing has brought me close to where I want to be.
Is this even possible? Or do I have to settle for the appearance of overlapping with the inner table not having a border?
On a side note, why the heck does a JSFiddle link need code accompanying it? The code is there on the JSF page!
Something like this?
Fiddle
table, tr, td{
border-collapse: collapse;
}
table.header2
{
background-color:#151515;
width:100%;
border-radius:20px;
padding: 0;
margin: 0;
}
.nopad {
border-spacing: 0;
display: table-cell;
padding: 2px;
}
As the title says my table border is being cut off on my table when using overflow: hidden. Please see code below for example.
<style>
table {
border-collapse: collapse;
}
table {
border: 1px solid black;
overflow: hidden;
}
</style>
<body>
<table>
<thead>
<tr>
<th>header 1</th>
<th>header 2</th>
<th>header 3</th>
</tr>
</thead>
<tbody>
<tr>
<th>side header</th>
<td>data 1</td>
<td>data 2</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>footer header</th>
<td>footer 2</td>
<td>footer 3</td>
</tr>
</tfoot>
</table>
</body>
</html>
I have simplified my example down the the bare minimum. I could lose the border-collapse style which would correct this, but I need that style. My code becomes to messy without it.
As an interim solution I have found that I can hack it using the css below, but I am not a hug fan of hacks!
.borderhack:after {
content: '\00a0';
position: absolute;
border: 1px solid black;
left: -2px;
top: -2px;
width: 100%;
height: 100%;
z-index: -10;
}
table {
position: relative;
}
I would appreciate any explanations or better solutions to this. I am really interested to know why it's actually doing this after a days worth of investigation.
Thanks
There are two quick solutions:
Use 2px border width.
Use outline instead of border.
Eg:
table {
border-collapse: collapse;
border: 2px solid black;
overflow: hidden;
}
or
table {
border-collapse: collapse;
outline: 1px solid black;
overflow: hidden;
}
http://jsfiddle.net/6NVtS/1/
The why of it happening, I think, is that when using the collapsed border model of table borders the browser is trying to split the border in the center. On a one-pixel outside border obviously that's not possible, so the browser is using a full pixel width if top/left, and nothing if bottom/right. This behavior might be somewhere in the standards, I didn't look that far. But inside this will correctly fill out the borders without doubling up width, it's just the combination of the outside and overflow:hidden that's presumably cropping the bottom and right, which the browser generates but are technically nudged a half-pixel to the right and thus are 'outside' the region of the element. I hope that makes sense. Outline is not cropped by the overflow - I'm not sure why, I wouldn't have predicted an exception.
http://www.w3.org/TR/CSS21/tables.html#collapsing-borders
Another solution might be to apply overflow to td and th instead of table, or check if you really need to set overflow at all.
What's the point in using border-collapse if there are no borders to collapse? Remove the border-collapse and you'll be fine.
See working example here: http://jsfiddle.net/86xST/
Thanks to skrivener and some further investigation I have managed to figure this out. See the solution here.
Problem - border collapsing not equal around table border:
.table1 {
border : 3px solid black;
overflow : hidden;
border-collapse : collapse;
}
Solution - must not declare border width in border must do it using border-width:
.table2 {
border : solid black;
overflow : hidden;
border-collapse : collapse;
border-width : 6px 7px 7px 6px;
}
th {
border: 1px solid black;
}
th {
border: 1px solid black;
}
Problem:
<table class="table1">
<thead>
<tr>
<th>header 1</th>
<th>header 2</th>
<th>header 3</th>
</tr>
</thead>
<tbody>
<tr>
<th>side header</th>
<td>data 1</td>
<td>data 2</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>footer header</th>
<td>footer 2</td>
<td>footer 3</td>
</tr>
</tfoot>
</table>
Solution:
<table class="table2">
<thead>
<tr>
<th>header 1</th>
<th>header 2</th>
<th>header 3</th>
</tr>
</thead>
<tbody>
<tr>
<th>side header</th>
<td>data 1</td>
<td>data 2</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>footer header</th>
<td>footer 2</td>
<td>footer 3</td>
</tr>
</tfoot>
</table>
Skrivener:
"The why of it happening, I think, is that when using the collapsed
border model of table borders the browser is trying to split the
border in the center. On a one-pixel outside border obviously that's
not possible, so the browser is using a full pixel width if top/left,
and nothing if bottom/right."
This let me to believe that perhaps if I just set the 4 borders setting border-width manually and added 1px to the right and the bottom, the rounding would work correctly. See the solution and you can update the borders to see it works correctly. Now no matter what you can have equal width outer borders as long as you add 1px to the right and bottom borders.
Thanks again for all the help!
Try following
1. give margin to your table
2. User table-layout: fixed
3. set
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.