Table module
Tables allow the presentation of tabular data.
They really should not be used for layouting page content as it was popular in the 1990s before the rise of CSS.
You can define tables with the <table>
, <tr>
, <th>
and <td>
elements as usual.
CSS classes can be applied to the <table>
element to configure the appearance.
Note:
There are many CSS classes available for table styling.
Search for “table” in the CSS classes reference to get a full list.
This page tries to show how each of them looks.
This module and all of its plugins is available in the Minimal and Complete bundles.
Simple tables
This is a plain table with no additional styling.
The use of <thead>
and <tbody>
is normally optional but shown here because the browser would insert it in ugly places in this example.
The table border and grid line colour can be customised with the --table-grid-color
CSS class, the table header background with --table-header-background
.
Column 1 | Column 2 | Column 3 |
---|---|---|
Data 1 | Data 2 | Data 3 |
Data 1 | Data 2 | Data 3 |
Data 1 | Data 2 | More data 3 |
Full width
To expand the table to the full available width, use the full-width
CSS class.
Normally, a table will only use the width it needs for its content.
But for consistency with multiple tables on the same page, or when displaying a long list of data, it could look nicer to always let the table use the full page width.
Column 1 | Column 2 | Column 3 |
---|---|---|
Data 1 | Data 2 | Data 3 |
Data 1 | Data 2 | More data in column 3 |
Tables without borders
This table has the no-border
, no-vgrid
and center
classes to eliminate the outer table border and the inner vertical grid lines, and align all cell content centered, respectively.
The alternative to no-vgrid
is no-hgrid
to remove the horizontal grid lines instead.
Both are combined in the no-grid
class that removes all inner grid lines.
All table content can be centered with the center
class applied to the table.
Individual cells can be aligned differently by applying the left
, center
and right
classes to each <th>
or <td>
element (shown in the last row).
Column 1 | Column 2 | Column 3 | Column 4 |
---|---|---|---|
Data 1 | Data 2 | Data 3 | Data 4 |
Data 1 | Data 2 | Data 3 | Data 4 |
Left | Data 2 Second line |
Data 3 | Right |
The no-outer-padding
class removes the outer cell padding towards the border of the table, but leaves the inner cell padding between adjacent cells intact.
This is most useful in combination with no-border
(as shown here) and without any cell background colours.
It aligns the table content exactly with the surrounding text.
Data 1 | Data 2 | Data 3 |
Data 1 | Data 2 | Data 3 |
Data 1 | Data 2 | Data 3 |
Compact tables
Tables can be made more compact with the compact
CSS class.
This reduces the cell padding and removes the inner grid lines.
Column 1 | Column 2 | Column 3 |
---|---|---|
Data 1 | Data 2 | Data 3 |
Data 1 | Data 2 | Data 3 |
To remove all padding completely and have table cells touch each other directly, use the combination of the no-border
, no-grid
and no-padding
CSS classes.
It is probably advisable not to use a table header (<th>
) with this.
You could still place elements with their own custom padding in each table cell.
Column 1 | Col 2 | Column 3 |
---|---|---|
Data 1 | Data 2 | Data 3 |
Data 1 | Data 2 | Data 3 |
Larger cells
Big links
Hyperlinks in a table cell that only have the size of the text content can be a bit small to click or touch, and it might seem unintuitive to have a smaller touch area than the visual box of the table cell.
For this reason, links in a table can be enlarged to fill their entire cell, by adding the big-links
CSS class to the table.
Tall rows
Table rows that may have buttons to perform certain actions.
These buttons have a larger height than regular text content because of their additional padding.
If some of the rows contain a button and others do not, the row heights are not regular.
To avoid this, and to further increase the touch area of links in a table, add the tall-rows
CSS class to the table.
Column 1 | Column 2 | Action |
---|---|---|
Data 1 | Data 2 | |
Data 1 | Data 2 | |
Data 1 | Data 2 |
Here is another example with tall-rows
and big-links
together.
Interactive table styles demonstration
The following example can be used to interactively set the individual table-level CSS classes and see their effect.
Column 1 | Col 2 | Column 3 |
---|---|---|
Link 1 | Data 2 | Data 3 |
Data 1 | Data 2 Next line |
Data 3 |
Sticky header
Long tables can be hard to read when the header row has already been scrolled out of view.
The sticky-header
class keeps the table header of a table visible at the top of the viewport while scrolling down.
The sticky position is applied to <th>
elements in a <thead>
element, so use these properly.
The vertical offset is defined in the CSS variable --sticky-header-top
and can be changed to keep the sticky header below a fixed page header.
If unset, the offset defaults to 0 (top edge of the viewport with no fixed elements).
In this example, the CSS variable --fixed-header-height
is set by the site CSS and adjusted so that it updates when the page header is no longer fixed on less tall viewports.
Because of the way that collapsed table borders work, they cannot be used together with sticky headers. So to avoid missing or inconsistent table borders, only use this feature with all borders in the table header disabled. The set of classes shown in the example demonstrate this.
Scroll down and | I’ll stay visible |
---|---|
Data 1 | Data 2 |
Data 1 | Data 2 |
Data 1 | Data 2 |
Data 1 | Data 2 |
Data 1 | Data 2 |
Data 1 | Data 2 |
Vertical text
Text can also be rotated to be vertical by placing it in a <span>
element with the vertical
class.
This is especially useful for table headers with narrow columns.
Column 1 | Column 2 | Column 3 |
---|---|---|
A | B | C |
A | B | more |
Filtered table data
In some situations, tables have a different style for the first and last row and column. When a view filter is used to hide certain rows or columns of the table, the special first/last style is still applied to the now hidden rows or columns. A JavaScript function is needed to apply extra classes that override the default CSS selectors and apply these special styles to the right spots again. This is provided with the two following methods.
The updateFirstLastRow()
updates the rows of each selected table.
Call this method on the <tbody>
element after changing the visibility of rows in the table.
The updateFirstLastColumn()
updates the columns of each selected table.
Call this method on the <table>
element after changing the visibility of columns in the table.
The following example shows a table with relevant styles. It has horizontal grid lines between the rows, but none above the first or below the last row. It also has no horizontal outer padding and no outer border in the first and last column. With the four outer checkboxes, you can hide the corresponding row or column. With the central checkbox, the invocation of the update methods is enabled or disabled after each visibility change. Use it to observe the style flaws that would appear without them and compare it to how the table style remains consistent with them.
The example source code already includes the modifications by these methods and adds the highlighted classes.
The style display: none;
(not highlighted) is set by the checkbox event handlers of the example.
Name | Age | Location | Profession |
---|---|---|---|
Mary | 26 | Chicago | Scientist |
James | 21 | Seattle | Physician Assistant |
Patricia | 54 | Telluride | Lawyer |
Robert | 62 | Salt Lake City | Designer |
Overflow columns
This plugin depends on the plugins: modal
Tables can also be used for data entry forms where the same (or similar) properties are provided for a number of records (see template rows below). Such data tables can easily grow to a width that does not fit the screen anymore. In these situations, the overflowing columns can be hidden away and displayed in a separate modal upon clicking a button. To use this feature, the following requirements must be met:
- The table element must have the
overflow-columns
CSS class. - All table header cells must be in a separate
<thead>
element. - All columns that can be collapsed (hidden on overflow) must have the
collapsible-column
CSS class in their header cell. - A table column for the overflow modal button must be added with the
overflow-column
CSS class for all cells. - The
overflow-column
cells (excluding the header) must contain a single<button>
element with theoverflow-button
CSS class as shown in the example.
All columns are collapsed from right to left, as long as the table width exceeds the content width of its parent element.
Optionally, the header cells can have a data-collapse-priority
HTML attribute that is set to a number value.
These columns are collapsed first, in the order of their values, lowest first.
Columns with the same priority value are still collapsed from right to left.
All other columns are collapsed last.
As soon as a column is collapsed, the overflow buttons become visible in all rows. Clicking that button opens a modal that contains the column headers and cell content of each hidden column in a vertical form layout. The cell content is moved from the original locations in the table into the modal form when the modal is opened, and moved back when the modal is closed. So the input elements in the modal are the actual input elements from the table, not clones. Changes to these input elements are immediately persisted and change events are triggered, there is no Cancel button for the modal.
As the width of the cell content can change on user interaction, the overflow columns need to be updated at appropriate times. This can be triggered with the update() plugin method. The layout is already updated when a “change” or “input” event bubbles through the table. See the descriptions of the plugin methods below.
Name | Options | Checkbox | Number | Description | |
---|---|---|---|---|---|
Just text | |||||
Another text |
Plugin methods
This plugin provides methods to control the layout.
update
update()
→ this
Updates the overflow column visibilities for a table. This needs to be called after updating the contents of the table, like adding/removing rows, changing data or showing additional columns. It is called automatically after the window has been resized.
Template rows
Tables can also be used for data entry forms where the same (or similar) properties are provided for a number of records.
Such data tables are best populated from record data provided in a JSON object or fetched directly from a server or database.
You can define a row template that contains the form fields for each table column and that will be used for each loaded record.
Each field element needs the data-name
HTML attribute to bind it to a record field.
To prepare a table for template rows, call the templateRows() plugin method on a table element.
The data rows can be added or read with the plugin methods described below.
Name | Location | Age | Verified |
---|
Options
The following options are available:
Name | Type | Description | Default |
---|---|---|---|
init |
Function |
A function that is called for each added row after it has been added to the table.
It gets the following arguments:
|
None |
jsonField |
String, Node | The form field that contains all records as JSON string. If set, the table rows are created at load time. The template must also be set in the options then. This option can be set later with the loadJSON() method. It will be reused for saving the table data to a JSON field for form submit. | None |
template |
Node, String | The template element that contains a table row to use for all records. Specified as Node or CSS selector. | None |
Plugin methods
This plugin provides methods to set and read the table data.
addRow
addRow()
→ HTMLTableRowElementaddRow(record)
→ HTMLTableRowElement
Appends a new table row with the specified record data. If no record is specified, the new row will not be altered.
addRows
addRows(records)
→ Array(HTMLTableRowElement)
Appends new table rows with the specified record data.
getRecord
getRecord(row)
→ Object
Returns the object with the data from the specified table row fields. If a row was created without a record, a new object will be assigned so that subsequent calls return the same record instance.
getRecords
getRecords()
→ Array
Returns an Array of objects with the data from the table row fields. If a row was created without a record, a new object will be assigned so that subsequent calls return the same record instance.
loadJSON
loadJSON()
→ Array(HTMLTableRowElement)loadJSON(jsonField)
→ Array(HTMLTableRowElement)
Appends new table rows with the data from the specified JSON form field, and remembers the field for later updating. If the field is not specified, it must be set in the plugin options. Returns the added table row elements.
If the JSON form field is already set with the element, the loadJSON
method is automatically called at initialisation time.
saveJSON
saveJSON()
→ voidsaveJSON(jsonField)
→ void
Saves the data from the table row fields as JSON to a form field. If the field is not specified, it must be set in the plugin options or in a previous loadJSON() call.