Box-Model for inline vs. block elements within a table td - html

I'm using a table to display tabular data, but I need to get the sizing pixel-perfect so that the contents don't end up taking more vertical space than I have available. Also, layout using css alone isn't feasible because I have dozens of elements.
Here is my simple test code:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
table, td, tr, thead, tfoot, tbody, th, tf {
border-collapse: collapse;
margin: 0px;
padding: 0px;
border:0;
line-height:16px;
}
</style>
</head>
<body>
<table border="0" cellspacing="0" cellpadding="0">
<tr style="height:16px">
<td>
<span style="font-size:10pt;">Here is some text</span>
</td>
</tr>
</table>
</body>
</html>
Basically I want the row of the table to take up only 16px, however, in this configuration it ends up taking 17px.
Inspecting the elements in FireBug it shows the span at 15px but the td and tr at 17, yet no padding, no border, etc...
In IE I get the same behavior, however there is a little more information about my mysterious extra pixel or two, seems there is an offset on the span element:
Finally, I can fix the problem by turning my span element into a div, (or by making the span element display:block, or even display: table-cell which I don't really understand). So I don't really need help solving my problem, but I want to understand why inline elements within table cells end up taking more space then they should. I tried google and the w3c spec but couldn't find anything useful.

Could it be something like the line-height of the span?
Edit: I realized that I didn't really answer the question. I did some poking around in Firebug (I'm on a Mac, so no access to IE at the moment), and it looks like it's not the span itself that's pushing the cell's height, but that the line-height of the td does end up controlling the height of the td. The height of the span is only 14px. I suspect that it's the empty text node (show's in IE's dev tools) that's pushing the height. One way to see this is to move the font-size specification up a node or two so that it will apply to the empty text node as well. At least in FB that seems to fix it and demonstrate that the span isn't the issue. (Maybe the empty text node doesn't exist if you use a div instead? Do you even need a span or a div, or could you have your text right in the td?)

Related

How to position elements inside a TD or TH without getting a warning in Firefox?

I'm using an absolutely positioned element in a table header cell. To do this, the TH has to be positioned itself, to make it the child element's offsetParent (in my case, using position:relative). Unfortunately, it appears that current Firefox versions will issue a warning any time a TD or TR is given a position other than static.
With the following minimal table HTML
<table>
<tr><th>head</th></tr>
<tr><td>cell</td></tr>
</table>
and the following minimal CSS rules
th { position: relative } // either of these is enough
td { position: relative } // to trigger the warning
table { border-collapse: collapse }
this warning appears in the console for Firefox 30 and 32:
Relative positioning of table rows and row groups is now supported. This site may need to be updated because it may depend on this feature
having no effect.
(the warning does not appear when the table borders are kept separate)
The source of this message is Firefox's table layout code:
/* static */ void
nsTableFrame::RegisterPositionedTablePart(nsIFrame* aFrame)
{
// Supporting relative positioning for table parts other than table cells has
// the potential to break sites that apply 'position: relative' to those
// parts, expecting nothing to happen. We warn at the console to make tracking
// down the issue easy.
So it seems we get this warning even if we're doing nothing wrong at all, because other sites may rely on the position rule doing "nothing". Is there a way to get rid of this annoying warning? It's basically telling me: Warning, what you're doing actually works!
I was getting the same warning and resolved it by applying positioning to a div inside the th or td rather than directly to the td or th. Not sure why it cares but now I don't need to see it anymore.
td div{position:relative;}
<table>
<tr>
<td>
<div></div>
</td>
</tr>
</table>
Have you tried this?
<table>
<tr><th><span class="pos1">head</span></th></tr>
<tr><td><span class="pos2">cell</span></td></tr>
</table>
css:
.pos1{
position:absolute;
top:25px /* example*/
}
.pos2{
position:absolute;
top:10px /* example*/
}

In ipython notebook, can't hide table borders as usual

The following IPython notebook cell results in a table with a gray background and borders:
from IPython.display import HTML
s="""
<style type="text/css">
table, td {
border-collapse: collapse;
border-style: hidden;
background-color: rgb(240,240,240);
}
</style>
<table>
<tr>
<td>a
<td>b
<tr>
<td>c
<td>d
</table>
"""
h = HTML(s); h
but when the same html content (the content of string s) is the entire body of a plain html file, the table has a gray background and no border (as intended). It appears that the border properties don't work correctly in IPython notebook. Any ideas?
Another puzzle: adding a colgroup to the table and a col to the css selector causes everything but the horizontal rule between rows to disappear in IPython notebook.
This will remove border from the whole table:
create and run a code cell above the table markdown cell, with the following content:
%%html
<style>
table,td,tr,th {border:none!important}
</style>
When a <style> element without the (HTML5) scoped attribute appears in the <body> of an html document, the behavior of the agent is unspecified.
Browsers like Firefox and Opera try to do something anyway, but we can't be sure of the way inheritance, cascading and specificity are accounted for in this fuzzy context.
You have two easy (local) solutions:
add the scoped attribute (works well in Firefox, not so well in Opera, don't know about IE)
<style type="text/css"> --> <style type="text/css" scoped>
The scoped attribute is subject to hot debate, see these for example: On the abominable proposed html5 scoped attribute and Saving the day with scoped CSS.
and of course, add an inline style to your <table> element
Other, more global solutions aren't so good, in my opinion, but it depends on what you want to achieve.
alternatively you can use inline css
<table style="border-style:hidden;border-collapse:collapse;">

Can I make a TR clickable without java script?

I currently have a java script solution to make an entire table row clickable. I need to support the non-java script folks so is this possible without java script?
I can add a a href tag to each cell but that seems like overkill and it also only lets the user click on the contents of the cell.
Any other alternatives to turn an entire table row into a hyperlink?
Not without putting a link inside each cell unfortunately, otherwise it's not valid markup.
You can still make it appear like the "row" is clickable though by making the links display as blocks so they take up the entire cell.
e.g. (jsFiddle)
<table>
<tr>
<td>Some text</td>
<td>more text</td>
<td>more text</td>
</tr>
</table>
tr:hover { background: #ddd; }
td { border: 1px solid #000; border-collapse: collapse; }
td a { display: block; padding: 5px 20px; }
I realise this is an old thread with a perfectly legit solution in Rich's answer. There is however also a way to do this without javascript AND without duplicating your link * the number of columns AND keeping your markup/CSS valid. It took me a while to figure out, so I thought I'd post it here for others that also happen to end up on this thread like I did.
Put the link in the first column:
<table class="search_results">
<tr>
<td>Some text</td>
<td>more text</td>
<td>more text</td>
</tr>
</table>
This is perfectly fine markup, so your only real issue is getting that link to span the width of your table. I did it like this using pretty standard CSS:
table.search_results a {position:absolute;display:block;width:98%;}
Change the width to whatever you want and in principle you are done and dusted. So that is all relatively easy, however if you, like me, have a fluid/responsive layout, and also some standard styling on your links plus some padding on your tables, you are going to need these rules (copied necessary from above and added extra).
table.search_results td:first-child {padding:0;}
table.search_results a {position:absolute;display:block;width:98%;max-width:1272px;font-weight:normal;color:#000;padding:.5em;}
table.search_results a:hover {background:none;}
table.search_results tr:hover {border-color:#25505b;background:#b5d6dd;}
To explain:
The first rule removes all padding on my first td ONLY. By default the padding on my td is .5em.
The second rule adds the same padding back on the link, otherwise you end up with misaligned cell contents. It also corrects a few standard styles I have on my a to ensure the columns all look the same. You could do this the other way around too (add the link styles to your td).
With the last two rules I get rid of the default hover effect on my links, then put it on the tr for any tables with the right class.
This works in the browsers I care about, but you should of course test in those you care about :) Hope I help save someone some minutes with this writeup!
Various browsers may or may not allow you to wrap the entire TR with an href, HOWEVER, even if the browser supports this, it is not valid (X)HTML and the results will vary from browser to browser in a very unreliable way (updates could change behavior as well).
Your best bet is to either use JS, or put an href inside of each cell.

Tables: How to achieve “normal” td widths, but 100% table width?

On our site we have tables containing data. We like the column widths we get with a normal table, but we like the border-bottom of tds to stretch the entire width of the page like we get with CSS: table { width:100% }, as can be seen on a demo table widths page, which renders like this:
Is it possible to achieve the same column widths as with a normal (non-width-100%) table in a table where the border-bottom stretches the entire width?
And no, td { white-space: nowrap } in combination with an extra width: 100% td (see the link above) is not good, as sometimes the tds are long and so we want the tds to wrap exactly like in a normal table.
We need a solution that works in at least IE6-8 + FF.
Btw, is there a better way (tm) of showing HTML snippets than linking to an external page? I can show just source, but having HTML rendered too is very illustrative.
This was originally posted on Webmasters, but following a suggestion there, I now (re)post it here.
I finally figured it out.
My first few attempts dealt with floating <td>s and <tr>s, but apparently I was on the right track but had the wrong element.
I think what you want to do is to float the <tbody>. The <table> will still be 100% width, so it will stretch the whole width of the page, but the <tbody> inside of it will act as a container for everything else, and floating it will release it from the shackles of the size of its <table> container width.
The downside of this is that you won't be able to use <thead> or <tfoot> elements, because you will no longer have any way to align them with the <tbody> content.
Try this out:
table {
width: 100%;
border: 1px #000 solid;
}
tbody {
float: left;
}
td {
border: 1px #000 solid;
}
You can use the new CSS properties min-width and max-width to bound the columns sizes without setting them explicitly.
To get a proportional version of what would be rendered when the table's width is not specified, I think you'd have to let it render normally (remove your table width setting) and then use javascript to read the column widths and resize.
Pulled this example of using jQuery to syncronize the column widths of two tables from another question:
$("#t1").width($("#t2").width());
$("#t1 tr td").each(function (i){
$(this).width($($("#t2 tr:first td")[i]).width());
})
Should be a pretty good starting point for scaling your column widths.
This is pretty ugly and not exactly what you asked for, but it works in Firefox and appears to get the same gist...
<html>
<head>
<style type="text/css">
td{background-color:blue;}
div{border:1px solid red;position:absolute;width:100%;}
</style>
</head>
<body>
<table>
<tr>
<td>asdf<div></div></td><td>hello blah blah</td>
</tr>
<tr>
<td>lorem ipsum dolor si amet</td><td>testing</td>
</tr>
</body>
</html>
I was looking for a similar answer to this question, however I don't understand what you mean by
And no, td { white-space: nowrap } in combination with an extra width: 100% td (see the link above) is not good, as sometimes the tds are long and so we want the tds to wrap exactly like in a normal table.
But anyway, I found a solution to my problem. Not sure if it can be used here, but it solved my problem. Maybe it can be helpful to others.
I didn't add in another td. I just applied 100% to every last td with content.
So I could add a class to every last td to do that, or I could use the last-child selector to do it for me.
Something like:
table
{
width:auto;
}
table tr td:last-child
{
width:100%;
}

IE bug with TD's tables and whitespace?

I have a page that is using tables, in FF etc it works perfect, but in IE7 it causes issues, it's basically where the four corners have a td and and img (its a rounded corner form) .. if I remove the whitespace from the document it fixes the issue.. What actually happens is that it messes up the tables.. it puts a thin white line between the upper tr that holds the 2 corners and the next tr
I need to remove the the whitespace between the img and the TD, is there a better work around, as I have lots and not only that if I reformat the document the problem returns..
Here is a simple example..
<table width="100%" height="418" border="0" cellpadding="0" cellspacing="0" bgcolor="#F04A23"
style="margin: 0px; padding: 0px">
<tr>
<td width="12" align="left" valign="top">
<img src="content/images/corner_left.gif" width="12" height="12" />
</td>
as you can see there is white space between img and td... and I remove it so it looks like this:
<img src="content/images/corner_left.gif" width="12" height="12" /></td>
the problem is gone, (notice the td and image are right next to each other)
Any ideas, I tried setting all sorts of css, padding 0px, margins 0px etc ...
Any ideas really appreciated.
As it turns out, removing the whitespace is NOT the only way to fix it. Everyone else has probably figured this out by now, but I figured I'd add it here for completeness for the next poor soul that stumbles across this annoying problem.
Basically, you don't have to worry about the whitespace in your markup. Instead, add style="display:block;" to the img tag. Since images are inline elements, and you have whitespace in your markup, IE adds the extra whitespace to the bottom of the cell to account for the possibility of text with decenders (e.g. g, y, p, etc.). Setting the img tag to display as a block element takes care of this. No more ugly whitespace!
Credit goes to this guy: http://blog.wheelerstreet.com/ie-white-space-issue-with-td-and-img-solved, which is where I found the answer. Guess he got it from a google discussion group or other.
Hope that helps!
The only way to "fix it" (and I use that term loosely) is to remove the whitespace.
More importantly, you should stop making websites like it's 2001. :)
I've fixed adding this before the end of table:
<tr>
<td height="0"><img src="pixel.gif" width="0" height="0" alt=""></td>
</tr>
Hope this help.
This drove me nuts for a while - moving from IE 8.0 to IE 9.0 on intranet sites - all images suddenly had a bit of white space beneath them.
Setting display:block on the images did it for me.
I tried all solutions above:
a) tried the display:block
b) removed white spaces in td tags (ie I used tr and td tags without white space inbetween them. )
c) I tried using:
padding:0px;border-spacing:0px;border-style:none;border-collapse: collapse;margin:0;overflow: hidden;
Solution a) worked. Solutions b) and c) did not work on IE.
But the BEST SOLUTION I found is this:
Add a hspace=0 attribute to the Image tag. For example:
<img src="http://www.printersrose.com/css/myimages/book1.jpg" alt="Header1" class="ImageHeader" hspace="0" />
This does the trick.
IE finds that there is text content inside the TD (other than the image), so it gives it its text line-height. Try setting a height and overflow: hidden for the TDs.
It's been this way for as far back as I can remember, all versions.
For myself, I've never found another way than putting the image and td on the same line, but I've never really looked - there may be a way that I've missed. Guess I just got in the habit of streamlining them.
Other (and the best :) ) solution is:
set the td width/height to the image width/height with css
set image to the background for td
Like:
<td style='width: 12px; height: 12px; background: url(corner-left.gif) no-repeat;'></td>
It works form me :)
(sorry for my english :"> )
Another late response, but you could also use line-height: 0; to remove the whitespace.
To ensure that text will still be readable you could wrap it in another element and use line-height: normal or another value of your choice.
td * { line-height: normal; }
I had this issue too with an intranet site on Internet Explorer, so I turned off the compatibility view mode for intranet sites to fix it: