Sections
Tables are used to list all information from a data set. The base style establishes preferred padding, font-size, and font-weight treatments. To enhance or customize the look of the table, apply any additional classes listed below.
Default style
Section titled Default styleTables should be wrapped in a container, .s-table-container
. This provides horizontal scrolling when necessary in the smallest breakpoints. The default table style is a bordered cell layout with a stylized header row.
<div class="s-table-container">
<table class="s-table">
<thead>
<tr>
<th scope="col"></th>
<th scope="col"></th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row"></th>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
Name | Reputation | Joined | Last seen |
---|---|---|---|
Aaron Shekey |
|
Dec 1 ’17 at 20:24 | just now |
Joshua Hynes |
|
Feb 12 at 18:47 | Aug 10 at 14:57 |
Piper Lawson |
|
Jul 5 at 14:32 | Aug 14 at 12:41 |
Borders & backgrounds
Section titled Borders & backgroundsBy default, tables are outlined, have borders on all cells, and have a styled header. Depending on the size and complexity of a table, these can all be configured.
Horizontal borders
Section titled Horizontal bordersShows only horizontal table cell borders. Good for tables with lots of data that can be sorted and filtered.
<div class="s-table-container">
<table class="s-table s-table__bx">
…
</table>
</div>
First name | Last name | Username | |
---|---|---|---|
1 | Aaron | S. | @aarons |
2 | Joshua | H. | @joshuah |
3 | Paweł | L. | @pawełl |
4 | Ted | G. | @so-ted |
Simple borders
Section titled Simple bordersRemoves most of the default borders and backgrounds. Good for tables without much data that don't need to be sorted or filtered.
<div class="s-table-container">
<table class="s-table s-table__bx-simple">
…
</table>
</div>
First name | Last name | Username | |
---|---|---|---|
1 | Aaron | S. | @aarons |
2 | Joshua | H. | @joshuah |
3 | Paweł | L. | @pawełl |
4 | Ted | G. | @so-ted |
No borders
Section titled No bordersRemoves all table cell borders.
<div class="s-table-container">
<table class="s-table s-table__b0">
…
</table>
</div>
First name | Last name | Username | |
---|---|---|---|
1 | Aaron | S. | @aarons |
2 | Joshua | H. | @joshuah |
3 | Paweł | L. | @pawełl |
4 | Ted | G. | @so-ted |
Zebra striping
Section titled Zebra stripingWhen tables have a lot of information, you can help users group information and isolate data by adding zebra striping.
<div class="s-table-container">
<table class="s-table s-table__stripes">
…
</table>
</div>
First Name | Last Name | Username | |
---|---|---|---|
1 | Aaron | S. | @aarons |
2 | Joshua | H. | @joshuah |
3 | Paweł | L. | @pawełl |
4 | Ted | G. | @so-ted |
Spacing
Section titled SpacingA table’s padding can be changed to be more or less condensed.
Small
Section titled Small<div class="s-table-container">
<table class="s-table s-table__sm">
…
</table>
</div>
First Name | Last Name | Username | |
---|---|---|---|
1 | Aaron | S. | @aarons |
2 | Joshua | H. | @joshuah |
Default
Section titled Default<div class="s-table-container">
<table class="s-table">
…
</table>
</div>
First Name | Last Name | Username | |
---|---|---|---|
1 | Paweł | L. | @pawełl |
2 | Ted | G. | @so-ted |
Large
Section titled Large<div class="s-table-container">
<table class="s-table s-table__lg">
…
</table>
</div>
First Name | Last Name | Username | |
---|---|---|---|
1 | Aaron | S. | @aarons |
2 | Joshua | H. | @joshuah |
Cell widths
Section titled Cell widthsTable columns will size themselves based on their content. To set a specific width, you can use one of the following table cell classes to specify the width for any column.
Classes
Section titled ClassesClass | Width |
---|---|
.s-table--cell1 |
8.3333333% |
.s-table--cell2 |
16.6666667% |
.s-table--cell3 |
25% |
.s-table--cell4 |
33.3333333% |
.s-table--cell5 |
41.6666667% |
.s-table--cell6 |
50% |
.s-table--cell7 |
58.3333333% |
.s-table--cell8 |
66.6666667% |
.s-table--cell9 |
75% |
.s-table--cell10 |
83.3333333% |
.s-table--cell11 |
91.6666667% |
.s-table--cell12 |
100% |
Examples
Section titled Examples// Example 1
<div class="s-table-container">
<table class="s-table">
<tr>
<td class="s-table--cell2">…</td>
<td>…</td>
</tr>
</table>
</div>
// Example 2
<div class="s-table-container">
<table class="s-table">
<tr>
<td class="s-table--cell3">…</td>
<td class="s-table--cell6">…</td>
<td>…</td>
<td>…</td>
<td>…</td>
</tr>
</table>
</div>
// Example 3
<div class="s-table-container">
<table class="s-table">
<tr>
<td class="s-table--cell4">…</td>
<td>…</td>
<td>…</td>
<td>…</td>
<td>…</td>
<td class="s-table--cell2">…</td>
</tr>
</table>
</div>
.s-table--cell2 | No Class |
.s-table--cell3 | .s-table--cell6 | No Class | No Class | No Class |
.s-table--cell4 | No Class | No Class | No Class | No Class | .s-table--cell2 |
Alignment
Section titled AlignmentVertical alignment
Section titled Vertical alignmentThe default vertical alignment is middle
. You change a table’s or a specific cell’s vertical alignment by using the Vertical Alignment atomic classes.
<div class="s-table-container">
<table class="s-table">
<tbody>
<tr>
<td class="va-top">…</td>
<td class="va-middle">…</td>
<td class="va-bottom">…</td>
</tr>
</tbody>
</table>
</div>
<div class="s-table-container">
<table class="s-table va-bottom">
<tbody>
<tr>
<td>…</td>
<td>…</td>
<td>…</td>
</tr>
</tbody>
</table>
</div>
.va-top | .va-middle | .va-bottom |
.s-table.va-bottom | .s-table.va-bottom | .s-table.va-bottom |
Text alignment
Section titled Text alignmentText alignment can be changed at a table or cell level by using atomic text alignment classes. Columns containing copy should be left-aligned. Columns containing numbers should be right-aligned.
<div class="s-table-container">
<table class="s-table">
<tbody>
<tr>
<td class="ta-left">…</td>
<td class="ta-center">…</td>
<td class="ta-right">…</td>
</tr>
</tbody>
</table>
</div>
<div class="s-table-container">
<table class="s-table ta-right">
<tbody>
<tr>
<td>…</td>
<td>…</td>
<td>…</td>
</tr>
</tbody>
</table>
</div>
.ta-left | .ta-center | .ta-right |
.s-table.ta-right | .s-table.ta-right | .s-table.ta-right |
Sortable tables
Section titled Sortable tablesTo indicate that the user can sort a table by different columns, add the s-table__sortable
class to the table.
The <th>
cells should include arrows to indicate sortability or the currently applied sorting. In addition, the column that is currently sorted should be indicated with the is-sorted
class on its <th>
.
<div class="s-table-container">
<table class="s-table s-table__sortable">
<thead>
<tr>
<th scope="col" class="is-sorted">Listing @Svg.ArrowDownSm</th>
<th scope="col">Status @Svg.ArrowUpDownSm</th>
<th scope="col">Owner @Svg.ArrowUpDownSm</th>
<th scope="col" class="ta-right">Views @Svg.ArrowUpDownSm</th>
<th scope="col" class="ta-right">Applies @Svg.ArrowUpDownSm</th>
</tr>
</thead>
<tbody>
…
</tbody>
</table>
</div>
Listing | Status | Owner | Views | Applies |
---|---|---|---|---|
Site Reliability Engineer, Generalist Sydney, Australia |
Running | Sansa Stark | 502 | 13 |
Senior Product Designer New York, NY, USA |
Running | Robert Baratheon | 900 | 15 |
Product Manager, Developer Products London, England |
Running | Sansa Stark | 3 | 1 |
JavaScript sorting
Section titled JavaScript sortingStacks provides built-in functionality for letting the user sort a table by the values in a column through clicking the column header. This requires the complete data to already exist in the table (e.g. it is not going to work if the table is paged and requires a call to the server to update data on sorting). See the JavaScript introduction for general information about JS in Stacks.
To make your table user-sortable, do the following:
- Style the table as sortable as explained in the section above.
- Set
data-controller="s-table"
on the<table>
element. - Set
data-s-table-target="column"
anddata-action="click->s-table#sort"
on each of the<th>
elements that control sorting. -
Add the three icons for showing ascending sort, descending sort, and unsorted to each of these header cells, hiding the first two with a
d-none
class. Add thejs-sorting-indicator
class to each of the icons, and addjs-sorting-indicator-asc
,js-sorting-indicator-desc
, andjs-sorting-indicator-none
to the appropriate icon.
By default, the data is sorted by the content of the cell. If you need to use a different value, for example because your cell contains a human-readable date, add a data-s-table-sort-val
attribute to the cell.
If a column contains any data that is not an integer, the data will be sorted lexicographically. Otherwise it will be sorted numerically, with empty cells being considered the lowest number.
If the table contains rows that should not be sorted, but rather always be at the top or always be at the bottom, add data-s-table-sort-to="top"
or data-s-table-sort-to="bottom"
to the <tr>
element.
JavaScript data attributes
Section titled JavaScript data attributesAttribute | Applied to | Description |
---|---|---|
data-controller="s-table" |
table |
Wires up the table to the JS controller |
data-s-table-target="column" |
th |
Marks this is a sortable column for the purpose of modifying arrow icons |
data-action="click->s-table#sort" |
button |
Causes a click on the header cell to sort by this column |
data-s-table-sort-to="top" |
tr |
Forces the sorting of a row to the top |
data-s-table-sort-to="bottom" |
tr |
Forces the sorting of a row to the bottom |
data-s-table-sort-val="[x]" |
td |
Optionally use a custom value for sorting instead of the cell’s text content |
JavaScript example
Section titled JavaScript example<div class="s-table-container">
<table class="s-table s-table__sortable" data-controller="s-table">
<thead>
<tr>
<th scope="col" data-s-table-target="column">
<button data-action="click->s-table#sort">
Season
@Svg.ArrowUpSm.With("js-sorting-indicator js-sorting-indicator-asc d-none")
@Svg.ArrowDownSm.With("js-sorting-indicator js-sorting-indicator-desc d-none")
@Svg.ArrowUpDownSm.With("js-sorting-indicator js-sorting-indicator-none")
</button>
</th>
<th scope="col" data-s-table-target="column">
<button data-action="click->s-table#sort">
Starts in month
…
</button>
</th>
<th scope="col" data-s-table-target="column">
<button data-action="click->s-table#sort">
Typical temperature in °C
…
</button>
</th>
</tr>
</thead>
<tbody>
<tr><td>Winter</td><td data-s-table-sort-val="12">December</td><td>2</td></tr>
<tr><td>Spring</td><td data-s-table-sort-val="3">March</td><td>13</td></tr>
<tr><td>Summer</td><td data-s-table-sort-val="6">June</td><td>25</td></tr>
<tr><td>Fall</td><td data-s-table-sort-val="9">September</td><td>13</td></tr>
<tr data-s-table-sort-to="bottom" class="fw-bold">
<td colspan="2">Average temperature</td>
<td>13</td>
</tr>
</tbody>
</table>
</div>
Winter | December | 2 |
Spring | March | 13 |
Summer | June | 25 |
Fall | September | 13 |
Average temperature | 13 |
Bar graphs
Section titled Bar graphsTo help users, you can add data visualizations into table cells. These are useful to help visualize the reported data and calling extra attention to the table cell. These graphs should always be paired with a number.
<div class="s-table-container">
<table class="s-table">
<thead>…</thead>
<tbody>
<tr>
<td>…</td>
<td>…</td>
<td>…</td>
<td>…</td>
<td class="s-table--progress">1,854</td>
<td class="s-table--progress-bar">
<div class="s-progress bg-white">
<div class="s-progress--bar bg-powder-400" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="67.247" aria-label="example progressbar powder" style="width: 67.247%"></div>
</div>
</td>
<td class="s-table--progress">43</td>
<td class="s-table--progress-bar">
<div class="s-progress bg-white">
<div class="s-progress--bar bg-orange-400" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="72.881" aria-label="example progressbar orange" style="width: 72.881%"></div>
</div>
</td>
</tr>
…
</tbody>
</table>
</div>
Listing | Status | Owner | Source | Views | Applies | ||
---|---|---|---|---|---|---|---|
Site Reliability Engineer, Generalist Sydney, Australia |
Running | Sansa Stark | stackoverflow.com | 1,854 |
|
43 |
|
Senior Product Designer New York, NY, USA |
Running | Robert Baratheon | linkedin.com | 900 |
|
15 |
|
Product Manager, Developer Products London, England |
Running | Sansa Stark | m.facebook.com | 3 |
|
1 |
|
Bulk actions
Section titled Bulk actionsGenerally for a checkbox input that’s placed first in the table row for bulk actions.
<div class="s-table-container">
<table class="s-table">
<thead>
<tr>
<th scope="col" class="s-table--bulk">
<label class="v-visible-sr" for="example-checkbox-1">bulk checkbox</label>
<input type="checkbox" class="s-checkbox" id="example-checkbox-1">
</th>
<th scope="col">…</th>
<th scope="col">…</th>
<th scope="col">…</th>
</tr>
</thead>
<tbody>
<tr>
<td class="s-table--bulk">
<label class="v-visible-sr" for="example-checkbox-2">bulk checkbox</label>
<input type="checkbox" class="s-checkbox" id="example-checkbox-2">
</td>
<td>…</th>
<td>…</td>
<td>…</td>
</tr>
</tbody>
</table>
</div>
Display Name | Full Name | ||
---|---|---|---|
SansaStark | Sansa Stark | sstark@company.com | |
RobertBaratheon | Robert Baratheon | rbaratheon@company.com | |
Test Developer To Be Is Not A Developer Yet | Test Developer To Be Is Not A Developer Yet | testdevelopertobeisnotadevyet@team-mgmt.dev.company.com |
Totals row
Section titled Totals rowUsed mainly with data tables, the totals row increases the font-size for all cells within a row.
<div class="s-table-container">
<table class="s-table ta-right">
…
<tfoot class="s-table--totals">
…
</tfoot>
</table>
</div>
Listing | Views | Apps | App CTR |
---|---|---|---|
Site Reliability Engineer, Generalist | 6,871 | 187 | 5.02% |
Senior Product Designer | 2,242 | 196 | 16.46% |
Product Manager, Developer Products | 3,469 | 229 | 14.9% |
Totals | 12,582 | 612 | 14.65% |
Inactive rows
Section titled Inactive rowsFor tables that include inactive or disabled rows, such as inactive users or teams, .is-disabled
can be applied to any <tr>
. Additionally, .is-enabled
can be applied to any <th>
or <td>
that you’d like to ignoring the parent disabled styling (such as a persistent link to reactivate a disabled account).
<div class="s-table-container">
<table class="s-table">
<tbody>
<tr class="is-disabled">
<td>…</td>
<td>…</td>
<td class="is-enabled">
<a>Add</a>
</td>
</tr>
</tbody>
</table>
</div>
Name | Last seen | ||
---|---|---|---|
Aaron Shekey | emailaddress@website.com | just now | Remove |
Joshua Hynes | emailaddress@website.com | Sep 28 ’18 | Add |
Paweł Ludwiczak | emailaddress@website.com | Apr 17 ’19 | Add |
Piper Lawson | emailaddress@website.com | Yesterday | Remove |
Ted Goas | emailaddress@website.com | 5min ago | Remove |
Atomic classes
Section titled Atomic classesFurther control of table behavior is possible with atomic classes. For example, you can make non-table markup display as a table layout by pairing .d-table
, .d-table-cell
and .tl-fixed
.
Class | Output |
---|---|
.tl-auto |
table-layout: auto; |
.tl-fixed |
table-layout: fixed; |