Edit - Original Title: Is there an alternative way to achieve border-collapse:collapse
in CSS
(in order to have a collapsed, rounded corner table)?
Since it turns out that simply getting the table's borders to collapse does not solve the root problem, I have updated the title to better reflect the discussion.
I am trying to make a table with rounded corners using the CSS3
border-radius
property. The table styles I'm using look something like this:
table {
-moz-border-radius:10px;
-webkit-border-radius:10px;
border-radius:10px
}
Here's the problem. I also want to set the border-collapse:collapse
property, and when that is set border-radius
no longer works. Is there a CSS-based way I can get the same effect as border-collapse:collapse
without actually using it?
Edits:
I've made a simple page to demonstrate the problem here (Firefox/Safari only).
It seems that a large part of the problem is that setting the table to have rounded corners does not affect the corners of the corner td
elements. If the table was all one color, this wouldn't be a problem since I could just make the top and bottom td
corners rounded for the first and last row respectively. However, I am using different background colors for the table to differentiate the headings and for striping, so the inner td
elements would show their rounded corners as well.
Summary of proposed solutions:
Surrounding the table with another element with round corners doesn't work because the table's square corners "bleed through."
Specifying border width to 0 doesn't collapse the table.
Bottom td
corners still square after setting cellspacing to zero.
Using JavaScript instead- works by avoiding the problem.
Possible solutions:
The tables are generated in PHP, so I could just apply a different class to each of the outer th/tds and style each corner separately. I'd rather not do this, since it's not very elegant and a bit of a pain to apply to multiple tables, so please keep suggestions coming.
Possible solution 2 is to use JavaScript (jQuery, specifically) to style the corners. This solution also works, but still not quite what I'm looking for (I know I'm picky). I have two reservations:
I know that trying to do this with CSS3 today may seem needless, but I have my reasons. I would also like to point out that this problem is a result of the w3c specification, not poor CSS3 support, so any solution will still be relevant and useful when CSS3 has more widespread support.
This question is related to
html
css
rounded-corners
html-table
Here is a recent example of how to implement a table with rounded-corners from http://medialoot.com/preview/css-ui-kit/demo.html. It's based on the special selectors suggested by Joel Potter above. As you can see, it also includes some magic to make IE a little happy. It includes some extra styles to alternate the color of the rows:
table-wrapper {
width: 460px;
background: #E0E0E0;
filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#E9E9E9', endColorstr='#D7D7D7');
background: -webkit-gradient(linear, left top, left bottom, from(#E9E9E9), to(#D7D7D7));
background: -moz-linear-gradient(top, #E9E9E9, #D7D7D7);
padding: 8px;
-webkit-box-shadow: inset 0px 2px 2px #B2B3B5, 0px 1px 0 #fff;
-moz-box-shadow: inset 0px 2px 2px #B2B3B5, 0px 1px 0 #fff;
-o-box-shadow: inset 0px 2px 2px #B2B3B5, 0px 1px 0 #fff;
-khtml-box-shadow: inset 0px 2px 2px #B2B3B5, 0px 1px 0 #fff;
box-shadow: inset 0px 2px 2px #B2B3B5, 0px 1px 0 #fff;
-webkit-border-radius: 10px;
/*-moz-border-radius: 10px; firefox doesn't allow rounding of tables yet*/
-o-border-radius: 10px;
-khtml-border-radius: 10px;
border-radius: 10px;
margin-bottom: 20px;
}
.table-wrapper table {
width: 460px;
}
.table-header {
height: 35px;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
text-align: center;
line-height: 34px;
text-decoration: none;
font-weight: bold;
}
.table-row td {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
text-align: left;
text-decoration: none;
font-weight: normal;
color: #858585;
padding: 10px;
border-left: 1px solid #ccc;
-khtml-box-shadow: 0px 1px 0px #B2B3B5;
-webkit-box-shadow: 0px 1px 0px #B2B3B5;
-moz-box-shadow: 0px 1px 0px #ddd;
-o-box-shadow: 0px 1px 0px #B2B3B5;
box-shadow: 0px 1px 0px #B2B3B5;
}
tr th {
border-left: 1px solid #ccc;
}
tr th:first-child {
-khtml-border-top-left-radius: 8px;
-webkit-border-top-left-radius: 8px;
-o-border-top-left-radius: 8px;
/*-moz-border-radius-topleft: 8px; firefox doesn't allow rounding of tables yet*/
border-top-left-radius: 8px;
border: none;
}
tr td:first-child {
border: none;
}
tr th:last-child {
-khtml-border-top-right-radius: 8px;
-webkit-border-top-right-radius: 8px;
-o-border-top-right-radius: 8px;
/*-moz-border-radius-topright: 8px; firefox doesn't allow rounding of tables yet*/
border-top-right-radius: 8px;
}
tr {
background: #fff;
}
tr:nth-child(odd) {
background: #F3F3F3;
}
tr:nth-child(even) {
background: #fff;
}
tr:last-child td:first-child {
-khtml-border-bottom-left-radius: 8px;
-webkit-border-bottom-left-radius: 8px;
-o-border-bottom-left-radius: 8px;
/*-moz-border-radius-bottomleft: 8px; firefox doesn't allow rounding of tables yet*/
border-bottom-left-radius: 8px;
}
tr:last-child td:last-child {
-khtml-border-bottom-right-radius: 8px;
-webkit-border-bottom-right-radius: 8px;
-o-border-bottom-right-radius: 8px;
/*-moz-border-radius-bottomright: 8px; firefox doesn't allow rounding of tables yet*/
border-bottom-right-radius: 8px;
}
Solution with border-collapse:separate for table and display:inline-table for tbody and thead.
table {
width: 100%;
border-collapse: separate;
border-spacing: 0px;
background: transparent;
}
table thead {
display: inline-table;
width: 100%;
background: #fc0 url(../images/bg-heading.png) repeat-x 0% 0;
-webkit-border-top-left-radius: 7px;
-moz-border-radius-topleft: 7px;
-webkit-border-top-right-radius: 7px;
-moz-border-radius-topright: 7px;
border-radius: 7px 7px 0px 0px;
padding: 1px;
padding-bottom: 0;
}
table tbody {
border: 1px solid #ddd;
display: inline-table;
width: 100%;
border-top: none;
}
I just wrote a crazy set of CSS for this that seems to work perfectly:
table {
border-collapse: separate;
border-spacing: 0;
width: 100%;
}
table td,
table th {
border-right: 1px solid #CCC;
border-top: 1px solid #CCC;
padding: 3px 5px;
vertical-align: top;
}
table td:first-child,
table th:first-child {
border-left: 1px solid #CCC;
}
table tr:last-child td,
table tr:last-child th {
border-bottom: 1px solid #CCC;
}
table thead + tbody tr:first-child td {
border-top: 0;
}
table thead td,
table th {
background: #EDEDED;
}
/* complicated rounded table corners! */
table thead:first-child tr:last-child td:first-child {
border-bottom-left-radius: 0;
}
table thead:first-child tr:last-child td:last-child {
border-bottom-right-radius: 0;
}
table thead + tbody tr:first-child td:first-child {
border-top-left-radius: 0;
}
table thead + tbody tr:first-child td:last-child {
border-top-right-radius: 0;
}
table tr:first-child td:first-child,
table thead tr:first-child td:first-child {
border-top-left-radius: 5px;
}
table tr:first-child td:last-child,
table thead tr:first-child td:last-child {
border-top-right-radius: 5px;
}
table tr:last-child td:first-child,
table thead:last-child tr:last-child td:first-child {
border-bottom-left-radius: 5px;
}
table tr:last-child td:last-child,
table thead:last-child tr:last-child td:last-child {
border-bottom-right-radius: 5px;
}
/* end complicated rounded table corners !*/
Have you tried using table{border-spacing: 0}
instead of table{border-collapse: collapse}
???
If you want a CSS-only solution (no need to set cellspacing=0
in the HTML) that allows for 1px borders (which you can't do with the border-spacing: 0
solution), I prefer to do the following:
border-right
and border-bottom
for your table cells (td
and th
)border-top
border-left
first-child
and last-child
selectors, round the appropriate corners for the table cells in the four corners.Given the following HTML:
SEE example below:
_x000D_
_x000D_
.custom-table{margin:30px;}_x000D_
table {_x000D_
border-collapse: separate;_x000D_
border-spacing: 0;_x000D_
min-width: 350px;_x000D_
_x000D_
}_x000D_
table tr th,_x000D_
table tr td {_x000D_
border-right: 1px solid #bbb;_x000D_
border-bottom: 1px solid #bbb;_x000D_
padding: 5px;_x000D_
}_x000D_
table tr th:first-child, table tr th:last-child{_x000D_
border-top:solid 1px #bbb;}_x000D_
table tr th:first-child,_x000D_
table tr td:first-child {_x000D_
border-left: 1px solid #bbb;_x000D_
_x000D_
}_x000D_
table tr th:first-child,_x000D_
table tr td:first-child {_x000D_
border-left: 1px solid #bbb;_x000D_
}_x000D_
table tr th {_x000D_
background: #eee;_x000D_
text-align: left;_x000D_
}_x000D_
_x000D_
table.Info tr th,_x000D_
table.Info tr:first-child td_x000D_
{_x000D_
border-top: 1px solid #bbb;_x000D_
}_x000D_
_x000D_
/* top-left border-radius */_x000D_
table tr:first-child th:first-child,_x000D_
table.Info tr:first-child td:first-child {_x000D_
border-top-left-radius: 6px;_x000D_
}_x000D_
_x000D_
/* top-right border-radius */_x000D_
table tr:first-child th:last-child,_x000D_
table.Info tr:first-child td:last-child {_x000D_
border-top-right-radius: 6px;_x000D_
}_x000D_
_x000D_
/* bottom-left border-radius */_x000D_
table tr:last-child td:first-child {_x000D_
border-bottom-left-radius: 6px;_x000D_
}_x000D_
_x000D_
/* bottom-right border-radius */_x000D_
table tr:last-child td:last-child {_x000D_
border-bottom-right-radius: 6px;_x000D_
}_x000D_
_x000D_
<div class="custom-table">_x000D_
<table>_x000D_
<tr>_x000D_
<th>item1</th>_x000D_
<th>item2</th>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>item1</td>_x000D_
<td>item2</td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>item1</td>_x000D_
<td>item2</td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>item1</td>_x000D_
<td>item2</td>_x000D_
</tr>_x000D_
</table>_x000D_
</div>
_x000D_
For a bordered and scrollable table, use this (replace variables, $
starting texts)
If you use thead
, tfoot
or th
, just replace tr:first-child
and tr-last-child
and td
with them.
#table-wrap {
border: $border solid $color-border;
border-radius: $border-radius;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
table td { border: $border solid $color-border; }
table td:first-child { border-left: none; }
table td:last-child { border-right: none; }
table tr:first-child td { border-top: none; }
table tr:last-child td { border-bottom: none; }
table tr:first-child td:first-child { border-top-left-radius: $border-radius; }
table tr:first-child td:last-child { border-top-right-radius: $border-radius; }
table tr:last-child td:first-child { border-bottom-left-radius: $border-radius; }
table tr:last-child td:last-child { border-bottom-right-radius: $border-radius; }
HTML:
<div id=table-wrap>
<table>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
</tr>
</table>
</div>
Border-radius is now officially supported. So, in all of the above examples you may drop the "-moz-" prefix.
Another trick is to use the same color for the top and bottom rows as is your border. With all 3 colors the same, it blends in and looks like a perfectly rounded table even though it isn't physically.
I had the same problem.
remove border-collapse
entirely and use:
cellspacing="0" cellpadding="0"
in the html document.
example:
<table class="top_container" align="center" cellspacing="0" cellpadding="0">
I always do this way using Sass
table {
border-radius: 0.25rem;
thead tr:first-child th {
&:first-child {
border-top-left-radius: 0.25rem;
}
&:last-child {
border-top-right-radius: 0.25rem;
}
}
tbody tr:last-child td {
&:first-child {
border-bottom-left-radius: 0.25rem;
}
&:last-child {
border-bottom-right-radius: 0.25rem;
}
}
}
The best solution so far comes from your own solution and it goes like this:
table, tr, td, th{_x000D_
border: 1px solid; _x000D_
text-align: center;_x000D_
}_x000D_
_x000D_
table{_x000D_
border-spacing: 0;_x000D_
width: 100%;_x000D_
display: table;_x000D_
}_x000D_
_x000D_
table tr:last-child td:first-child, tr:last-child, table {_x000D_
border-bottom-left-radius: 25px;_x000D_
}_x000D_
_x000D_
table tr:last-child td:last-child, tr:last-child, table {_x000D_
border-bottom-right-radius: 25px;_x000D_
}_x000D_
_x000D_
_x000D_
table tr:first-child th:first-child, tr:first-child, table {_x000D_
border-top-left-radius: 25px;_x000D_
}_x000D_
_x000D_
table tr:first-child th:last-child, tr:first-child, table {_x000D_
border-top-right-radius: 25px;_x000D_
}
_x000D_
<table>_x000D_
<tr>_x000D_
<th>Num</th><th>Lett</th><th>Lat</th>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>1</td><td>A</td><td>I</td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>2</td><td>B</td><td>II</td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>3</td><td>C</td><td>III</td>_x000D_
</tr>_x000D_
</table>
_x000D_
I started experiment with "display" and I found that: border-radius
, border
, margin
, padding
, in a table
are displayed with:
display: inline-table;
For example
table tbody tr {
display: inline-table;
width: 960px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
But we need set a width
of every column
tr td.first-column {
width: 100px;
}
tr td.second-column {
width: 860px;
}
The following method works (tested in Chrome) by using a box-shadow
with a spread of 1px
instead of a "real" border.
table {
border-collapse: collapse;
border-radius: 30px;
border-style: hidden; /* hide standard table (collapsed) border */
box-shadow: 0 0 0 1px #666; /* this draws the table border */
}
td {
border: 1px solid #ccc;
}
_x000D_
<table>
<thead>
<tr>
<th>Foo</th>
<th>Bar</th>
</tr>
</thead>
<tbody>
<tr>
<td>Baz</td>
<td>Qux</td>
</tr>
<tr>
<td>Life is short</td>
<td rowspan="3">and</td>
</tr>
<tr>
<td>Love</td>
</tr>
<tr>
<td>is always over</td>
</tr>
<tr>
<td>In the</td>
<td>Morning</td>
</tr>
</tbody>
</table>
_x000D_
Found this answer after running into the same problem, but found it's pretty simple: just give the table overflow:hidden
No need for a wrapping element. Granted, I don't know if this would have worked 7 years ago when the question was initially asked, but it works now.
easiest way...
table {
border-collapse: inherit;
border: 1px solid black;
border-radius: 5px;
}
I tried a workaround using the pseudo elements :before
and :after
on the thead th:first-child
and thead th:last-child
In combination with wrapping the table with a <div class="radius borderCCC">
table thead th:first-child:before{
content:" ";
position:absolute;
top:-1px;
left:-1px;
width:15px;
height:15px;
border-left:1px solid #ccc;
border-top:1px solid #ccc;
-webkit-border-radius:5px 0px 0px;
}
table thead th:last-child:after{
content:" ";
position:absolute;
top:-1px;
right:-1px;
width:15px;
height:15px;
border-right:1px solid #ccc;
border-top:1px solid #ccc;
-webkit-border-radius:0px 5px 0px 0px;
}
see jsFiddle
Works for me in chrome (13.0.782.215) Let me know if this works for you in other browsers.
To the best of my knowledge, the only way you could do it would be to modify all the cells like so:
table td {
border-right-width: 0px;
border-bottom-width: 0px;
}
And then to get the border on the bottom and right back
table tr td:last-child {
border-right-width: 1px;
}
table tr:last-child td {
border-bottom-width: 1px;
}
:last-child
is not valid in ie6, but if you are using border-radius
I assume you don't care.
EDIT:
After looking at your example page, it appears that you may be able to work around this with cell spacing and padding.
The thick gray borders you are seeing are actually the background of the table (you can see this clearly if you change the border color to red). If you set the cellspacing to zero (or equivalently: td, th { margin:0; }
) the grey "borders" will disappear.
EDIT 2:
I can't find a way to do this with only one table. If you change your header row to a nested table, you might possibly be able to get the effect you want, but it'll be more work, and not dynamic.
As Ian said, the solution is to nest the table inside a div and set it like that:
.table_wrapper {
border-radius: 5px;
overflow: hidden;
}
With overflow:hidden
, the square corners won't bleed through the div.
Here is a way:
div {_x000D_
..._x000D_
overflow: hidden;_x000D_
border-radius: 14px;_x000D_
transform: rotate(0deg);_x000D_
}_x000D_
table {_x000D_
border-spacing: 0;_x000D_
}
_x000D_
<div>_x000D_
<table></table>_x000D_
</div>
_x000D_
Or
div {
...
overflow: hidden;
border-radius: 14px;
position: relative;
z-index: 1;
}
Actually you can add your table
inside a div
as its wrapper. and then assign these CSS
codes to wrapper:
.table-wrapper {
border: 1px solid #f00;
border-radius: 5px;
overflow: hidden;
}
table {
border-collapse: collapse;
}
Table with rounded corners and with bordered cells. Using @Ramon Tayag solution.
The key is to use border-spacing: 0
as he points out.
Solution using SCSS.
$line: 1px solid #979797;
$radius: 5px;
table {
border: $line;
border-radius: $radius;
border-spacing: 0;
th,
tr:not(:last-child) td {
border-bottom: $line;
}
th:not(:last-child),
td:not(:last-child) {
border-right: $line;
}
}
You'll probably have to put another element around the table and style that with a rounded border.
The working draft specifies that border-radius
does not apply to table elements when the value of border-collapse
is collapse
.
I am new with HTML and CSS and I was also looking for solution for this, here what I find.
table,th,td {
border: 1px solid black;
border-spacing: 0
}
/* add border-radius to table only*/
table {
border-radius: 25px
}
/* then add border-radius to top left border of left heading cell */
th:first-child {
border-radius: 25px 0 0 0
}
/* then add border-radius to top right border of right heading cell */
th:last-child {
border-radius: 0 25px 0 0
}
/* then add border-radius to bottom left border of left cell of last row */
tr:last-child td:first-child {
border-radius: 0 0 0 25px
}
/* then add border-radius to bottom right border of right cell of last row */
tr:last-child td:last-child {
border-radius: 0 0 25px 0
}
I try it, guess what it works :)
The given answers only work when there are no borders around the table, which is very limiting!
I have a macro in SASS to do this, which fully supports external and internal borders, achieving the same styling as border-collapse: collapse without actually specifying it.
Tested in FF/IE8/Safari/Chrome.
Gives nice rounded borders in pure CSS in all browsers but IE8 (degrades gracefully) since IE8 doesn't support border-radius :(
Some older browsers may require vendor prefixes to work with border-radius
, so feel free to add those prefixes to your code as necessary.
This answer is not the shortest - but it works.
.roundedTable {
border-radius: 20px / 20px;
border: 1px solid #333333;
border-spacing: 0px;
}
.roundedTable th {
padding: 4px;
background: #ffcc11;
border-left: 1px solid #333333;
}
.roundedTable th:first-child {
border-left: none;
border-top-left-radius: 20px;
}
.roundedTable th:last-child {
border-top-right-radius: 20px;
}
.roundedTable tr td {
border: 1px solid #333333;
border-right: none;
border-bottom: none;
padding: 4px;
}
.roundedTable tr td:first-child {
border-left: none;
}
To apply this style simply change your
<table>
tag to the following:
<table class="roundedTable">
and be sure to include the above CSS styles in your HTML.
Hope this helps.
Source: Stackoverflow.com