The following images are the rendering for the same page using the same browser (Chrome 25). The only difference is one page have a DOCTYPE (thus in Standars mode) and one doesn't (thus in Quirks)
Quirks:
Standards:
Both cells have vertical-align: middle, both images are display: inline-block.
Vertical-align is working in Quirks but not in Standards, why?
HTML
<table class="oppres" id="oppscore4">
<tbody>
<tr id="oppscore4-main">
<td><img src="images/gold.png"></td>
<td></td>
<td>0</td>
</tr>
<tr></tr>
<tr id="oppscore4-total">
<td></td>
<td>=</td>
<td>0</td>
</tr>
</tbody>
</table>
CSS
table.oppres{
height: 120px;
}
table[id^=oppscore]{
width: 80px;
font-size: 17px;
line-height: 1;
}
table[id^=oppscore] tr{height: 1em;}
table[id^=oppscore] img{height: 0.9em;}
table[id^=oppscore] tr:nth-last-child(2){height: auto;}
table[id^=oppscore] td:first-child{text-align: right;}
More than enough code to reproduce the issue.
The issue is not about vertical-align on <td> but on <img />
Quirks mode triggers a behaviour explained here:
Vertical alignment of an image is under certain conditions to the bottom of the enclosing box, not to the baseline of text. This happens when the image is the only content within an element, typically a table cell. This means that e.g. an image in a table cell is by default at the bottom of the cell in Quirks Mode (which is often what the author wants), whereas in Standards Mode there is a few pixels spacing below the image (unless one sets e.g. vertical-align: bottom for the img element).
The space you see in standard mode below the image is actually the space between the <td>'s box baseline and bottom (cf. http://www.w3.org/TR/CSS2/visudet.html#leading).
When vertical-align is bottom on <img /> its box' bottom is aligned with <td>'s box bottom, so there is no space anymore.
Related
Dear css experts: In my field, it is common to denote statistical significance with *'s on the numbers. I know I could put all stars in their own td field and then use css so that numbers are aligned, but I was wondering if this can be done in native css. the intent is to have an ability to realign numbers:
<html>
<head> <style type="text/css"> td { text-align:right; } </style> </head>
<body>
<table>
<tr> <th>c</th> </tr>
<tr> <td>1</td> </tr>
<tr> <td>11</td> </tr>
<tr> <td>111</td> </tr>
<tr> <td>1111</td> </tr>
<tr> <td>11<sup style="text-width:0pt">**</sup></td> </tr>
</table>
</body>
possible?
Yes, it’s possible, and it’s a novel idea (at least new to me). The idea is apparently to have a column with numbers, aligned to their last digit, but with one or more characters (here, asterisks) to the right of some numbers. Wrapping those characters to an element, setting the element’s width to zero, and letting the content overflow (overflow: visible, the default) does the job. However, the width needs to be set using the width property, which has no effect on inline (text-level) elements, and sup is inline by default, so this needs to be fixed by making it an inline block (which is affected by the width property):
<style>
td { text-align:right; }
.after { display: inline-block; width: 0; }
</style>
...
<tr> <td>11<sup class=after>**</sup></td> </tr>
I have used the same markup as in the question. However, the sup element has several technical problems (e.g., it may cause line misalignment), so I would use span instead. You can style it in superscript style if desired. But e.g. Chicago Manual of Style, clause 3.78, uses simple asterisk “*” characters in text in this context, with no attempt at raised position or reduced font size. The point is that in any many commonly used fonts, the asterisk itself is, by typographic design, superscript-like: above the baseline and relatively small.
Here’s a screenshot of a test that uses this technique, first with sup, then, on the last row, with span. The font is Cambria.
If I understand you correctly, you want to add '*' via css. You can do this:
td:after {
content: '*';
font-size: .8em;
vertical-align: top;
}
DEMO
I have this piece of HTML that I want to style.
The html is a table (and actual table), which I want to give a border.
The element also had a :before pseudo-element, which I use to put a small triangle in the top corner.
The JSFiddle is here.
I hope it makes sense. I stripped down the markup and the CSS as much as possible, because it's actually a small part of a big site.
http://jsfiddle.net/GolezTrol/28yDb/2/
Now the problem is that the combination of having 2 columns, having border-collapse: collapse; on the table and the :before pseudo element, cause the top border of the element to partially disappear. It's only there for the length of the first column.
You would assume that it is the pseudo element that is on top of the border, but this element is very small, and as far as I can tell, this could not be the problem. I added visibility: hidden; to the pseudo element to be sure, and I can tell that the triangle is gone, but the border is still incomplete.
Unfortunately I cannot change the markup, since this is outputted by MediaWiki, but I do have full control over the CSS.
The HTML:
<div id="globalWrapper">
<div id="column-content">
<div class="thumb tright">
<table class="infobox vcard" style="">
<tbody>
<tr>
<th colspan="2" class="fn org" style=""> Example text</th>
</tr>
<tr>
<th>Row head</th>
<td>Content</td>
</tr>
The CSS:
/* Generic table styling */
table {
border-collapse: collapse;
/*border-spacing: 0;*/ }
/* The box */
.thumb.tright table.infobox.vcard {
border: 3px solid #fae104;
position: relative;
}
/* Triangle */
.thumb.tright table.infobox.vcard:before {
content: "";
position: absolute;
width: 0;
height: 1px;
border-top: 5px solid transparent;
top: -7px;
border-left: 10px solid #555;
visibility: hidden;
right: -1px; }
I already found out that it works when I remove border-collapse: collapse;, but I'm not sure that is a proper solution, and even if it is, I would really like an explanation of what is going on.
Btw. I got this problem both in Chrome 29 and in Internet Explorer 10. Haven't tested other browsers.
Update
Instead of using -or not using- 'border-collapse' to fix the problem, I found out that this also works:
.thumb.tright table.infobox.vcard tbody {
display: block;
}
So the table itself is still a table, the pseudo element is still on the table, as is the border, positioning etc. The tbody, which was unstyled before, is now a block and the problem is solved in both browsers. I found this by trial and error, and still wouldn't know the reason behind it.
Updated fiddle: http://jsfiddle.net/GolezTrol/28yDb/9/
Being a newbie to StackOverflow and jsFiddle I updated the Fiddle with that I think is the solution. I didn't change the CSS except for moving the pseudo class from the table itself to the table header, and changing it into :after. Works for me in Firefox and Chrome!
/* Triangle */
.thumb.tright table.infobox.vcard th:after { }
Border-collapse: seperate is not supported in IE8 but I think this will be.
edit: nevermind ;)
It is a problem only occur on Webkit browsers I think. It can be considered a "browser bug" imo.
th should be inside thead, not tbody:
<thead>
<tr>
<th colspan="2" class="fn org" style=""> Example text</th>
</tr>
</thead>
<tbody>
<tr>
<th>Row head</th>
<td>Content</td>
</tr>
<tbody>
And I think this is the correct solution. You are putting an element where it is not advised to be, so it should be normal for a problem to occur.
Edit: as thirtydot pointed out, changing the th to td doesn't change the result. It only work when I moved the th to the thead section. At this point I am at a loss, I can't find a way to solve this.
But at least I think I can provide my speculation on the cause of this problem:
:before create a pseudo element inside the target element. What kind of element is unknown to me, but I suspect that the browser create a td. If that is true, then after rendering your html should look like this:
<table>
<td></td> /*the pseudo element*/
<tbody>
<tr>
<th colspan="2" class="fn org" style=""> Example text</th>
</tr>
<tr>
<th>Row head</th>
<td>Content</td>
</tr>
<tbody>
</table>
Needless to say this look weird. And if you try the above html out you can see the result is similar to your problem. border-collapse:collapse will merge 2 borders together where there are 2 cells next to each other, or a cell is next to the table's border. So I suspect in this case, the pseudo element - which doesn't have appropriate colspan - last only 1 column, the rest of that row is empty: nothing's there. This is where I think caused the bug: because there's no cells next to the table border there, no border is created at all.
The real reason may be a little bit more complicated ("why doesn't the bug occur when I put in a thead?"), but I think my answer is not too far off the mark. :)
The only reasonable explanation I can think of is pseudo-element :before not being compatible with the display: table of the table in collapsed mode. That is why border-collapse: separate; solves the problem. Suddenly, the browser can display the top border not caring about the pseudo element.
If you look closely, you can clearly see that the missing part of the border is the width of the second column. If you change it to after pseudo element, the border is missing in the bottom-right corner, again due to the fact that the borders of the table and the pseudo-element are collapsed.
If you change the border-bottom of th to be 3px solid red in collapsed mode, the th overpowers the table and the border is red. I presume, the power of after and before follow the same rule. It would be nice if someone who knows the specs better came to answer that.
Thinking this way, I do not believe there can be any other solution than:
using separate borders
putting the pseudo element on the parent div
What I inspected is that the pseudo element is actually rendered as block and can be change to table and list-item. However, none of these change the behaviour.
Very random stuff that is actually compliant with Av Avt's answer about where the pseudo element is rendered in regards of the DOM.
If I append the :beofre like this, the border stays:
.thumb.tright table.infobox.vcard tr:before
Obviously, it creates as many new pseudo element as there are rows.
I browsed some other questions, but couldn't find something that fixes my issue.
I created a code snippet here:
http://jsfiddle.net/manoj382/3SeB7/embedded/result/
I have a table with one row and six cells. The width of each td/cell is defined and it matches the width of the image inside of it (the width of each image is defined, too). Everything works fine, but when I zoom in or out in the browser, white gaps appear somewhat sporadically.
I tried removing white space in the code, I defined the width and height, the images are set to display:block, the total width of each cell/image matches the total width of the entire table, which is also defined. The client is being picky about the gaps when zooming, though, and I'm out of ideas.
*This is for an HTML newsletter, which is why I'm using the old school table layout method.
<table width="600" cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td width="31">
<img src="http://placekitten.com/g/31/64" style="width:31px; height:64px;">
</td>
<td width="65">
<img src="http://placekitten.com/g/65/64" style="width:65px; height:64px;">
</td>
<td width="411">
<img src="http://placekitten.com/g/411/64" style="width:411px; height:64px;">
</td>
<td width="64">
<img src="http://placekitten.com/g/64/64" style="width:64px; height:64px;">
</td>
<td width="29">
<img src="http://placekitten.com/g/29/64" style="width:29px; height:64px;">
</td>
</tr>
</tbody>
</table>
The relevant css:
<style type="text/css">
img {display:block !important;}
</style>
While zooming in/out, the browser has to round the box widths to integers. You cannot assume that things will always be properly aligned.
One solution could be to use float: left boxes instead of table cells so that the boxes are always guaranteed to be flush against each other.
Another solution could be to use background images instead of <img> tags as #user1760422 mentioned in a comment above. You could make the images slightly wider than the cells or just allow background-repeat: repeat-x to show a patch of pixels instead of a white strip between the images.
I cannot explain why it's doing this (I'm able to duplicate it on my Mac). But I do have a fix.
For some reason, your table cell with the width of 411 pixels is showing as 412px wide. The image is also showing as 412px wide, even though the image itself is only 411px wide. You can see this if you run Chrome Dev Tools and mouse over the table cell. It will show that it has an actual width of 412 for some reason that I cannot explain.
If I delete the table width of 600 at the top, the problem goes away.
Change this:
<table width="600" cellpadding="0" cellspacing="0" border="0">
to:
<table cellpadding="0" cellspacing="0" border="0">
See: http://jsfiddle.net/3SeB7/1/embedded/result/
The issue is your sliced images are sometimes odd integers. If you change the image slice widths to an even number (and of course in the widths in the img and td tags), it should eliminate the gaps at certain zoom levels.
insted of giving width in the table, try giving the width in the style tag:
Insted of
Try the below
<table style="width:700px" cellpadding="0" cellspacing="0" border="0">
I just had a similar issue. What the browser is doing is increasing the <td> cells so that combined they fill the whole width of the table, which is causing the white space between the image which is XXpx and the td which is now XX.2313px. You can fix this by setting the min-width of all your images to 100%.
Here's something I never thought I'd say: I have a problem in Firefox and Chrome, but it's working fine in IE!
It's very simple, but I don't understand why it doesn't work:
I have a table inside a cell, and I have style="text-align:right" on the cell, but the table is staying left in Firefox and Chrome (in IE it's obediently going to the right...). If I put align=right in the cell tag then it works, but I don't want to do that.
Code is basically:
<table width="1000" border="1" cellpadding="0" cellspacing="0">
<tr>
<td style="text-align:right">
<table border="1">
<tr><td>Hello</td><td>Hello 2</td></tr>
</table>
</td>
<td>Hello 2</td>
</tr>
</table>
I don't want the nested table to be width=100% or anything like that...
Could anyone please explain to me why it doesn't work, and how to fix it, and maybe why it works in IE but not Firefox or Chrome?
My guess is that Chrome and FF are actually the ones rendering it correctly. text-align probably isn't supposed to affect table elements. However, applying float:right to the table will do what you want.
I would like to add that the CSS way to align tables relative to its container is with the margin property.
You must add margin: 0 auto; if you'd like to align it to the center, or margin-left: auto; if you'd like to align it to the right.
As #maxedison says, text-align will work only with inline and inline-block elements, so the other solution is change your inner table to take some of those display values.
You also need to remember that text-align works from 'container-to-content', this means it is normally applied to a container to affect its content (applied to a p to affect its inline content such as the text within), and margin: 0 auto works from 'content-to-container', meaning that it's normally applied to a block element and affects its position related to its container (applied to a div to center it to its parent).
If you want to fix it (not with full functionality), you can write this:
table {
display: inline-block;
}
This makes your table able to be centered with text-align: center;, if applied to the parent element(s).
when you don't want the div to be floating, you may try this :
http://jsfiddle.net/NvEZ8/
<div style="text-align:right;">
<table style="display:inline-block">
<tbody>
<tr>
<td></td>
<td>one</td>
<td>two</td>
</tr>
</tbody>
</table>
</div>
It looks like text-align (with a DOCTYPE html) only affects inline-block in Chrome and not inline only element. Replacing inline-block by inline here and it doesn't work anymore on my Chrome
I've got a problem and I'm desperate for help.
I needed for some reason to render table header and table body separately. Each column and header cell have got same css class (eg. .col1_name). Those css classes have got declared width and text-align, and in that manner i'm making sure that header and table body cells stay aligned properly.
And, everything is OK in IE8 and Firefox. I've got problems with WebKit browsers (Chrome and Safari. Chrome is important for me.) They are rendering width of table body cells 5px less than IE and FF. I could not trace the problem, but I saw that those -5px widths are in Computed styles.
Below are s-shots and some sample code.
IE 8 Is just fine http://img191.imageshack.us/img191/2360/probie8.png
Firefox is just fine http://img705.imageshack.us/img705/661/probff.png
Google Chrome is not so fine http://img199.imageshack.us/img199/5176/probgc.png
Inspecting element ... http://img96.imageshack.us/img96/19/probj.png
<style type="text/css">
.rbr{ width: 45px; text-align: left;}
.sifra {width: 90px; text-align: left;}
.naziv { width: 240px; text-align: left;}
.kolicina {width: 90px; text-align: right;}
.cena {width: 60px; text-align: right;}
</style>
<table id="tableheader">
<thead>
<tr>
<th class="rbr">RB.</th>
<th class="sifra">Sifra</th>
<th class="naziv">Naziv</th>
<th class="kolicina">Kolicina</th>
</tr>
</thead>
</table>
<table id="tablebody">
<tbody>
<tr>
<td class="rbr">1</td>
<td class="sifra">11111112</td>
<td class="naziv">Adelante 3 series</td>
<td class="kolicina">2.00</td>
</tr>
<tr>
<td class="rbr">2</td>
<td class="sifra">86868631</td>
<td class="naziv">Canyon CNR</td>
<td class="kolicina">1.00</td>
</tr>
</tbody>
</table>
Many thanks people for any help!
While I suspect you simply have another declaration overriding the one you expect, try adding a min-width and max-width.
#NSD you got me on right track. I re-re-re-re-viewed my entire code that is working with datagrids, and I found that body table got width set to auto.
So, thank you guys for your time.
Conclusion: if you have same cells width, but different table width (ie. xyz px / auto ) , in Chrome you'll get different cell widths.
Again, thank you for your time.
Did you try to also set margin and padding?
margin: 0;
padding: 4px;
In your code the id is 'table-body' but in the Chrome screenshot it says 'table-bodypozicije'.
Check your css for a definition of 'table-bodypozicije' - this may be overiding your class styles applied to your td's.