But what about cellspacing?
Cellspacing can also be omitted if you work with the border-collapsing model, because IE supports this model in CSS. (Or maybe not; we'll come back to this later.) Anyway, just put border-collapse: collapse in your table's style, and all the space between your table cells will be gone, and the adjacent borders will collapse to one simple border.
(For those of you who didn't fully get the picture, here is a nice illustration of the two border models.)
Problems will arise when you want to use the separated borders model. In this mode the CSS engine (browser) is expected to apply the td border styles separatedly to every single table cell, just as these were simple divs. We can think of this as the normal behaviour, and the collapsing model as a special case, if only because that the former is the initial (default) value in the CSS specs. When you're in the 'separate' model, you can control the space between your table cells with the border-spacing value of the table. You can set the horizontal and the vertical spacing.
But the problem is that IE doesn't support the CSS border-spacing attribute. Instead it puts a fixed 2px space between the cells. This is the point, where normally a developer gives up, becomes a bit melancholy, and puts back the cellspacing attribute into the HTML code. The conclusion: cellspacing can't be controlled by CSS (cross-browser).
Some good news
However, there is some consolation: generally you don't need that. Usually we only need to eliminate that bad looking space between the cells, and this can be achieved by CSS, even in IE. And the good news is that not only in the 'collapse' model but even in the separated!Say, we want a table, in which all table rows have a red 1px bottom border, and a pink 1px top border (we want it to look a bit like buttons). 'Collapse' model is not an option now. This is a situation, where we have to use the 'separate' model with 0-width border-spacing between the cells.
For this the standard CSS code is as follows:
table {
border-collapse: separate;
}
td {
border-top: 1px solid red;
border-bottom: 1px solid pink;
}
It works in the standard compliant browsers, but what about IE?
That's a Feature, Not a Bug
Thankfully, IE is so buggy, that one bug helps to fix an other. So, what to do if I want to achieve a zero-spacing separating model? Exploit the bugs in the collapsing model! IE's border collapsing works fine, but magically gets switched off, if you give a 'position: relative' style to the table cells. If you do this, the browser jumps back to the separated model, width 0 cellspacing! Thx, Mr. Bug.table {
border-collapse: separate;
border-spacing: 0;
*border-collapse: collapse; /* hack is needed for IE7 also */
}
td {
border-top: 1px solid red;
border-bottom: 1px solid pink;
*position: relative;
}
This way, you don't need any of those ugly HTML tag attributes, while working in either a collapsed, or a 0-cellspacing separated borders model. Have fun!
UPDATE
knakts noted in his comment that this workaround provides solution only to those cases in which the border-spacing value is zero. And I felt sympathy for him/her. Thus, as a matter of urgency, I researched another workaround, which brings us closer to the heaven.Here it is:
table {
border-collapse: separate;
border-spacing: 5px;
*border-collapse: expression('separate', cellSpacing = '5px');
}
Still not perfect, because you can't differentiate vertical and horizontal spacing, but, as I said, one small step to the happiness.
knakts, don't be melancholic!
OK -- this is a great post on an obscure topic -- thanks for the info!
ReplyDeleteThanks a lot, this is great hack :-)
ReplyDelete1)Should I use both collapse and separate for class.table?
ReplyDeleteand
2)Is that "*" necessary in both
*border-collapse: collapse;
and
*position: relative; ?
Thanks
David
Hi David,
ReplyDelete1. Yes, you should. Standard browsers will ignore the rules with an "*" before them.
2. Yes, it's a necessary workaround for those rules which are not supported in either IE6 and IE7.
Interesting article. Unfortunately it is not solution for border-spacing other than zero. Now let me get a bit melancholy and put back up the cellspacing...
ReplyDeleteThanks, the "expression" method worked. :)
ReplyDeleteI've been looking for days for a way to get more spacing between cells to simulate border-spacing in IE. This is the best solution I've found. Thanks very much!
ReplyDeleteExcellent solution!
ReplyDeleteThanks.
It is really helpful, thanks
ReplyDeleteWow! Two days trying to figure out a solution to the border-spacing issue and all it needed was one line. This worked for me to make the spaces between cells look the same in IE, Opera, and Firefox.
ReplyDeletetable {
border-collapse: separate;
*border-collapse: expression('separate', cellSpacing = '1px');
border-spacing: 1px
}
So simple.
When you know how. ;-)
Thank you so very much.
Just what I was looking for! Thanks, Martin
ReplyDeleteI tried this solution and it didn't work. IE only said something about blocking active content, asked me if I wanted to allow some ActiveX thing, and when I said 'Yes' nothing happened. Still the default 2px separation.
ReplyDelete@León, this is because JS is disabled on local machine by default in IE. You can test it with any script written in the HTML file. I bet you were working with a local file. CSS expressions are JS.
ReplyDeleteAfter allowing that activeX thing refresh the page, then it'll work.
You will not experience such problems if you work with remote files.
This post provided a very easy solution to a frustrating problem. Thank you for the info.
ReplyDeleteFantastic workaround!!
ReplyDeleteUnfortunately, this work arround leaves you with a css not validated by the W3C CSS Validator.
ReplyDeleteIf it's so important to you, I'll post a workaround how to make your workaroundish css validated by the w3c validator.
ReplyDeleteI used this, which validates fine. Hope it's useful to someone!
ReplyDeleteHTML:
< link rel='stylesheet' type='text/css' href='/css/basic.css' />
< !--[if lte IE 7]>< link rel='stylesheet' type='text/css' href='/css/basic_ie_workarounds.css' />< ![endif]-->
BASIC.CSS:
table { border-collapse:separate; border-spacing:0; }
/* ... etc ... */
BASIC_IE_WORKAROUNDS.CSS:
table { border-collapse:expression('separate',cellSpacing=0); }
There's more CSS reset (browser unification) stuff in basic.css, and more IE workarounds (body->* font inheritance workaround, other) in basic_ie_workarounds.css too.
Now I just need a working, validating, cross-browser block-level anchor element! :-) (Hint: this is impossible.)
In the above comment, there's a space between < and the following character, since this stupid blogging software thinks I want to inject HTML into the comment. So replace "< " with "<" before running the code.
ReplyDeleteAlso, if anyone is wondering whether 'separate',cellSpacing=0 really returns 'separate' and not 0, this little test reveals that both statements are run and the result of the first one is returned. Paste it in the browsers' URL line.
Return value test:
javascript:alert('x',cellSpacing=0);
Run both test:
javascript:alert('x',alert('y'));
and what if your CSS is "border-spacing: 2px 5px;"?
ReplyDeleteIn the IE-fix you can give only one number for cellspacing...
You haven't read the entire post. As for that, and AFAIK, different vertical and horizontal cellspacing is unaccomplishable in IE, either by HTML or CSS or other ways.
ReplyDeletethink i found a way to fix and diferentiate the vertical and horizontal spacing in IE.. :.
ReplyDeletejust give the td a class, position it relative and move it left by -6px; it's kinda weird, but worked for what i needed to do... maybe u can use also td+td .
A lot of hacks for one css though. I think i will use divs...
table tr td.second {
*position:relative;
left:-6px;
}
Ah, thank you!
ReplyDeletethanks!!
ReplyDeletePS u can also use - it's shorter ;)
table.css_class {
border-spacing: 1px;
*border-collapse: expression('separate', cellSpacing = '1px');
}
Perfect, a million thanks.
ReplyDeletePerfect solution for me!
ReplyDeleteThanks.
Thanks, appreciate this.
ReplyDeleteYou are a friggin' genius! T H A N K - Y O U !
ReplyDeleteNot the perfect fix, but well worth mentioning in my blog about dynamic table creation.
ReplyDeletehttp://www.skewsme.com/observations4.html#tables
One and a half year later, still a very useful exploit. Thanks for sharing!
ReplyDeleteAnyone tested this on IE8? Anyway, big thanks, saves me the time I don't have to figure this one out.
ReplyDeleteIE8 fully supports CSS 2.1, so this is not an issue anymore.
ReplyDeleteI am having an issue with Firefox that I can't seem to find a hack for. Check out the Main vertical menu for www.wholesalewarrantyclub.com in Firefox and then in any other browser. It's working the way that I want it to in all browsers except firefox.
ReplyDeleteThe html looks like this:
table border="0" cellspacing="2" cellpadding="0"
and the images are a sprite. Firefox allows some of the background image to show through the 2px cellspacing...and I don't want that.
This is really good...it worked..but have another problem if anyone knows abt it. As per css if we use border-collapse: collapse; it will ignore empty-cells: show. how to achieve that? I mean for IE I am using the star hack provided here (*border-collapse: collapse;, *position:relative and empty-cells: show;) where as empty-cells is getting ignored because of *border-collapse: collapse;. I need both the properties any workaround?
ReplyDeleteThis is exactly what I was looking for, thanks!
ReplyDeleteExcellent post. Just helped me too. Trying to make my ap the same in as many different browsers as possible even older ones like ie6 and have menu that looked fine in all but ie6/7. 3d effect with light border one side dark on other needed border-collapse:sererate but couldn't get the spacing on older ie's down to 0 till now. Have bookmarked your blog and will have a better look through soon to see what other handy snippets are there
ReplyDeleteCheers
Andrew Blake
Thank you for sharing you provided me with a quick solution to the problem!!! Cheers x
ReplyDeleteSweet, the expression worked for IE7
ReplyDeleteThank you, the expression is fantastic for IE!
ReplyDeleteAwesome dude, how did you even discover this hack, hats off!!
ReplyDeleteThanks for this great hint!
ReplyDeleteOnly drawback is, IE only understands px-values. em-values are not interpreted at all :-/
Thank you!! great quick solution for a obscure problem!!
ReplyDeletethanks. this is very useful and it fixed the same problem on IE 9 for me.
ReplyDelete