Need to improve your PageSpeed score? Enter your website address to see how much CSS you can remove:
You Might Also Be Interested In
Let’s assume you have a website theme that requires having rounded corners for elements including tables. Let’s see how we can achieve them and what are the challenges in achieving so.
Let’s create a simple table.
<table>
<tr>
<th>Name</th>
<th>Department</th>
<th>Office</th>
</tr>
<tr>
<td>John</td>
<td>Admin</td>
<td>North</td>
</tr>
<tr>
<td>Smith</td>
<td>Logistics</td>
<td>South</td>
</tr>
<tr>
<td>David</td>
<td>Transport</td>
<td>East</td>
</tr>
</table>
Name | Department | Office |
---|---|---|
John | Admin | North |
Smith | Logistics | South |
David | Transport | East |
Let’s add some basic styling to it using background-color
, color
, and padding
properties. We also remove the spacing between the internal borders using border-spacing: 0
(not by using border-collapse
- this is important for out rounded corners).
Name | Department | Office |
---|---|---|
John | Admin | North |
Smith | Logistics | South |
David | Transport | East |
Let’s next add a border-radius
to get our rounded corners.
table.rounded-corners {
border-spacing: 0;
border-collapse: separate;
border-radius: 10px;
}
table.rounded-corners th, table.rounded-corners td {
border: 1px solid black;
}
Name | Department | Office |
---|---|---|
John | Admin | North |
Smith | Logistics | South |
David | Transport | East |
Whoa, the corners didn't get rounded! Well, the corners of the background got rounded, but not the border. This is because the borders of the table cells didn't get rounded - they stayed square. Lets take a look if we applied the border to the outside of the table, and removed it from the individual cells:
table.rounded-corners {
border-spacing: 0;
border-collapse: separate;
border-radius: 10px;
border: 1px solid black;
}
Name | Department | Office |
---|---|---|
John | Admin | North |
Smith | Logistics | South |
David | Transport | East |
Now all we need to do is add back the internal borders, but not round the outside edges of the cells. If you take another look at the previous tables, you will also see that the interal borders are 2px wide. This is because we are using border-collapse: separate
which means each cell has its own 1px border, which touches the 1px border from the next cell. Unfortunately we can't just set the border width to 0.5px. However, we can rely on the content model of the table to help us construct some funky selectors that will work for all tables. The following snippet will work for any well-structured table, including tables with captions, colgroups, tbody, no tbody etc.
table.rounded-corners {
border-spacing: 0;
border-collapse: separate;
border-radius: 10px;
border: 1px solid black;
}
/* Apply a border to the right of all but the last column */
table.rounded-corners th:not(:last-child),
table.rounded-corners td:not(:last-child) {
border-right: 1px solid black;
}
/* Apply a border to the bottom of all but the last row */
table.rounded-corners>thead>tr:not(:last-child)>th,
table.rounded-corners>thead>tr:not(:last-child)>td,
table.rounded-corners>tbody>tr:not(:last-child)>th,
table.rounded-corners>tbody>tr:not(:last-child)>td,
table.rounded-corners>tfoot>tr:not(:last-child)>th,
table.rounded-corners>tfoot>tr:not(:last-child)>td,
table.rounded-corners>tr:not(:last-child)>td,
table.rounded-corners>tr:not(:last-child)>th,
table.rounded-corners>thead:not(:last-child),
table.rounded-corners>tbody:not(:last-child),
table.rounded-corners>tfoot:not(:last-child) {
border-bottom: 1px solid black;
}
Name | Department | Office |
---|---|---|
John | Admin | North |
Smith | Logistics | South |
David | Transport | East |
This is starting to look good now. You could probably stop there if that's all you need. If you want to style the backgrounds of individual cells or rows (e.g. alternating colors or highlighting rows on hover) then we'll sort that out first. Lets just change the background color of our header row to something really nice to make it stand out:
table.rounded-corners th {
background: red;
}
Name | Department | Office |
---|---|---|
John | Admin | North |
Smith | Logistics | South |
David | Transport | East |
And we just broke our nice rounded corners again... Remember we didn't round the corners of the individual cells, just the table itself. Thankfully, although the fix was a little bit tricky for the borders, it's much easier for the background. We can just set the overflow
on the whole table to hidden
to hide the bit that sticks out over the rounded corners. We've used a CSS variable here just to remove the duplication on the border style.
table.rounded-corners {
/* Change these properties */
--border: 1px solid black;
border-radius: 10px;
/* Don't change these properties */
border-spacing: 0;
border-collapse: separate;
border: var(--border);
overflow: hidden;
}
/* Apply a border to the right of all but the last column */
table.rounded-corners th:not(:last-child),
table.rounded-corners td:not(:last-child) {
border-right: var(--border);
}
/* Apply a border to the bottom of all but the last row */
table.rounded-corners>thead>tr:not(:last-child)>th,
table.rounded-corners>thead>tr:not(:last-child)>td,
table.rounded-corners>tbody>tr:not(:last-child)>th,
table.rounded-corners>tbody>tr:not(:last-child)>td,
table.rounded-corners>tfoot>tr:not(:last-child)>th,
table.rounded-corners>tfoot>tr:not(:last-child)>td,
table.rounded-corners>tr:not(:last-child)>td,
table.rounded-corners>tr:not(:last-child)>th,
table.rounded-corners>thead:not(:last-child),
table.rounded-corners>tbody:not(:last-child),
table.rounded-corners>tfoot:not(:last-child) {
border-bottom: var(--border);
}
Name | Department | Office |
---|---|---|
John | Admin | North |
Smith | Logistics | South |
David | Transport | East |
And there we have it. We now have our rounded table corners with an easy copy/paste snippet
While the above works great if all you want to do is round the outer 4 corners of the table, it doesn't work so well if you want to round any of the other corners. Lets say, for example, you wanted to round the corners of the table headings so it looks separate from the body. If we use the previous trick using overflow: hidden
, then the background will show outside the rounded corners between the heading and the body. We can easily fix this by applying the background to the individual cells, but we now have the problem of actually creating the border around these rounded corners. We can apply the border to the individual cells, but then we get the minimum 2px internal borders. If we just apply the border to one side of each cell boundary, then we lose part of the border on the internal rounded corners:
Name | Department | Office |
---|---|---|
John | Admin | North |
Smith | Logistics | South |
David | Transport | East |
It almost works perfectly, apart from these bits here:
Instead of using borders, we can use a little trick involving a box-shadow
on every cell to create the effect that we're after. It actually makes our border code surprisingly simple:
table.rounded-corners {
/* We need this to be able to use border-radius. */
border-collapse: separate;
/* Add a 1px border spacing for out box-shadow to fit into. Increase this if you want to increase the border width. */
border-spacing: 1px;
}
table.rounded-corners th, table.rounded-corners td {
/* Remove any borders from our stylesheet. */
border: 0;
/* Use the spread value on the box-shadow to set the border width. */
box-shadow: 0 0 0 1px black;
}
Now we can style the rest of the cells and round their corners as much as we want:
table.rounded-corners thead tr:first-child th:first-child {
border-top-left-radius: 10px;
}
table.rounded-corners thead tr:last-child th:first-child {
border-bottom-left-radius: 10px;
}
table.rounded-corners thead tr:first-child th:last-child {
border-top-right-radius: 10px;
}
table.rounded-corners thead tr:last-child th:last-child {
border-bottom-right-radius: 10px;
}
table.rounded-corners tbody tr:first-child td:first-child {
border-top-left-radius: 10px;
}
table.rounded-corners tbody tr:last-child td:first-child {
border-bottom-left-radius: 10px;
}
table.rounded-corners tbody tr:first-child td:last-child {
border-top-right-radius: 10px;
}
table.rounded-corners tbody tr:last-child td:last-child {
border-bottom-right-radius: 10px;
}
And the results are just right
Name | Department | Office |
---|---|---|
John | Admin | North |
Smith | Logistics | South |
David | Transport | East |
Rounding the corners of a table appears to be a simple task but it can easily get tricky based on your requirements. If you are only rounding the corners of the whole table, a border-radius will get the job done. But if you need to round the header and body separately, or even round the individual table rows in the body, then you can get the job done with a box-shadow
.