Applying a background image to a table row

Applying CSS to a table can certainly be one of the more frustrating exercises out there. Applying a background image to a table row is one of those. Consider this an addendum to my previous post Designing Data.

In reviewing the CSS spec for tables, it seems to indicate that one should be able to apply a background image to a table row much like applying a background to any specific cell or to the table at large.

However, only Firefox 1.0.3 (and likely all the way back to 1.0) managed to apply the background correctly. In both IE 6 and Opera 7.54, the background image that is declared on the row gets applied to each cell contained within. This creates an ugly repeating pattern that is rather troublesome.

I don't have a solution as of yet (although, if you have any insight, please post a comment) but I'll be working on this some more in the morning.

Published May 03, 2005 · Updated September 17, 2005
Categorized as HTML and CSS
Short URL: http://snook.ca/s/360

Conversation

26 Comments · RSS feed
Bernie Zimmermann said on May 03, 2005

I spent about a half hour looking into this and couldn't find a single thing on it. The thing is, the little test page I wrote up doesn't even look "right" in Firefox 1.0.3.

Are you really seeing the background image span the inner cells in the 'fox?

If the behavior was consistent in all the major browsers, that would lead me to believe that the spec actually lays out the visible behavior...inner table cells taking on the outer row's background image property.

Seems backwards, but we are dealing with tables here ;)

I tested in Opera 8, IE 6 and Firefox 1.0.3.

Jonathan Snook said on May 03, 2005

I just put together a quick test case and Firefox does seem to paint the background according to spec. If I have a table of 500px wide and a background image of 500px wide then the background image when applied to the row gets painted from edge to edge of the table for each row in the table.

IE6 and Opera 7.54 don't do this. They repaint the image for each cell within the row -- which is NOT what I want. Later today I'll put together a test case that I can post online.

Jonathan Fenocchi said on May 03, 2005

This only works in Firefox if the document is in standards-compliant mode (and, more specifically, has a doctype). I didn’t test in XHTML, but that’s how it is in HTML.

Interesting find, Jonathan. I don’t forsee any CSS-only solution, though, unfortunately. Who knows, though. Give someone like Eric Meyer this kind of a problem, and I’m sure they’ll come up with some funky, logically correct technique to solve it.

Josh said on May 03, 2005

I am at my real job, supposed to be doing other things, so I can't try this out, but by any chance are the <td>s inheriting the bg image from the <tr>? would a:
td {
background:none;
} work?

Do you have a test page live?

Bart Noppen said on May 03, 2005

I was going to recommend trying Josh's idea ...

Jonathan Snook said on May 03, 2005

Josh/Bart, that makes sense — good suggestion. Especially since Netscape 4 had a similar issue with tables inside tables. But, at least in IE6, it didn't fix the problem. It removed the background altogether.

Bart Noppen said on May 03, 2005

Jonathan,

if the height of each table row is the same, you can try adding an y-repeating bg image to the whole table ?

Jonathan Snook said on May 03, 2005

Yeah, that would have been nice, but no, each row could have a variable amount of text.

I ended up creating a class for each cell of the row and applying a different background to each cell to create the effect that I needed. Although, in retrospect, I should have looked into applying the background to the <col>.

Dennis said on August 04, 2005

I just had the same problem with IE. I found that 5 years ago the same problem was with Ns4, while worked fine for ie5+ and Ns6 (from some article).
Opera 8.02 and Firefox 1.0.6 show table's background correctly, while ie6.0.3790.1830 doesn't and repeats it in each cell.
I had to add
CSS:
td.removeBg{
background-image: none;
}
HTML
<td class="removeBg"> ...</td>

and now it seems to work for explorer.

bruceontheloose said on August 25, 2005

I've found (and you prob have, too) that Safari suffers from the same problem IE does, except that

td { background-image: none; }

doesn't fix Safari. Anyone found a solution? Thanks.

andrew said on November 06, 2005

This is the exact problem I have at the moment.

I tried the td {background-image:none} tip but it just removed everything (in IE 6.0)

