Tables
Documentation and examples for opt-in styling of tables (given their prevalent use in JavaScript plugins) with Boosted.
Examples
Due to the widespread use of tables across third-party widgets like calendars and date pickers, we’ve designed our tables to be opt-in. Just add the base class .table
to any <table>
, then extend with custom styles or our various included modifier classes.
Using the most basic table markup, here’s how .table
-based tables look in Boosted. All table styles are inherited in Boosted 4, meaning any nested tables will be styled in the same manner as the parent.
# | First | Last | Handle |
---|---|---|---|
1 | Mark | Otto | @mdo |
2 | Jacob | Thornton | @fat |
3 | Larry | the Bird |
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
You can also invert the colors—with light text on dark backgrounds—with .table-dark
.
# | First | Last | Handle |
---|---|---|---|
1 | Mark | Otto | @mdo |
2 | Jacob | Thornton | @fat |
3 | Larry | the Bird |
<table class="table table-dark">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
Hoverable rows
Add .table-hover
to enable a hover state on table rows within a <tbody>
.
# | First | Last | Handle |
---|---|---|---|
1 | Mark | Otto | @mdo |
2 | Jacob | Thornton | @fat |
3 | Larry the Bird |
<table class="table table-hover">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td colspan="2">Larry the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
# | First | Last | Handle |
---|---|---|---|
1 | Mark | Otto | @mdo |
2 | Jacob | Thornton | @fat |
3 | Larry the Bird |
<table class="table table-hover table-dark">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td colspan="2">Larry the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
Sizes
Small table
Add .table-sm
to make tables more compact by cutting cell padding in half.
# | First | Last | Handle |
---|---|---|---|
1 | Mark | Otto | @mdo |
2 | Jacob | Thornton | @fat |
3 | Larry the Bird |
<table class="table table-sm">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td colspan="2">Larry the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
Create responsive tables by wrapping any .table
with .table-responsive{-sm|-md|-lg|-xl}
, making the table scroll horizontally at each max-width
breakpoint of up to (but not including) 576px, 768px, 992px, and 1120px, respectively.
Note that since browsers do not currently support range context queries, we work around the limitations of min-
and max-
prefixes and viewports with fractional widths (which can occur under certain conditions on high-dpi devices, for instance) by using values with higher precision for these comparisons.
Captions
A <caption>
functions like a heading for a table. It helps users with screen readers to find a table and understand what it’s about and decide if they want to read it.
# | First | Last | Handle |
---|---|---|---|
1 | Mark | Otto | @mdo |
2 | Jacob | Thornton | @fat |
3 | Larry | the Bird |
<table class="table">
<caption>List of users</caption>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
Responsive tables
Responsive tables allow tables to be scrolled horizontally with ease. Make any table responsive across all viewports by wrapping a .table
with .table-responsive
. Or, pick a maximum breakpoint with which to have a responsive table up to by using .table-responsive{-sm|-md|-lg|-xl}
.
Vertical clipping/truncation
Responsive tables make use of overflow-y: hidden
, which clips off any content that goes beyond the bottom or top edges of the table. In particular, this can clip off dropdown menus and other third-party widgets.
Always responsive
Across every breakpoint, use .table-responsive
for horizontally scrolling tables.
# | Heading | Heading | Heading | Heading | Heading | Heading | Heading | Heading | Heading |
---|---|---|---|---|---|---|---|---|---|
1 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
2 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
3 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
<div class="table-responsive">
<table class="table">
...
</table>
</div>
Breakpoint specific
Use .table-responsive{-sm|-md|-lg|-xl}
as needed to create responsive tables up to a particular breakpoint. From that breakpoint and up, the table will behave normally and not scroll horizontally.
These tables may appear broken until their responsive styles apply at specific viewport widths.
# | Heading | Heading | Heading | Heading | Heading | Heading | Heading | Heading |
---|---|---|---|---|---|---|---|---|
1 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
2 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
3 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
<div class="table-responsive-sm">
<table class="table">
...
</table>
</div>
# | Heading | Heading | Heading | Heading | Heading | Heading | Heading | Heading |
---|---|---|---|---|---|---|---|---|
1 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
2 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
3 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
<div class="table-responsive-md">
<table class="table">
...
</table>
</div>
# | Heading | Heading | Heading | Heading | Heading | Heading | Heading | Heading |
---|---|---|---|---|---|---|---|---|
1 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
2 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
3 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
<div class="table-responsive-lg">
<table class="table">
...
</table>
</div>
# | Heading | Heading | Heading | Heading | Heading | Heading | Heading | Heading |
---|---|---|---|---|---|---|---|---|
1 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
2 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
3 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
<div class="table-responsive-xl">
<table class="table">
...
</table>
</div>
# | Heading | Heading | Heading | Heading | Heading | Heading | Heading | Heading |
---|---|---|---|---|---|---|---|---|
1 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
2 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
3 | Cell | Cell | Cell | Cell | Cell | Cell | Cell | Cell |
<div class="table-responsive-xxl">
<table class="table">
...
</table>
</div>
Rich content tables
Boosted tables may contain icons, thumbnails and checkboxes. To ensure proper layout, avoid using sizes variants in that case: rows’ height should automatically match .table-lg
ones.
Also, when using checkboxes in the first column, add .has-checkbox
class to the <table>
element to get correct spacing on the first column.
|
Name | Column heading | Column heading | Column heading |
---|---|---|---|---|
|
folder Finance | Column content | Column content | Column content |
|
file File | Column content | Column content | Column content |
|
Image 1 | Column content | Column content | Column content |
|
Image 2 | Column content | Column content | Column content |
|
info | checked | checked | checked |
<table class="table table-hover has-checkbox">
<thead>
<tr>
<th scope="col">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck" autocomplete="off">
<label class="custom-control-label" for="customCheck">
<span class="custom-control-description sr-only">Select all</span>
</label>
</div>
</th>
<th scope="col">Name</th>
<th scope="col">Column heading</th>
<th scope="col">Column heading</th>
<th scope="col">Column heading</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck1" autocomplete="off">
<label class="custom-control-label" for="customCheck1">
<span class="custom-control-description sr-only">Select row 1</span>
</label>
</div>
</th>
<td>
<span class="icon-folder-document" aria-hidden="true"></span>
<span class="sr-only">folder</span>
<span>Finance</span>
</td>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr>
<th scope="row">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck2" autocomplete="off">
<label class="custom-control-label" for="customCheck2">
<span class="custom-control-description sr-only">Select row 2</span>
</label>
</div>
</th>
<td>
<span class="icon-unknown-file" aria-hidden="true"></span>
<span class="sr-only">file</span>
<span>File</span>
</td>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="selected">
<th scope="row">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck3" autocomplete="off" checked>
<label class="custom-control-label" for="customCheck3">
<span class="custom-control-description sr-only">Select row 3</span>
</label>
</div>
</th>
<td>
<svg width="30" height="30" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" focusable="false" role="img">
<rect width="100%" height="100%" fill="#ffd200"/>
</svg>
<span>Image 1</span>
</td>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr>
<th scope="row">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck4" autocomplete="off">
<label class="custom-control-label" for="customCheck4">
<span class="custom-control-description sr-only">Select row 4</span>
</label>
</div>
</th>
<td>
<svg width="30" height="30" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" focusable="false" role="img">
<rect width="100%" height="100%" fill="#4bb4e6"/>
</svg>
<span>Image 2</span>
</td>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr>
<th scope="row">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck5" autocomplete="off">
<label class="custom-control-label" for="customCheck5">
<span class="custom-control-description sr-only">Select row 5</span>
</label>
</div>
</th>
<td>
<span class="icon-info" aria-hidden="true"></span>
<span class="sr-only">info</span>
</td>
<td>
<span class="svg-tick" aria-hidden="true"></span>
<span class="sr-only">checked</span>
</td>
<td>
<span class="svg-tick" aria-hidden="true"></span>
<span class="sr-only">checked</span>
</td>
<td>
<span class="svg-tick" aria-hidden="true"></span>
<span class="sr-only">checked</span>
</td>
</tr>
</tbody>
</table>
Sortable tables
Boosted bundle includes TableSorter, a jQuery plugin to make data tables sortable.
Then initialize tableSorter by targetting an element, and passing some options. Please refer to TableSorter documentation for more options.
$(document).ready(function () {
$("#sortable").tablesorter({
sortList: [[4, 1]],
onRenderTemplate : function(i, t){
return '<span>' + t + '</span>';
}
});
});
Date | Number | Place called | Call class | Duration | Cost |
---|---|---|---|---|---|
08/10/12 | 447765896321 | BT Freefone | talk | 0:05:40 | 0.214 |
09/10/12 | 447765896321 | BT Freefone | talk | 0:19:09 | 0.158 |
10/10/12 | 447765896322 | Free | talk | 0:10:06 | 0.089 |
11/10/12 | 447765896324 | Orange | SMS | - | 0.10 |
<table id="sortable" class="table tablesorter">
<caption>Calls received</caption>
<thead>
<tr>
<th scope="col">Date</th>
<th scope="col">Number</th>
<th scope="col">Place called</th>
<th scope="col">Call class</th>
<th scope="col">Duration</th>
<th scope="col">Cost</th>
</tr>
</thead>
<tbody>
<tr>
<td>08/10/12</td>
<td>447765896321</td>
<td>BT Freefone</td>
<td>talk</td>
<td>0:05:40</td>
<td>0.214</td>
</tr>
<tr>
<td>09/10/12</td>
<td>447765896321</td>
<td>BT Freefone</td>
<td>talk</td>
<td>0:19:09</td>
<td>0.158</td>
</tr>
<tr>
<td>10/10/12</td>
<td>447765896322</td>
<td>Free</td>
<td>talk</td>
<td>0:10:06</td>
<td>0.089</td>
</tr>
<tr>
<td>11/10/12</td>
<td>447765896324</td>
<td>Orange</td>
<td>SMS</td>
<td>-</td>
<td>0.10</td>
</tr>
</tbody>
</table>