<table class="table table--scope-row" tabindex="0" role="table">
    <caption class="table__caption">
        This is a table. Binded text in caption should explain what kind of data this table presents. Can be also a longer text with inline HTML elements inside
    </caption>
    <tbody>
        <tr role="row">
            <th class="" data-th="Example heading:" scope="row" role="rowheader">
                Example content
            </th>
            <td class="" data-th="Example heading:" role="gridcell">
                Example content
            </td>
        </tr>
        <tr role="row">
            <th class="" data-th="Example heading:" scope="row" role="rowheader">
                Example content
            </th>
            <td class="" data-th="Example heading:" role="gridcell">
                Example content
            </td>
        </tr>
        <tr role="row">
            <th class="" data-th="Example heading:" scope="row" role="rowheader">
                Example content
            </th>
            <td class="" data-th="Example heading:" role="gridcell">
                Example content
            </td>
        </tr>
    </tbody>
</table>
<table
    class="table {{ class }}"
    tabindex="0"
    role="table"
    {{{ additionalAttributes }}}
>
    {{#if captionText}}
        <caption class="table__caption">
            {{ captionText }}
        </caption>
    {{/if}}
    {{#each mainTags }}
        <{{{ mainTag }}} {{{mainAttributes}}}>
            {{#each rowTags}}
                <{{{ rowTag }}} {{{ rowTagAttributes }}}>
                    {{#each childTags}}
                        <{{{ childTag }}}
                             class="{{ childTagClasses }}"
                             {{{ childTagAttributes }}}
                        >
                            {{#if contentVisuallyHidden}}
                                <span class="table__visually-hidden">
                                    {{{ content }}}
                                </span>
                            {{else}}
                                {{#if contentComponent}}
                                    {{ render (component contentComponent) contentContext }}
                                {{else}}
                                    {{{ content }}}
                                {{/if}}
                            {{/if}}
                        </{{{ childTag }}}>
                    {{/each}}
                </{{{ rowTag }}}>
            {{/each}}
        </{{{ mainTag }}}>
    {{/each}}
</table>
{
  "captionText": "This is a table. Binded text in caption should explain what kind of data this table presents. Can be also a longer text with inline HTML elements inside",
  "mainTags": [
    {
      "mainTag": "tbody",
      "rowTags": [
        {
          "rowTag": "tr",
          "rowTagAttributes": "role=\"row\"",
          "childTags": [
            {
              "childTag": "th",
              "childTagAttributes": "data-th=\"Example heading:\" scope=\"row\" role=\"rowheader\"",
              "content": "Example content"
            },
            {
              "childTag": "td",
              "childTagAttributes": "data-th=\"Example heading:\" role=\"gridcell\"",
              "content": "Example content"
            }
          ]
        },
        {
          "rowTag": "tr",
          "rowTagAttributes": "role=\"row\"",
          "childTags": [
            {
              "childTag": "th",
              "childTagAttributes": "data-th=\"Example heading:\" scope=\"row\" role=\"rowheader\"",
              "content": "Example content"
            },
            {
              "childTag": "td",
              "childTagAttributes": "data-th=\"Example heading:\" role=\"gridcell\"",
              "content": "Example content"
            }
          ]
        },
        {
          "rowTag": "tr",
          "rowTagAttributes": "role=\"row\"",
          "childTags": [
            {
              "childTag": "th",
              "childTagAttributes": "data-th=\"Example heading:\" scope=\"row\" role=\"rowheader\"",
              "content": "Example content"
            },
            {
              "childTag": "td",
              "childTagAttributes": "data-th=\"Example heading:\" role=\"gridcell\"",
              "content": "Example content"
            }
          ]
        }
      ]
    }
  ],
  "class": "table--scope-row"
}
  • Content:
    $table__padding                  : $spacer--medium !default;
    $table__color                    : $black !default;
    $table__background               : $white !default;
    $table__font-size                : $font-size-base !default;
    $table__line-height              : $font-line-height !default;
    $table__border-radius            : $border-radius !default;
    $table__border                   : 1px solid $gray-light !default;
    $table__th-background            : $gray-lightest !default;
    $table__td-background            : transparent !default;
    $table__tfoot-background         : $gray-lightest !default;
    $table__background-odd--odd-even : $white !default;
    $table__background-even--odd-even: #f9f9f9 !default;
    $table__th-font-weight--clean    : $font-weight-bold !default;
    $table__th-background--clean     : transparent !default;
    $table__background-odd--clean    : #f9f9f9 !default;
    $table__background-even--clean   : $white !default;
    
    .table {
        width: 100%;
        background: $table__background;
        margin: 1em 0;
        border: $table__border;
        border-radius: $table__border-radius;
        color: $table__color;
        border-collapse: separate;
        border-spacing: 0;
        font-size: $table__font-size;
        line-height: $table__line-height;
    
        &--odd-even {
            tbody {
                tr {
                    &:nth-child(odd) {
                        background: $table__background-odd--odd-even;
                    }
    
                    &:nth-child(even) {
                        background: $table__background-even--odd-even;
                    }
    
                    &:first-child {
                        border-top-left-radius: $table__border-radius;
                        border-top-right-radius: $table__border-radius;
    
                        @include mq($screen-m) {
                            border-top-left-radius: 0;
                            border-top-right-radius: 0;
                        }
                    }
                }
    
                td {
                    background-color: transparent;
                }
            }
        }
    
        &--clean {
            margin: 0;
            border: 0;
            border-radius: 0;
    
            thead {
                tr {
                    padding: 0;
                    border-bottom: 0;
                }
            }
    
            th {
                border-bottom: 0;
                border-right: 0;
                background: $table__th-background--clean;
                text-align: left;
                font-weight: $table__th-font-weight--clean;
            }
    
            td {
                border-bottom: 0;
                border-right: 0;
                background: $table__th-background--clean;
            }
    
            tbody {
                tr {
                    &:nth-child(odd) {
                        background: $table__background-odd--clean;
                    }
    
                    &:nth-child(even) {
                        background: $table__background-even--clean;
                    }
                }
            }
        }
    
        &--scope-row {
            border-width: 1px 0;
    
            tr {
                padding: 0;
    
                &:nth-child(even) {
                    th[scope="row"],
                    td {
                        background-color: $table__background-even--odd-even;
                    }
                }
            }
        }
    
        &__caption,
        &__visually-hidden {
            @include visually-hidden();
        }
    
        thead {
            tr {
                padding: 0;
                border-bottom: 0;
    
                @include mq($screen-m) {
                    border-top-left-radius: $table__border-radius;
                    border-top-right-radius: $table__border-radius;
                }
            }
    
            th {
                &:first-child {
                    @include mq($screen-m) {
                        border-top-left-radius: $table__border-radius;
                    }
                }
    
                &:last-child {
                    @include mq($screen-m) {
                        border-top-right-radius: $table__border-radius;
                    }
                }
            }
        }
    
        tr {
            display: block;
            padding: $table__padding 0;
            border-bottom: $table__border;
    
            @include mq($screen-m) {
                padding: 0;
                border-bottom: 0;
                display: table-row;
            }
        }
    
        th {
            display: none;
    
            &:last-child {
                @include mq($screen-m) {
                    border-right: 0;
                }
            }
    
            @include mq($screen-m) {
                display: table-cell;
                padding: $table__padding;
                background: $table__th-background;
                border-bottom: $table__border;
                border-right: $table__border;
            }
        }
    
        td {
            display: flex;
            padding: 5px $table__padding;
            background: $table__td-background;
    
            &:before {
                content: attr(data-th);
                font-weight: bold;
                margin-right: 10px;
                max-width: 25%;
                width: 25%;
                display: block;
    
                @include mq($screen-m) {
                    display: none;
                }
            }
    
            &:last-child {
                @include mq($screen-m) {
                    border-right: 0;
                }
            }
    
            @include mq($screen-m) {
                display: table-cell;
                padding: $table__padding;
                background: $table__td-background;
                border-bottom: $table__border;
                border-right: $table__border;
            }
        }
    
        tbody {
            tr {
                &:last-child {
                    td {
                        &:first-child {
                            @include mq($screen-m) {
                                border-bottom-left-radius: $table__border-radius;
                            }
                        }
    
                        &:last-child {
                            @include mq($screen-m) {
                                border-bottom-right-radius: $table__border-radius;
                            }
                        }
                    }
                }
            }
        }
    
        tfoot {
            tr {
                &:last-child {
                    border-bottom: 0;
    
                    td {
                        border-bottom: 0;
    
                        &:first-child {
                            @include mq($screen-m) {
                                border-bottom-left-radius: $table__border-radius;
                            }
                        }
    
                        &:last-child {
                            @include mq($screen-m) {
                                border-bottom-right-radius: $table__border-radius;
                            }
                        }
                    }
                }
            }
    
            td {
                display: block;
                padding: 5px $table__padding;
                background: $table__background;
    
                @include mq($screen-m) {
                    display: table-cell;
                    padding: $table__padding;
                    background: $table__tfoot-background;
                    border-right: $table__border;
                }
            }
        }
    }
    
  • URL: /components/raw/table/_table.scss
  • Filesystem Path: build/components/02-elements/table/_table.scss
  • Size: 6.8 KB

Tables accessibility

  • Use table semantics elements: table, tbody, tr, th, td
  • Use scope="col" or scope="row" for table headings (th elements)
  • use capion element to describe what kind of data are presented in the table
  • To make mobile table accessible, please add apropriate aria roles:
    • role="columnheader" for th elements
    • role="row" for row elements
    • role="gridcell" for td elements

In desktop mode (wide screens) HTML5 tags are sufficient to make HTML table accessible. However, we change display mode on small screen to set our table visible without horizontal scrolling, so we need to ad apropriate aria roles to make it focusable and well read by AT.