Did you find a fix for this?
(I'm hoping to avoid implementing a workaround!!)

Dennis said on November 06, 2005

> I tried the td {background- image:none} tip but it just removed everything (in IE 6.0)

What does it remove?
Does it remove all content? try to specify background: transparent, it could help, but I am not sure.

andrew said on November 16, 2005

specifying td {background-image:none} removes the image entirely i.e. it doesn't show up in any cells, so it doesn't appear on the page - - - makes sense really since td is nested inside tr, so the td style overrides the tr style...

I ended up by replacing the row of cells with a single cell spanning all the columns. It works nicely, it just took a few extra lines of code.

Andy said on April 25, 2006

I am not sure if anyone is still looking for a solution to this probelm or not, but as I found this post while I was searching for a work around for the same problem encountered today with IE 7 Beta2 I did work out a solution.

Set the background of the table row using CSS, then create a CSS spec for the TD tag and set the position of the image using background-image and then use percentages.

This worked great for a background image that is used to setup a live data graphing routine.

Francesco said on July 23, 2006

Yes, that work just well, as I've posted some time ago here: http://kywocs.blogspot.com/2006/03/imagen-de-fondo-en-las-filas-de-una.html
but is in spanish, so I think the majority didn't found that post :P

jam.scs said on August 09, 2006

whew... forgive my newbieness to css. is there some chance someone can give an explanation/example that's a bit more detailed than #14 yet more comprehencable than #15 (er, for those of us who no habla espagnol)? thanks, -jam

Andy said on August 09, 2006

Here is about as detailed as it can get. Below is the css listing for both the table row and table cell.

tr.traGraph {
background-image: url(departments/mis/web/trafficStats/images/traBkg.gif);
background-repeat: no-repeat;
background-position: left;
height: 400px;
}

td.traPgGraph {
background-position: 20% 0%;
}

From here is the list for the table indicating where and how the css styles are applied to both the table row and that cell.

<tr class="traGraph" height="400px">
<td width="82"> </td>
<td valign="bottom" align="center" width="32" class="traPgGraph">

I hope this helps to make the solution more clear then it was in my first post.

John Daharsh said on September 20, 2006

Well I found this post trying to remember how I had done this in the past. Stupid IE.

What works - although it is a lot of css - is to reuse the row-by-row background image within each td.

You have to class the rows (if they alternate for example) and the td's

In my case, I had a table with a pretty header and footer, and alternating rows of data within the table.

Here's what the HTML would look like:
[table]
[tr class="head"]
[td class="first"][/td]
[td][/td]
[td class="last"][/td]
[/tr]
[tr]
[td class="first"][/td]
[td][/td]
[td class="last"][/td]
[/tr]
[tr class="alt"]
[td class="first"][/td]
[td][/td]
[td class="last"][/td]
[/tr]
[tr class="foot"]
[td class="first"][/td]
[td][/td]
[td class="last"][/td]
[/tr]
[/table]

Then I have to have 4 images: a header image that matches the width of the table, a default image for the "normal" rows, an alternate image for the alternate rows, and a footer image. Again, in my case all the images were the full width of the table.

Then I need to go css crazy.

Using the header as an example, each type of row needs css something like this:

/* default non-edge cell in the row, assuming all the columns except the edges are the same */
.head td
{
background-image:url{header-image.gif};
background-position:center;
}

/* left cell */
.head td.first
{
background-image:url{header-image.gif};
background-position:left;
}

/* right cell */
.head td.first
{
background-image:url{header-image.gif};
background-position:right;
}

you will need to duplicate this for each different type of row - making a fair amount of css.

IE makes me mad... especially since I can't rely on the "class='class1 class2' means of specifying details, which could make this process at least slightly less painful.

John Daharsh said on September 20, 2006

oops, the right cell should have been .head td.last - got in a hurry, sorry.

KurtWM said on September 16, 2008

I found a solution at http://www.mynameisal.com/2008/07/30/background-image-on-table-rows-repeating/

Simply give the TR a "position: relative" attribute and then give the TD a "background-image: none" attribute.

The guy who posted this fix did not know why it worked, but I tried it and it certainly did work in IE7!

nsa119 said on October 31, 2008

wow. it took 2 years for a great answer on this topic. Just in time for my table layout. Thanks for posting Kurt!

mark said on November 03, 2008

And just in time for mine too!
Thanks!

daniel said on November 13, 2008

you cannot use position: relative; if your table is inside a div with a max-height and a scroll:auto; because then the rows would draw beyond the max-height, and they wouldn't scroll. IE7.... sigh.

sarah said on November 14, 2008

works on every other browser except for Mac Safari.

Dalibor said on March 23, 2011

I'm but an amateur, but for me (IE8) worked to remove the <col> tags. I replaced them with a row of height 1 and the columns with the width I needed. To correct for this 1px I shifted the background down by 1 px. (didn't try a row with 0 height). You can see it at www.guideXpert.com, it's the top header.

bdaniel7 said on March 24, 2011

For IE7

<tr class="current">
<td class="project-number">
</td>
<td>
</td>
</tr>

.current td {background: none;}
.current td {background-color: #dcdcdc !important;}
.current td:first-child {background-color: #dcdcdc !important; background: url(../Images/current-item.png) no-repeat 0 0;}

Sorry, comments are closed for this post. If you have any further questions or comments, feel free to send them to me directly.