I currently implement rounded borders on a table like so:
.tbor {
border-width:3px;
border-style:solid;
border-color:lighten(@col-border,10%) darken(@col-border,10%) darken(@col-border,10%) lighten(@col-border,10%);
border-radius:12px;
}
.tbor>tr>td, .tbor>thead>tr>td, .tbor>tbody>tr>td, .tbor>tfoot>tr>td, .tbor>tr>th, .tbor>thead>tr>th, .tbor>tbody>tr>th, .tbor>tfoot>tr>th {
border: 1px solid @col-border;
padding: 2px;
}
.tbor_tl {border-top-left-radius: 8px;}
.tbor_tr {border-top-right-radius: 8px;}
.tbor_br {border-bottom-right-radius: 8px;}
.tbor_bl {border-bottom-left-radius: 8px;}
This works fine, but it requires me to manually set classes on the top-left, top-right, bottom-left and bottom-right cells.
On another project, I have used the following rules for cells:
.tbor>thead>tr:first-of-type>td:first-of-type,.tbor>colgroup+tbody>tr:first-of-type>td:first-of-type,.tbor>tbody:first-child>tr:first-of-type>td:first-of-type,.tbor>tr:first-of-type>td:first-of-type{border-top-left-radius:8px}
.tbor>thead>tr:first-of-type>td:last-of-type,.tbor>colgroup+tbody>tr:first-of-type>td:last-of-type,.tbor>tbody:first-child>tr:first-of-type>td:last-of-type,.tbor>tr:first-of-type>td:last-of-type{border-top-right-radius:8px}
.tbor>tbody:last-child>tr:last-of-type>td:first-of-type,.tbor>tfoot>tr:last-of-type>td:first-of-type,.tbor>tr:last-of-type>td:first-of-type{border-bottom-left-radius:8px}
.tbor>tbody:last-child>tr:last-of-type>td:last-of-type,.tbor>tfoot>tr:last-of-type>td:last-of-type,.tbor>tr:last-of-type>td:last-of-type{border-bottom-right-radius:8px}
It's an ugly mess, and it relies entirely on all table cells being 1x1. It completely falls apart when any of the cells (escpecially the bottom ones) having colspan
or rowspan
.
Is there any way to do this? JavaScript is okay: it can be assumed that all table are static, or that dynamic tables have static first and last rows.
jsFiddle Demo
Kind of an interesting situation. Really the non trivial part comes from identifying the bottom right corner table cell of the table. The others can be found through conventional means.
I am not sure if this is cleaner than your approach. Also, I used jQuery (sorry) for its offset
functionality. The function can easily be taken if you do not include jQuery in your code, but for this example, and for a little brevity, I used it.
This approach will sort the four corners based off of their min/max top and left position with relation to the page.
(function (){
var tl = {};tl.x=99999;tl.y=99999;
var tr = {};tr.x=0;tr.y=99999;
var bl = {};bl.x=99999;bl.y=0;
var br = {};br.x=0;br.y=0;
$(".tbor td").each(function(){
var cur = $(this).offset();
if( cur.top <= tl.y && cur.left <= tl.x ){
tl.x = cur.left;
tl.y = cur.top;
tl.td = this;
}
if( cur.top <= tr.y && cur.left >= tr.x ){
tr.x = cur.left;
tr.y = cur.top;
tr.td = this;
}
if( cur.top >= bl.y && cur.left <= bl.x ){
bl.x = cur.left;
bl.y = cur.top;
bl.td = this;
}
if( cur.top >= br.y && cur.left >= br.x ){
br.x = cur.left;
br.y = cur.top;
br.td = this;
}
});
tl.td.className += " tbor_tl";
tr.td.className += " tbor_tr";
bl.td.className += " tbor_bl";
br.td.className += " tbor_br";
})()
Anyway, this is a suggested alternative instead of determining by hand which td to place the class on.