41

I want to put a line above some field in a table, to indicate that it is a sum of the above values. However, the table already has borders by default.

Here is an example: I have a table with borders collapsed. I set the border-bottom on one field, and the border-top on the field below it. Both of these specify the same border. The CSS for the top one is used. Is there a way to use the bottom one?

<html>
    <head>
        <style type="text/css">
            table { border-collapse: collapse; }
            td.first { border-bottom: solid red 1px; }
            td.second { border-top: solid gold 1px; }
        </style>

    <body>
        <table>
            <tr><td class="first">Hello</td></tr>
            <tr><td class="second">World</td></tr>
        </table>
    </body>
</html>

This shows two cells with a red line between them. Is there way to get a gold line?

Josh Unger
  • 6,717
  • 6
  • 33
  • 55
Sjoerd
  • 74,049
  • 16
  • 131
  • 175
  • 3
    It has to do with the conflict-resolution. [This is a page](http://www.the-art-of-web.com/css/bordercollapse/) that explains how it works and how the browser calculates the different borders. – Justus Romijn Nov 04 '10 at 12:09
  • 1
    I believe there is no CSS solution for this, because the border collapse just does what it does. You can use some workarounds, for example use javascript. Do you have any javascript libraries included in your document? – Justus Romijn Nov 04 '10 at 12:12
  • I solved it using jQuery, using something like this: http://www.mail-archive.com/jquery-en@googlegroups.com/msg89877.html – Sjoerd Nov 04 '10 at 15:29

5 Answers5

72

This is a defined behavior of border-collapse. Page 357 of the O'Reilly CSS Definitive Guide 3rd Edition says:

if collapsing borders have the same style and width, but differ in color, then ... from most to least preferred: cell, row, row group, column, column group, table.

if ... come from same type of element, such as two rows... then color is taken from borders that are the topmost and the leftmost.

So the topmost, which is red, wins out.

One way to override this may be to use cell for the color to win over the color for the row.

example: http://jsfiddle.net/Chapm/

The rules that have higher precedence than this "same color rule is"

wider border wins over narrower ones

and after that,

double wins over solid, then dashed, dotted, ridge, outset, groove, inset

You can use 2px for the gold for it to win over, and I tried in Chrome to use 1px but double, and it appears as 1px solid and it will win over the red as well. Although if you want to use this method, then it may be best to make sure the browsers you support behave the same using this technique.

http://jsfiddle.net/Chapm/2/

Community
  • 1
  • 1
nonopolarity
  • 146,324
  • 131
  • 460
  • 740
  • This indeed solves my problem. However, it does not work in IE7. – Sjoerd Nov 04 '10 at 12:31
  • i updated with more rules... yeah, this is quite specific and may not be the same in all types of browsers. – nonopolarity Nov 04 '10 at 12:32
  • 1
    Thank you so much! I was struggling so bad with this and had no idea what was going on. The `double` trick worked great. I'm using it to show a border around a `TR` on hover. – vaughan Jun 01 '12 at 00:37
  • 1
    Even though its nearly four years old, this is a dandy answer. – David W Jul 24 '14 at 15:22
  • Maybe this rules work in perfect world or in Chrome, but different browsers have different priority rules. It is really sad, in my opinion. – user1561346 Nov 11 '15 at 14:46
  • In CSS2 specification, the "border conflict" behaviour is specified: https://www.w3.org/TR/CSS2/tables.html#propdef-border-collapse (17.6.2.1 Border conflict resolution). Hope all modern browsers support it now. – shaochuancs Aug 03 '16 at 08:48
5

Just change border-collapse to separate and set border-spacing to zero.

Note: IE8 supports the border-spacing property only if a !DOCTYPE is specified.

<!DOCTYPE html>
<html>

<head>
  <style type="text/css">
    table {
      border-collapse: separate;
      border-spacing: 0px;
    }
    
    td.first {
      border-bottom: solid red 1px;
    }
    
    td.second {
      border-top: solid gold 1px;
    }
  </style>
</head>

<body>
  <table>
    <tr>
      <td class="first">Hello</td>
    </tr>
    <tr>
      <td class="second">World</td>
    </tr>
  </table>
</body>

</html>

Tested on win7 with: Chrome 16, IE 9, FF 9, Safari 5.0.5.

Sanchit Patiyal
  • 4,910
  • 1
  • 14
  • 31
Dalius I
  • 943
  • 11
  • 6
  • The OPs question was kinda weird. Not sure if he wanted two borders or not. I got here because I wanted a table with a border on the top and bottom of each ``, but the borders were collapsing. I tried `border-collapse: separate` and there were margins around the cells I couldn't get rid of with CSS. It was the `border-spacing: 0` I was missing. Thanks for your answer. – Gavin Oct 04 '13 at 09:33
1

Remove border-collapse: collapse; from your code, instead set cellspacing attribute to 0 for your table.

Chinmayee G
  • 7,947
  • 2
  • 31
  • 41
1

I know it's an old question but just came across the issue and I solved it like this

table { 
  border-collapse: collapse;
}

td.first {
  border-bottom: solid red 1px;
}

td.second {
  border-top: solid gold 1px;
  position: relative;
}

tr:not(:first-child) td.second::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 100%;
  height: 1px;
  background-color: gold;
}
<table width="280">
    <tr><td class="first">Hello</td></tr>
    <tr><td class="second">World</td></tr>
    <tr><td class="second">World</td></tr>
    <tr><td class="second">World</td></tr>
</table>
Toni Michel Caubet
  • 19,333
  • 56
  • 202
  • 378
0

Just remove the td.first { border-bottom: solid red 1px; } from your style.

Or change red to gold in the td.first selector.

Example here.

Kyle
  • 65,599
  • 28
  • 144
  • 152