City of Ghent Style Guide

Table

When to use this component

Use the table component to let users compare information in rows and columns.

A table is a great way to present things such as:

  • Financial data and numbers
  • Pricing
  • Features (for comparison)
  • Calendars
  • And many other tabular data

When to not use this component

Do not use the table component for layout.

Furthermore, do not use a table component:

  • To present simple, non-tabular data.
  • To present information that users typically do not have to compare.

For presenting simple, non-tabular data, consider using a list instead. For presenting teasers of content, use the collection of teasers instead.

How it works

A table organizes information in rows and columns:

  • The columns can have column headings to tell users what the columns represent.
  • The rows can have row headings to tell users what the rows represent.
  • The table component adds the possibility to add an optional caption tag that describes the table.

The table styling features alternating row colors.

On desktop resolutions, when it is desired, individual rows, columns or even individual cells can be highlighted by overriding the background color. The colors that can be used are success, warning and error. To override the background color with one of these colors, apply the desired CSS class to a row or cell.

On tablets in portrait mode and mobile resolutions, the table component is rendered as a swiper, with arrows to swipe through the different columns. Highlighting cannot be used here. The first column is always fixed, the rest of the “slides” swipe under the first column.

{# Table (desktop). #}
<div class="responsive-table">
  <div class="table-wrapper">
    <table>
      {% for row in table.rows %}
        <tr {{ row.attributes }}>
          {% for cell in row.cells %}
            {% if cell.header %}
              <th {{ cell.attributes }}>{{ cell.text }}</th>
            {% else %}
              <td {{ cell.attributes }}>{{ cell.text }}</td>
            {% endif %}
          {% endfor %}
        </tr>
      {% endfor %}
      <caption>
        {{ caption }}
      </caption>
    </table>
  </div>
</div>

{# Fixed column with swiper (mobile). #}
<div class="table-swiper-wrapper">
    <div class="table-swiper">
        <div class="table-swiper__fixed-column">
            <dl>
                {% if table.columns[0].header is defined and table.columns[0].header.text is not empty %}
                    <dt class="column-header">{{ table.columns[0].header.text }}</dt>
                {% endif %}

                {% for cell in table.columns[0].cells %}
                    {% set rowIndex = loop.index0 %}
                    {% if cell.header %}
                        <dt {{ cell.attributes }} class="cell-row" data-row-index="{{ rowIndex }}">{{ cell.text }}</dt>
                    {% else %}
                        <dd {{ cell.attributes }} class="cell-row{% if rowIndex is odd %} row-even{% endif %}" data-row-index="{{ rowIndex }}">{{ cell.text }}</dd>
                    {% endif %}
                {% endfor %}
            </dl>
        </div>

        <div class="swiper">
            <div class="swiper-wrapper">
                {% for column in table.columns|slice(1) %}
                    <div class="swiper-slide">
                        <dl>
                            {% if column.header %}
                                <dt class="column-header">{{ column.header.text }}</dt>
                            {% endif %}
                            {% for cell in column.cells %}
                                {% set rowIndex = loop.index0 %}
                                <dd
                                        {{ cell.attributes }}
                                        class="cell-row{% if rowIndex is odd %} row-even{% endif %}"
                                        data-row-index="{{ rowIndex }}"
                                >
                                    {{ cell.text }}
                                </dd>
                            {% endfor %}
                        </dl>
                    </div>
                {% endfor %}
            </div>
        </div>

        <div class="swiper-pagination"></div>
        <div class="swiper-button-prev custom-prev">
            <i class="icon icon-arrow-left"></i>
        </div>
        <div class="swiper-button-next custom-next">
            <i class="icon icon-arrow-right"></i>
        </div>
    </div>
    <div class="caption">{{ caption }}</div>
</div>
<div class="responsive-table">
    <div class="table-wrapper">
        <table>
            <tr>
                <th scope="row">Header row 1</th>
                <td>Row 1, column 2</td>
                <td>Row 1, column 3</td>
                <td>Row 1, column 4</td>
                <td>Row 1, column 5</td>
                <td>Row 1, column 6</td>
            </tr>
            <tr>
                <th scope="row">Header row 2</th>
                <td class="cell-row success">Row 2, column 2</td>
                <td>Row 2, column 3</td>
                <td>Row 2, column 4</td>
                <td>Row 2, column 5</td>
                <td>Row 2, column 6</td>
            </tr>
            <tr>
                <th scope="row">Header row 3</th>
                <td>Row 3, column 2</td>
                <td>Row 3, column 3</td>
                <td>Row 3, column 4</td>
                <td>Row 3, column 5</td>
                <td>Row 3, column 6</td>
            </tr>
            <tr>
                <th scope="row">Header row 4</th>
                <td>Row 4, column 2</td>
                <td>Row 4, column 3</td>
                <td>Row 4, column 4</td>
                <td class="cell-row error">Row 4, column 5</td>
                <td>Row 4, column 6</td>
            </tr>
            <tr>
                <th scope="row">Header row 5</th>
                <td>Row 5, column 2</td>
                <td>Row 5, column 3</td>
                <td>Row 5, column 4</td>
                <td>Row 5, column 5</td>
                <td>Row 5, column 6</td>
            </tr>
            <tr>
                <th scope="row">Header row 6</th>
                <td>Row 6, column 2</td>
                <td>Row 6, column 3</td>
                <td class="cell-row warning">Row 6, column 4</td>
                <td>Row 6, column 5</td>
                <td>Row 6, column 6</td>
            </tr>
            <tr>
                <th scope="row">Header row 7</th>
                <td>Row 7, column 2</td>
                <td>Row 7, column 3</td>
                <td>Row 7, column 4</td>
                <td>Row 7, column 5</td>
                <td>Row 7, column 6</td>
            </tr>
            <tr>
                <th scope="row">Header row 8</th>
                <td>Row 8, column 2</td>
                <td>Row 8, column 3</td>
                <td>Row 8, column 4</td>
                <td>Row 8, column 5</td>
                <td>Row 8, column 6</td>
            </tr>
            <tr class="cell-row success">
                <th scope="row">Header row 9</th>
                <td>Row 9, column 2</td>
                <td>Row 9, column 3</td>
                <td>Row 9, column 4</td>
                <td>Row 9, column 5</td>
                <td>Row 9, column 6</td>
            </tr>
            <tr>
                <th scope="row">Header row 10</th>
                <td>Row 10, column 2</td>
                <td>Row 10, column 3</td>
                <td>Row 10, column 4</td>
                <td>Row 10, column 5</td>
                <td>Row 10, column 6</td>
            </tr>
            <caption>
                This is a table caption that describes the table content.
            </caption>
        </table>
    </div>
</div>

<div class="table-swiper-wrapper">
    <div class="table-swiper">
        <div class="table-swiper__fixed-column">
            <dl>

                <dt scope="row" class="cell-row" data-row-index="0">Header row 1</dt>
                <dt scope="row" class="cell-row" data-row-index="1">Header row 2</dt>
                <dt scope="row" class="cell-row" data-row-index="2">Header row 3</dt>
                <dt scope="row" class="cell-row" data-row-index="3">Header row 4</dt>
                <dt scope="row" class="cell-row" data-row-index="4">Header row 5</dt>
                <dt scope="row" class="cell-row" data-row-index="5">Header row 6</dt>
                <dt scope="row" class="cell-row" data-row-index="6">Header row 7</dt>
                <dt scope="row" class="cell-row" data-row-index="7">Header row 8</dt>
                <dt scope="row" class="cell-row" data-row-index="8">Header row 9</dt>
                <dt scope="row" class="cell-row" data-row-index="9">Header row 10</dt>
            </dl>
        </div>

        <div class="swiper">
            <div class="swiper-wrapper">
                <div class="swiper-slide">
                    <dl>
                        <dd class="cell-row" data-row-index="0">
                            Row 1, column 2
                        </dd>
                        <dd class="cell-row success" class="cell-row row-even" data-row-index="1">
                            Row 2, column 2
                        </dd>
                        <dd class="cell-row" data-row-index="2">
                            Row 3, column 2
                        </dd>
                        <dd class="cell-row row-even" data-row-index="3">
                            Row 4, column 2
                        </dd>
                        <dd class="cell-row" data-row-index="4">
                            Row 5, column 2
                        </dd>
                        <dd class="cell-row row-even" data-row-index="5">
                            Row 6, column 2
                        </dd>
                        <dd class="cell-row" data-row-index="6">
                            Row 7, column 2
                        </dd>
                        <dd class="cell-row row-even" data-row-index="7">
                            Row 8, column 2
                        </dd>
                        <dd class="cell-row" data-row-index="8">
                            Row 9, column 2
                        </dd>
                        <dd class="cell-row row-even" data-row-index="9">
                            Row 10, column 2
                        </dd>
                    </dl>
                </div>
                <div class="swiper-slide">
                    <dl>
                        <dd class="cell-row" data-row-index="0">
                            Row 1, column 3
                        </dd>
                        <dd class="cell-row row-even" data-row-index="1">
                            Row 2, column 3
                        </dd>
                        <dd class="cell-row" data-row-index="2">
                            Row 3, column 3
                        </dd>
                        <dd class="cell-row row-even" data-row-index="3">
                            Row 4, column 3
                        </dd>
                        <dd class="cell-row" data-row-index="4">
                            Row 5, column 3
                        </dd>
                        <dd class="cell-row row-even" data-row-index="5">
                            Row 6, column 3
                        </dd>
                        <dd class="cell-row" data-row-index="6">
                            Row 7, column 3
                        </dd>
                        <dd class="cell-row row-even" data-row-index="7">
                            Row 8, column 3
                        </dd>
                        <dd class="cell-row" data-row-index="8">
                            Row 9, column 3
                        </dd>
                        <dd class="cell-row row-even" data-row-index="9">
                            Row 10, column 3
                        </dd>
                    </dl>
                </div>
                <div class="swiper-slide">
                    <dl>
                        <dd class="cell-row" data-row-index="0">
                            Row 1, column 4
                        </dd>
                        <dd class="cell-row row-even" data-row-index="1">
                            Row 2, column 4
                        </dd>
                        <dd class="cell-row" data-row-index="2">
                            Row 3, column 4
                        </dd>
                        <dd class="cell-row row-even" data-row-index="3">
                            Row 4, column 4
                        </dd>
                        <dd class="cell-row" data-row-index="4">
                            Row 5, column 4
                        </dd>
                        <dd class="cell-row warning" class="cell-row row-even" data-row-index="5">
                            Row 6, column 4
                        </dd>
                        <dd class="cell-row" data-row-index="6">
                            Row 7, column 4
                        </dd>
                        <dd class="cell-row row-even" data-row-index="7">
                            Row 8, column 4
                        </dd>
                        <dd class="cell-row" data-row-index="8">
                            Row 9, column 4
                        </dd>
                        <dd class="cell-row row-even" data-row-index="9">
                            Row 10, column 4
                        </dd>
                    </dl>
                </div>
                <div class="swiper-slide">
                    <dl>
                        <dd class="cell-row" data-row-index="0">
                            Row 1, column 5
                        </dd>
                        <dd class="cell-row row-even" data-row-index="1">
                            Row 2, column 5
                        </dd>
                        <dd class="cell-row" data-row-index="2">
                            Row 3, column 5
                        </dd>
                        <dd class="cell-row error" class="cell-row row-even" data-row-index="3">
                            Row 4, column 5
                        </dd>
                        <dd class="cell-row" data-row-index="4">
                            Row 5, column 5
                        </dd>
                        <dd class="cell-row row-even" data-row-index="5">
                            Row 6, column 5
                        </dd>
                        <dd class="cell-row" data-row-index="6">
                            Row 7, column 5
                        </dd>
                        <dd class="cell-row row-even" data-row-index="7">
                            Row 8, column 5
                        </dd>
                        <dd class="cell-row" data-row-index="8">
                            Row 9, column 5
                        </dd>
                        <dd class="cell-row row-even" data-row-index="9">
                            Row 10, column 5
                        </dd>
                    </dl>
                </div>
                <div class="swiper-slide">
                    <dl>
                        <dd class="cell-row" data-row-index="0">
                            Row 1, column 6
                        </dd>
                        <dd class="cell-row row-even" data-row-index="1">
                            Row 2, column 6
                        </dd>
                        <dd class="cell-row" data-row-index="2">
                            Row 3, column 6
                        </dd>
                        <dd class="cell-row row-even" data-row-index="3">
                            Row 4, column 6
                        </dd>
                        <dd class="cell-row" data-row-index="4">
                            Row 5, column 6
                        </dd>
                        <dd class="cell-row row-even" data-row-index="5">
                            Row 6, column 6
                        </dd>
                        <dd class="cell-row" data-row-index="6">
                            Row 7, column 6
                        </dd>
                        <dd class="cell-row row-even" data-row-index="7">
                            Row 8, column 6
                        </dd>
                        <dd class="cell-row" data-row-index="8">
                            Row 9, column 6
                        </dd>
                        <dd class="cell-row row-even" data-row-index="9">
                            Row 10, column 6
                        </dd>
                    </dl>
                </div>
            </div>
        </div>

        <div class="swiper-pagination"></div>
        <div class="swiper-button-prev custom-prev">
            <i class="icon icon-arrow-left"></i>
        </div>
        <div class="swiper-button-next custom-next">
            <i class="icon icon-arrow-right"></i>
        </div>
    </div>
    <div class="caption">This is a table caption that describes the table content.</div>
</div>
{
  "table": {
    "rows": [
      {
        "attributes": null,
        "cells": [
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 1"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 1, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 1, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 1, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 1, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 1, column 6"
          }
        ]
      },
      {
        "attributes": null,
        "cells": [
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 2"
          },
          {
            "header": false,
            "attributes": "class=\"cell-row success\"",
            "text": "Row 2, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 2, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 2, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 2, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 2, column 6"
          }
        ]
      },
      {
        "attributes": null,
        "cells": [
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 3, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 3, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 3, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 3, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 3, column 6"
          }
        ]
      },
      {
        "attributes": null,
        "cells": [
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 4, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 4, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 4, column 4"
          },
          {
            "header": false,
            "attributes": "class=\"cell-row error\"",
            "text": "Row 4, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 4, column 6"
          }
        ]
      },
      {
        "attributes": null,
        "cells": [
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 5, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 5, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 5, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 5, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 5, column 6"
          }
        ]
      },
      {
        "attributes": null,
        "cells": [
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 6"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 6, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 6, column 3"
          },
          {
            "header": false,
            "attributes": "class=\"cell-row warning\"",
            "text": "Row 6, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 6, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 6, column 6"
          }
        ]
      },
      {
        "attributes": null,
        "cells": [
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 7"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 7, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 7, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 7, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 7, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 7, column 6"
          }
        ]
      },
      {
        "attributes": null,
        "cells": [
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 8"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 8, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 8, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 8, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 8, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 8, column 6"
          }
        ]
      },
      {
        "attributes": "class=\"cell-row success\"",
        "cells": [
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 9"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 9, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 9, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 9, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 9, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 9, column 6"
          }
        ]
      },
      {
        "attributes": null,
        "cells": [
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 10"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 10, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 10, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 10, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 10, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 10, column 6"
          }
        ]
      }
    ],
    "columns": [
      {
        "header": null,
        "cells": [
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 1"
          },
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 2"
          },
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 3"
          },
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 4"
          },
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 5"
          },
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 6"
          },
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 7"
          },
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 8"
          },
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 9"
          },
          {
            "header": true,
            "attributes": "scope=\"row\"",
            "text": "Header row 10"
          }
        ]
      },
      {
        "header": null,
        "cells": [
          {
            "header": false,
            "attributes": null,
            "text": "Row 1, column 2"
          },
          {
            "header": false,
            "attributes": "class=\"cell-row success\"",
            "text": "Row 2, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 3, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 4, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 5, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 6, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 7, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 8, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 9, column 2"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 10, column 2"
          }
        ]
      },
      {
        "header": null,
        "cells": [
          {
            "header": false,
            "attributes": null,
            "text": "Row 1, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 2, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 3, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 4, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 5, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 6, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 7, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 8, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 9, column 3"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 10, column 3"
          }
        ]
      },
      {
        "header": null,
        "cells": [
          {
            "header": false,
            "attributes": null,
            "text": "Row 1, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 2, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 3, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 4, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 5, column 4"
          },
          {
            "header": false,
            "attributes": "class=\"cell-row warning\"",
            "text": "Row 6, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 7, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 8, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 9, column 4"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 10, column 4"
          }
        ]
      },
      {
        "header": null,
        "cells": [
          {
            "header": false,
            "attributes": null,
            "text": "Row 1, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 2, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 3, column 5"
          },
          {
            "header": false,
            "attributes": "class=\"cell-row error\"",
            "text": "Row 4, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 5, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 6, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 7, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 8, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 9, column 5"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 10, column 5"
          }
        ]
      },
      {
        "header": null,
        "cells": [
          {
            "header": false,
            "attributes": null,
            "text": "Row 1, column 6"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 2, column 6"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 3, column 6"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 4, column 6"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 5, column 6"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 6, column 6"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 7, column 6"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 8, column 6"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 9, column 6"
          },
          {
            "header": false,
            "attributes": null,
            "text": "Row 10, column 6"
          }
        ]
      }
    ],
    "columnHeaders": false,
    "rowHeaders": true
  },
  "caption": "This is a table caption that describes the table content."
}
  • Content:
    @use '../../00-settings/settings' as *;
    @use '../../00-mixins/mixins' as *;
    
    div.responsive-table,
    div.table-swiper-wrapper {
      position: relative;
      padding-bottom: 1.4rem;
      hyphens: auto;
    
      caption,
      .caption {
        @include theme('color', 'help-text-color', 'table-caption-color');
        @include small-text();
      }
    }
    
    div.responsive-table {
      @include focus-style;
    
      display: none;
    
      @include tablet {
        display: block;
        max-width: 100%;
      }
    
      table {
        border-bottom: 1px solid coloring('gray', -5);
        border-collapse: collapse;
        caption-side: bottom;
    
        th {
          @include semi-bold-text;
    
          font-size: .9rem;
        }
    
        td {
          font-size: .8rem;
    
          &:nth-of-type(n) {
            @include table-backgrounds;
          }
        }
    
        tr {
          &:nth-of-type(even) th:not([scope="col"]) th:not([scope="row"]),
          &:nth-of-type(even) td {
            @include theme('background-color', 'color-secondary-light', 'table-row-color');
          }
    
          &:nth-of-type(n) {
            @include table-backgrounds(td);
          }
    
          th {
            @include theme('background-color', 'color-secondary', 'table-header-color');
          }
        }
    
        // Tables with a thead should have the same color scheme.
        thead ~ tbody tr {
          [class*="cs--"] &:nth-of-type(even) th:not([scope="col"]),
          [class*="cs--"] &:nth-of-type(even) td {
            background-color: transparent;
          }
    
          &:nth-of-type(odd) th:not([scope="col"]),
          &:nth-of-type(odd) td {
            @include theme('background-color', 'color-secondary-light', 'table-row-color');
          }
        }
    
        th,
        td {
          @include theme('color', 'color-zero', 'table-content-color');
          padding: 20px;
          text-align: left;
        }
    
        caption {
          margin-top: 10px;
          text-align: right;
        }
      }
    }
    
    // Swiper styling for mobile.
    
    $fixed-col-width: 130px;
    $pag-nav-wrapper-size: 50px;
    
    div.table-swiper-wrapper {
      display: block;
      width: 100%;
    
      @include tablet {
        display: none;
      }
    
      .table-swiper__fixed-column,
      .swiper-slide {
        padding-bottom: $pag-nav-wrapper-size;
    
        &::before,
        &::after {
          position: absolute;
          right: 0;
          left: 0;
          height: 1px;
          background-color: coloring('gray-light');
          content: "";
        }
    
        &::before {
          top: 0;
        }
    
        &::after {
          bottom: $pag-nav-wrapper-size;
        }
      }
    
      .table-swiper {
        display: flex;
        position: relative;
        width: 100%;
        overflow: hidden;
    
        dl,
        dt,
        dd {
          margin: 0;
        }
    
        dt,
        dd {
          display: block;
          width: 100%;
          padding: 20px;
        }
    
        .swiper {
          width: calc(100vw - #{$fixed-col-width} - 40px);
          margin-right: 0;
          margin-left: 0;
          padding-left: 0;
          overflow: hidden;
        }
    
        .swiper-wrapper {
          display: flex;
          width: 100%;
          margin: 0;
          padding: 0;
          gap: 0;
          box-sizing: border-box;
        }
    
        .swiper-slide {
          width: auto;
          max-width: 190px;  // = 360px - 2 x 20px - 130px (for fixed column).
          margin-right: -1px;
        }
    
        .swiper-pagination {
          top: calc(100% - $pag-nav-wrapper-size + 8px);
        }
    
        .swiper-pagination-bullet-active,
        .swiper-button-next,
        .swiper-button-prev {
          @include theme('color', 'color-primary');
        }
    
        .swiper-pagination-bullet {
          @include theme('background-color', 'bullet-inactive-color');
    
          width: 10px;
          height: 10px;
          margin: 0 7.5px;
          opacity: 1;
        }
    
        .swiper-pagination-bullet-active {
          @include theme('background-color', 'color-primary');
        }
    
        .swiper-button-next,
        .swiper-button-prev {
          top: calc(100% - $pag-nav-wrapper-size);
          height: $pag-nav-wrapper-size;
          margin-top: 0;
    
          &::after {
            display: none;
          }
    
          .icon {
            &::before {
              font-size: 1.6rem;
              line-height: $pag-nav-wrapper-size;
            }
          }
        }
      }
    
      .table-swiper__fixed-column {
        position: sticky;
        left: 0;
        flex-shrink: 0;
        width: $fixed-col-width;
        z-index: 2;
        pointer-events: none;
    
        &::after {
          position: absolute;
          top: 0;
          bottom: $pag-nav-wrapper-size;
          left: 100%;
          width: 25px;
          height: auto;
          background: linear-gradient(90deg, rgba(2, 0, 36, .25) 0%, rgba(0, 0, 0, 0) 100%);
          content: "";
          z-index: 4;
        }
      }
    
      dt {
        @include theme('background-color', 'color-secondary', 'table-header-color');
        @include theme('border-color', 'color-secondary', 'table-header-color');
        @include semi-bold-text();
      }
    
      dd {
    
        &:nth-of-type(n) {
          @include table-backgrounds();
        }
      }
    }
    
  • URL: /components/raw/table/_table.scss
  • Filesystem Path: components/21-atoms/table/_table.scss
  • Size: 4.6 KB
  • Content:
    // Global bindings for ResponsiveTable, Swiper, equalizeTableSwiperHeights.
    'use strict';
    
    (function () {
    
      /**
       * Reset heights for all elements in the given row map.
       *
       * @param {Object} rowMap - A map of data-row-index to an array of DOM elements.
       */
      function resetRowHeights(rowMap) {
        Object.keys(rowMap).forEach(function (key) {
          rowMap[key].forEach(function (cell) {
            cell.style.height = '';
          });
        });
      }
    
      /**
       * Set maximum height per row based on the row map.
       *
       * @param {Object} rowMap - A map of data-row-index to an array of DOM elements.
       */
      function setMaxRowHeights(rowMap) {
        Object.keys(rowMap).forEach(function (key) {
          const maxHeight = Math.max.apply(null, rowMap[key].map(function (el) {
            return el.offsetHeight;
          }));
          rowMap[key].forEach(function (cell) {
            cell.style.height = maxHeight + 'px';
          });
        });
      }
    
      /**
       * Set all .column-header elements within a wrapper to the same height.
       *
       * @param {Element} wrapper - The .table-swiper-wrapper element containing headers.
       */
      function equalizeColumnHeaders(wrapper) {
        const headers = wrapper.querySelectorAll('.column-header');
        if (headers.length === 0) {
          return;
        }
    
        headers.forEach(function (el) {
          el.style.height = '';
        });
    
        const maxHeaderHeight = Math.max.apply(null, Array.from(headers).map(function (el) {
          return el.offsetHeight;
        }));
    
        headers.forEach(function (el) {
          el.style.height = maxHeaderHeight + 'px';
        });
      }
    
      /**
       * Sets equal heights for cells in each row across fixed and swiper columns.
       */
      function equalizeTableSwiperHeights() {
        document.querySelectorAll('.table-swiper-wrapper').forEach(function (wrapper) {
          const rowMap = {};
    
          // Group .cell-row elements by data-row-index.
          const cells = wrapper.querySelectorAll('.cell-row[data-row-index]');
          cells.forEach(function (el) {
            const index = el.getAttribute('data-row-index');
            if (!rowMap[index]) {
              rowMap[index] = [];
            }
            rowMap[index].push(el);
          });
    
          resetRowHeights(rowMap);
          setMaxRowHeights(rowMap);
          equalizeColumnHeaders(wrapper);
        });
      }
    
      // Initialise each Swiper separately.
      function initializeSwiper() {
        document.querySelectorAll('.table-swiper-wrapper .swiper').forEach(function (swiperElement) {
          const swiperWrapper = swiperElement.closest('.table-swiper-wrapper');
          const paginationEl = swiperWrapper.querySelector('.swiper-pagination');
          const nextEl = swiperWrapper.querySelector('.swiper-button-next');
          const prevEl = swiperWrapper.querySelector('.swiper-button-prev');
          const slideCount = swiperElement.querySelectorAll('.swiper-slide').length;
    
          new Swiper(swiperElement, { // eslint-disable-line no-undef
            slidesPerView: 'auto',
            spaceBetween: 0,
            loop: slideCount > 1,
            pagination: {
              el: paginationEl,
              type: 'bullets',
              clickable: true
            },
            navigation: {
              nextEl: nextEl,
              prevEl: prevEl
            },
            on: {
              init: function () {
                equalizeTableSwiperHeights();
                setTimeout(() => this.update(), 100);
              },
              resize: function () {
                equalizeTableSwiperHeights();
              }
            },
            observer: true,
            observeParents: true
          });
        });
      }
    
    
      // Extra fallback for page load and window resize.
      window.addEventListener('load', initializeSwiper);
      window.addEventListener('load', equalizeTableSwiperHeights);
      window.addEventListener('resize', equalizeTableSwiperHeights);
    })();
    
  • URL: /components/raw/table/table.bindings.js
  • Filesystem Path: components/21-atoms/table/table.bindings.js
  • Size: 3.7 KB
  • Content:
    'use strict';
    
    (function (root, factory) {
      if (typeof define === 'function' && define.amd) {
        define(factory);
      }
      else {
        if (typeof exports === 'object') {
          module.exports = factory();
        }
        else {
          root.ResponsiveTable = factory();
        }
      }
    }(this || window, function () {
      return function (element, options) {
    
        let caption = null;
    
        const determineFocusable = () => {
          var scrollableWidth = element.parentNode.querySelector('table').scrollWidth;
          var containerWidth = element.parentNode.clientWidth;
    
          if (scrollableWidth <= containerWidth) {
            element.removeAttribute('tabindex');
          }
          else if (caption) {
            caption.innerText += ' ' + options.scrollableText;
          }
        };
    
        const setupResponsiveTable = () => {
          if (caption && !caption.hasAttribute('id')) {
            const tableUid = Math.random().toString(36).substr(2, 16);
            caption.setAttribute('id', 'responsive-table-caption-caption-' + tableUid);
            element.setAttribute('aria-labelledby', caption.getAttribute('id'));
          }
    
          element.setAttribute('tabindex', '0');
          element.setAttribute('role', 'group');
    
          let firstRow = element.querySelector('tr');
          let tableHeadingsNodeList = firstRow.querySelectorAll('th');
    
          if (firstRow.getElementsByTagName('th').length === firstRow.querySelectorAll('*').length) {
            for (let i = 0; i < tableHeadingsNodeList.length; i++) {
              if (!tableHeadingsNodeList[i].hasAttribute('scope')) {
                tableHeadingsNodeList[i].setAttribute('scope', 'col');
              }
            }
          }
    
          let tableRowsNodeList = element.querySelectorAll('tr');
          for (let i = 0; i < tableRowsNodeList.length; i++) {
            let firstChild = tableRowsNodeList[i].firstElementChild;
    
            if (firstChild && !firstChild.hasAttribute('scope')) {
              firstChild.setAttribute('scope', 'row');
            }
          }
    
          determineFocusable();
        };
    
        const equalizeColumnHeaderHeights = () => {
          const headers = document.querySelectorAll('.table-swiper .column-header');
          let maxHeaderHeight = 0;
    
          headers.forEach(header => {
            header.style.height = 'auto';
            const height = Math.round(header.offsetHeight);
            if (height > maxHeaderHeight) {
              maxHeaderHeight = height;
            }
          });
    
          headers.forEach(header => {
            header.style.height = `${maxHeaderHeight}px`;
          });
    
          const rows = document.querySelectorAll('.table-swiper .cell-row');
          const groupedByIndex = {};
    
          rows.forEach(row => {
            const index = row.getAttribute('data-row-index');
            if (!groupedByIndex[index]) {
              groupedByIndex[index] = [];
            }
            groupedByIndex[index].push(row);
          });
    
          Object.values(groupedByIndex).forEach(rowGroup => {
            let maxHeight = 0;
    
            rowGroup.forEach(row => {
              row.style.height = 'auto';
              const height = Math.round(row.offsetHeight);
              if (height > maxHeight) {
                maxHeight = height;
              }
            });
    
            rowGroup.forEach(row => {
              row.style.height = `${maxHeight}px`;
            });
          });
        };
    
        const init = () => {
          if (!element) {
            return;
          }
    
          caption = element.querySelector('caption');
    
          setupResponsiveTable();
          equalizeColumnHeaderHeights();
        };
    
        init();
    
        window.equalizeTableSwiperHeights = equalizeColumnHeaderHeights;
    
        return {};
      };
    }));
    
  • URL: /components/raw/table/table.functions.js
  • Filesystem Path: components/21-atoms/table/table.functions.js
  • Size: 3.5 KB