Tables

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.

Classes

ClassDescriptionParentModifies
.s-table-containerContainer for the table.N/AN/A
.s-tableBase table style..s-table-containerN/A
.s-table--cell:nTable cell width in 12 evenly divided columns. Replace `:n` with the number of columns the cell should span..s-table > tr > tdN/A
.s-table__b0Removes all table cell borders.N/A.s-table
.s-table__bxShows only horizontal table cell borders. Good for tables with lots of data that can be sorted and filtered.N/A.s-table
.s-table__bx-simpleRemoves most of the default borders and backgrounds. Good for tables without much data that don't need to be sorted or filtered.N/A.s-table
.s-table__sortableApplies styling to imply the table is sortable.N/A.s-table
.s-table__stripesApply zebra striping to the table.N/A.s-table
.s-table__smApply a condensed sizing to the table.N/A.s-table
.s-table__lgApply a large sizing to the table.N/A.s-table

Default style

Tables 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>
NameUsernameJoinedLast seen
Aaron ShekeyaaronshekeyDec 1 '17 at 20:24just now
Joshua HynesjoshuahynesFeb 12 at 18:47Aug 10 at 14:57
Piper LawsonpiperlawsonJul 5 at 14:32Aug 14 at 12:41

Borders & backgrounds

By 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

Shows 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 nameLast nameUsername
1AaronS.@aarons
2JoshuaH.@joshuah
3PawełL.@pawełl
4TedG.@so-ted

Simple borders

Removes 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 nameLast nameUsername
1AaronS.@aarons
2JoshuaH.@joshuah
3PawełL.@pawełl
4TedG.@so-ted

No borders

Removes all table cell borders.

<div class="s-table-container">
    <table class="s-table s-table__b0"></table>
</div>
First nameLast nameUsername
1AaronS.@aarons
2JoshuaH.@joshuah
3PawełL.@pawełl
4TedG.@so-ted

Zebra striping

When 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 NameLast NameUsername
1AaronS.@aarons
2JoshuaH.@joshuah
3PawełL.@pawełl
4TedG.@so-ted

Spacing

A table’s padding can be changed to be more or less condensed.

Small

<div class="s-table-container">
    <table class="s-table s-table__sm"></table>
</div>
First NameLast NameUsername
1AaronS.@aarons
2JoshuaH.@joshuah

Default

<div class="s-table-container">
    <table class="s-table"></table>
</div>
First NameLast NameUsername
1PawełL.@pawełl
2TedG.@so-ted

Large

<div class="s-table-container">
    <table class="s-table s-table__lg"></table>
</div>
First NameLast NameUsername
1AaronS.@aarons
2JoshuaH.@joshuah

Cell widths

Table 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

ClassWidth
.s-table--cell18.3333333%
.s-table--cell216.6666667%
.s-table--cell325%
.s-table--cell433.3333333%
.s-table--cell541.6666667%
.s-table--cell650%
.s-table--cell758.3333333%
.s-table--cell866.6666667%
.s-table--cell975%
.s-table--cell1083.3333333%
.s-table--cell1191.6666667%
.s-table--cell12100%

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--cell2No Class
.s-table--cell3.s-table--cell6No ClassNo ClassNo Class
.s-table--cell4No ClassNo ClassNo ClassNo Class.s-table--cell2

Alignment

Vertical alignment

The 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

Text 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

To 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">
                    <button type="button">Listing <svg class="svg-icon"></svg></button>
                </th>
                <th scope="col">
                    <button type="button">Status <svg class="svg-icon"></svg></button>
                </th></tr>
        </thead>
        <tbody></tbody>
    </table>
</div>
Listing Status
Site Reliability Engineer, Generalist
Sydney, Australia
RunningSansa Stark50213
Senior Product Designer
New York, NY, USA
RunningRobert Baratheon90015
Product Manager, Developer Products
London, England
RunningSansa Stark31

JavaScript sorting

Stacks 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:

  1. Style the table as sortable as explained in the section above.
  2. Set data-controller="s-table" on the <table> element.
  3. Set data-s-table-target="column" and data-action="click->s-table#sort" on each of the <th> elements that control sorting.
  4. 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 the js-sorting-indicator class to each of the icons, and add js-sorting-indicator-asc, js-sorting-indicator-desc, and js-sorting-indicator-none to the appropriate icon.

Note: Using js-… classes is not really the optimal way of doing this, and will probably be replaced with something better eventually. When that happens, the js-… mechanism will be deprecated but continue to be supported for a while, so you have ample time to update things.

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

AttributeDescriptionApplies to
data-controller="s-table"Wires up the table to the JS controller.table
data-s-table-target="column"Marks this as a sortable column for the purpose of modifying arrow icons.th
data-action="click-&gt;s-table#sort"Causes a click on the header cell to sort by this column.button
data-s-table-sort-to="top"Forces the sorting of a row to the top.tr
data-s-table-sort-to="bottom"Forces the sorting of a row to the bottom.tr
data-s-table-sort-val="[x]"Optionally use a custom value for sorting instead of the cell's text content.td

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-&gt;s-table#sort">
                        Season
                        <svg class="js-sorting-indicator js-sorting-indicator-asc d-none"></svg>
                        <svg class="js-sorting-indicator js-sorting-indicator-desc d-none"></svg>
                        <svg class="js-sorting-indicator js-sorting-indicator-none"></svg>
                    </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>
WinterDecember2
SpringMarch13
SummerJune25
FallSeptember13
Average temperature13

Bulk actions

Generally 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>
                    <div class="s-checkbox"><input type="checkbox" id="example-checkbox-1"></div>
                </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>
                    <div class="s-checkbox"><input type="checkbox" id="example-checkbox-2"></div>
                </td>
                <td></td>
            </tr>
        </tbody>
    </table>
</div>
Display NameFull NameEmail
SansaStarkSansa Starksstark@company.com
RobertBaratheonRobert Baratheonrbaratheon@company.com
Test Developer To Be Is Not A Developer YetTest Developer To Be Is Not A Developer Yettestdevelopertobeisnotadevyet@team-mgmt.dev.company.com

Totals row

Used 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>
ListingViewsAppsApp CTR
Site Reliability Engineer, Generalist6,8711875.02%
Senior Product Designer2,24219616.46%
Product Manager, Developer Products3,46922914.9%
Totals12,58261214.65%

Inactive rows

For 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 ignore 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>
NameEmailLast seen
Aaron Shekeyemailaddress@website.comjust nowRemove
Joshua Hynesemailaddress@website.comSep 28 '18Add
Paweł Ludwiczakemailaddress@website.comApr 17 '19Add
Piper Lawsonemailaddress@website.comYesterdayRemove
Ted Goasemailaddress@website.com5min agoRemove

Atomic classes

Further 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.

ClassOutput
.tl-autotable-layout: auto;
.tl-fixedtable-layout: fixed;