Tables
The Table
feature offers table creation and editing tools that help content authors bring tabular data into their documents. Tables help organize the content in a distinct, visual way that stands out from the text and is more easily readable for certain types of information. They are perfect for listing, grouping, and otherwise organizing data sets or for providing information in a clear, efficient way.
Tables are great for schedules, timetables, price lists or menus; for listing terms and conditions or providing troubleshooting solutions. They also visually break and provide relief from large body texts. CKEditor 5 offers all necessary functionality to produce advanced, visually appealing and highly efficient tables.
You may look for more interesting details in the Tables in CKEditor 5 blog post after reading this guide.
The basic table feature feature is enabled by default in all predefined builds.
# Demos
# Basic table features
The editor bellow shows the basic set of table features focusing on the structure and semantics. Use the Insert table toolbar button in the editor below to create new tables. Focus any cell in the table to display the toolbar with buttons that will help you further shape the structure of the table.
Click anywhere inside the table to invoke the table toolbar. The features available in there allow users to add or remove columns and rows and merge or split cells . It is also worth noting that you will find them out–of–the–box in all predefined builds.
The ultimate table of spaceflight:
Presented below is a list of the first countries to send a human into space. Listed below these are countries able to launch their own manned spacecraft (the other listed astronauts were sent to space onboard a foreign spacecraft).
Countries that sent their citizen into space |
|||
Country |
Date of launch |
Name |
Spacecraft |
USSR | 1961 | Yuri Gagarin | Vostok-1 |
USA | 1961 | Alan Shepard | Mercury-Redstone 3 |
Czechoslovakia | 1978 | Vladimír Remek | Soyuz 28 |
Poland | 1978 | Mirosław Hermaszewski | Soyuz 30 |
East Germany | 1978 | Sigmund Jähn | Soyuz 31 |
Countries capable of sending their own manned spacecraft |
|||
Country |
Capable since |
First astronaut |
Current spacecraft |
USSR/Russia | 1961 | Yuri Gagarin | Soyuz MS |
USA | 1961 | Alan Shepard | Crew Dragon |
China | 2003 | Yang Liwei | Shenzhou |
# Table and cell styling tools
In addition to the default table features described in the previous section, the editor below comes with some additional tools that will help you modify the look of tables and table cells, for instance, their border color and style, background color, padding, or text alignment. The table and cell properties are available from the table toolbar on click, just like basic table features.
The planet of robots
Humans have always searched for new places to explore and new ways to get where they wanted. Where no human could (yet) go, we would send robots to do a job for us. Mars, one of our closest neighbours, is currently home to quite a few robotic devices, some of which are able to move around freely, roaming the wild, red sands and relaying their experience back to the mother planet.
Color coding for missions | |||
Failed | Successful | In progress | Planned |
Country/Agency | Rover | Date of landing | Operational time | Distance travelled | Notes |
---|---|---|---|---|---|
PROP-M rover | November 27, 1971 | 0 days | 0 km | Lost when it crash-landed on Mars | |
PROP-M rover | December 2, 1971 | 0 days | 0 km | Lost when Mars 3 lander stopped communicating about 20 seconds after landing | |
Sojourner | July 4, 1997 | 85 days | 100 m (330 ft) | First successful rover on Mars | |
Spirit | January 4, 2004 | 2269 days | 7.73 km (4.80 mi) | ||
Opportunity | January 25, 2004 | 5498 days | 45.16 km (28.06 mi) | The longest distance traveled by any rover and the most days operated | |
Curiosity | January 25, 2012 | 3214 days |
24.85 km (15.44 mi) as of 4 March 2021 |
Currently active | |
Perseverance | February 18, 2021 | 96 days |
322 m (1,056 ft) as of 14 May 2021 |
Currently active | |
Zhurong | May 14, 2021 | 11 days | Currently active | ||
Rosalind Franklin | 2023 (planned) | 420 days (planned) | Planned to launch 2022 |
Put the caret anywhere inside the table to invoke the table toolbar. Then click the “Table properties” button in the toolbar to open a pop–up with multiple options that will allow you to shape the look of the entire table. If you click the “Cell properties” button, a similar interface will appear with styling options for individual table cells.
Learn more about configuring color palettes in the table styling pop–up interfaces.
By default, table styling tools are not included in the predefined builds and must be installed separately. See the installation section to learn how to enable them in your editor.
# Table column resize
The TableColumnResize
plugin adds support for resizing tables and table columns. It gives the content creator full control over the column width. It is a great tool to control both the content and the look of the table. By resizing individual columns, the authors can adjust them to their needs, depending on content inside.
To resize a column, simply hover you pointer over the column edge until it gets highlighted. Just drag the column edge until you achieve the desired size and release.
The column resize feature is compatible with the Export to Word feature. The converter will respect the column width set in the editor and retain it in the effecting .DOCX file.
Dwarf planets of the Solar System
Name | Region | Orbital radius (AU) | Orbital period (years) | Number of moons |
---|---|---|---|---|
Ceres | Asteroid belt | 2,768 | 4,6 | - |
Orcus | Kuiper belt | 39,40 | 247,3 | 1 |
Pluto | Kuiper belt | 39,48 | 247,9 | 5 |
Haumea | Kuiper belt | 43,22 | 284,1 | 2 |
Quaoar | Kuiper belt | 43,69 | 288,8 | 1 |
Makemake | Kuiper belt | 45,56 | 307,5 | 1 |
Gonggong | Scattered disc | 67,38 | 553,1 | 1 |
Eris | Scattered disc | 67,78 | 558,0 | 1 |
Sedna | detached | 506,8 | 11,400 | no data |
By default, the table column resize feature is not included in the predefined builds and must be installed separately.
# Table caption
The TableCaption
plugin adds support for table captions. These work very much like image captions — the caption informs the reader about the content of the table. Using captions is also beneficial from the accessability point of view as they would be read by screen readers.
Click on the table caption in the demo to edit it or use the table toolbar button to toggle the caption on and off.
By default, the table caption feature is not included in the predefined builds and must be installed separately. See the installation section to learn how to enable it in your editor.
By default, the table caption is placed above the table. You can change the placement by setting caption-side
in your content styles for the .ck-content .table > figcaption
style. Changing it to caption-side: bottom
will display the caption below the table.
# Nesting tables
Starting from version 27.1.0 CKEditor 5 allows nesting tables inside other table’s cells. This may be used for creating advanced charts or layouts based on tables. The nested table can be formatted just like a regular one.
You can test this feature in the demo below by adding a table in the “abandoned” section that was left blank at the bottom of the main table. To nest a table, simply click in the selected cell and use the “Insert table” button in the toolbar to insert a new, nested table into an existing one.
American spacecraft
Status | Name and service time | ||||||||
discontinued |
|
||||||||
in use |
|
||||||||
planned |
|
||||||||
abandoned |
If you would like to block the possibility to nest tables in your editor, see the Disallow nesting tables section to learn how to disable this functionality.
# Table selection
The TableSelection
plugin introduces support for the custom selection system for tables that lets you:
- Select an arbitrary rectangular table fragment — a few cells from different rows, a column (or a few of them) or a row (or multiple rows).
- Apply formatting or add a link to all selected cells at once.
The table selection plugin is loaded automatically by the Table
plugin and can be tested in the demos above.
# Installation
# Basic table features
The basic table features are enabled by default in all predefined builds. The installation instructions are for developers interested in building their own, custom rich text editor.
To add only the basic table features to your editor, install the @ckeditor/ckeditor5-table
package:
npm install --save @ckeditor/ckeditor5-table
Then add the Table
and TableToolbar
plugins to your plugin list and configure the table toolbar:
import Table from '@ckeditor/ckeditor5-table/src/table';
import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';
ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Table, TableToolbar, Bold, ... ],
toolbar: [ 'insertTable', ... ],
table: {
contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells' ]
}
} )
.then( ... )
.catch( ... );
# Default table headers
In order to make every inserted table to have n
number of rows and columns as table headers by default, set an optional table config property defaultHeadings
as follows:
import Table from '@ckeditor/ckeditor5-table/src/table';
import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';
ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Table, TableToolbar, Bold, ... ],
toolbar: [ 'insertTable', ... ],
table: {
defaultHeadings: { rows: 1, columns: 1 }
}
} )
.then( ... )
.catch( ... );
Check the table with default headers applied to both the first row and the first column in the demo below. Click on the table and use the column properties or the row properties UI button to toggle the respective headers.
Financial report
Main product line for Q4.
|
Sales |
Income |
Revenue |
---|---|---|---|
Walker |
1050 |
$104.000 |
15% |
Stroller |
24 |
$12.000 |
10% |
Walker 3 |
980 |
$97.000 |
15% |
# Table and cell styling tools
To enable not only the basic table features but also the rich table and cell styling tools in your editor, you need to have the @ckeditor/ckeditor5-table
package installed (it is already present in the predefined builds):
npm install --save @ckeditor/ckeditor5-table
Then add the Table
, TableToolbar
, TableProperties
, and TableCellProperties
plugins to your plugin list and configure the table toolbar:
import Table from '@ckeditor/ckeditor5-table/src/table';
import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';
import TableProperties from '@ckeditor/ckeditor5-table/src/tableproperties';
import TableCellProperties from '@ckeditor/ckeditor5-table/src/tablecellproperties';
ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Table, TableToolbar, TableProperties, TableCellProperties, Bold, ... ],
toolbar: [ 'insertTable', ... ],
table: {
contentToolbar: [
'tableColumn', 'tableRow', 'mergeTableCells',
'tableProperties', 'tableCellProperties'
],
// Configuration of the TableProperties plugin.
tableProperties: {
// ...
},
// Configuration of the TableCellProperties plugin.
tableCellProperties: {
// ...
}
}
} )
.then( ... )
.catch( ... );
Learn more about configuring color palettes in the table and table cell property pop–ups.
# Table column resize
To enable the table column resize feature in your editor, you need to have the @ckeditor/ckeditor5-table
package installed (it is already present in the predefined builds):
npm install --save @ckeditor/ckeditor5-table
Then add the Table
and TableColumnResize
plugins to your plugin list and configure the table toolbar:
import Table from '@ckeditor/ckeditor5-table/src/table';
import TableColumnResize from '@ckeditor/ckeditor5-table/src/tablecolumnresize';
ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Table, TableColumnResize, ... ],
toolbar: [ 'insertTable', ... ],
} )
.then( ... )
.catch( ... );
# Table caption
To enable the table caption feature in your editor, you need to have the @ckeditor/ckeditor5-table
package installed (it is already present in the predefined builds):
npm install --save @ckeditor/ckeditor5-table
Then add the Table
, TableToolbar
, and TableCaption
plugins to your plugin list and configure the table toolbar:
import Table from '@ckeditor/ckeditor5-table/src/table';
import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';
import TableCaption from '@ckeditor/ckeditor5-table/src/tablecaption';
ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Table, TableToolbar, TableCaption, Bold, ... ],
toolbar: [ 'insertTable', ... ],
table: {
contentToolbar: [
'toggleTableCaption'
]
}
} )
.then( ... )
.catch( ... );
Read more about installing plugins.
# Configuring styling tools
By default, table styling tools are not included in any predefined editor builds and must be installed separately. See the installation section to learn how to enable them in your editor.
Among other formatting options, table and cell styling tools allow users to create tables with colorful backgrounds and borders. These colors can be easily picked using color palettes in the “Table properties” and “Cell properties” pop–ups. To help users choose the right colors for the content, the color palettes can be pre–configured, like in the editor below:
A beautiful color palette
Red | Pink | Purple | Deep Purple |
Indigo | Blue | Light Blue | Cyan |
Teal | Green | Light Green | Lime |
Yellow | Amber | Orange | Deep Orange |
Brown | Grey | Blue Grey | White |
With the selection inside any table cell, use the “Table properties” and “Cell properties” buttons in the toolbar to inspect available styling and color options.
# Customizing color palettes
You can use these specific configuration options to define customized color palettes for background and border colors to match your document:
tableProperties.borderColors
– Defines the color palette for table borders.tableProperties.backgroundColors
– Defines the color palette for table background.tableCellProperties.borderColors
– Defines the color palette for cell borders.tableCellProperties.backgroundColors
– Defines the color palette for cell background.
The above configurations do not impact the data loaded into the editor, i.e. they do not limit or filter the colors in the data. They are used only in the user interface allowing users to pick colors in a more convenient way.
For instance, to define the same color palette for all border and background configurations, use the following code snippet:
const customColorPalette = [
{
color: 'hsl(4, 90%, 58%)',
label: 'Red'
},
{
color: 'hsl(340, 82%, 52%)',
label: 'Pink'
},
{
color: 'hsl(291, 64%, 42%)',
label: 'Purple'
},
{
color: 'hsl(262, 52%, 47%)',
label: 'Deep Purple'
},
{
color: 'hsl(231, 48%, 48%)',
label: 'Indigo'
},
{
color: 'hsl(207, 90%, 54%)',
label: 'Blue'
},
// ...
];
ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Table, TableToolbar, TableProperties, TableCellProperties, Bold, ... ],
toolbar: [ 'insertTable', ... ],
table: {
contentToolbar: [
'tableColumn', 'tableRow', 'mergeTableCells',
'tableProperties', 'tableCellProperties'
],
// Set the palettes for tables.
tableProperties: {
borderColors: customColorPalette,
backgroundColors: customColorPalette
},
// Set the palettes for table cells.
tableCellProperties: {
borderColors: customColorPalette,
backgroundColors: customColorPalette
}
}
} )
.then( ... )
.catch( ... );
# Default table and table cell styles
The table styles feature allows for configuring the default look of the tables in the editor. The configuration object should be synchronized with the editor content styles.
The “Table properties” and “Table cell properties” buttons in the toolbar will show the table and table cell properties applied to the table or table cells.
The stylesheet for the editor displayed below looks as follows:
.ck-content .table {
float: left;
width: 550px;
height: 450px;
}
.ck-content .table table {
border-style: dashed;
border-color: 'hsl(90, 75%, 60%)';
border-width: 3px;
}
.ck-content .table table td {
text-align: center;
vertical-align: bottom;
padding: 10px
}
The same values must be passed to the editor configuration as:
- The
table.tableProperties.defaultProperties
object for the table properties. - The
table.tableCellProperties.defaultProperties
object for the table cell properties.
const tableConfig = {
table: {
tableProperties: {
// The default styles for tables in the editor.
// They should be synchronized with the content styles.
defaultProperties: {
borderStyle: 'dashed',
borderColor: 'hsl(90, 75%, 60%)',
borderWidth: '3px',
alignment: 'left',
width: '550px',
height: '450px'
},
// The default styles for table cells in the editor.
// They should be synchronized with the content styles.
tableCellProperties: {
defaultProperties: {
horizontalAlignment: 'center',
verticalAlignment: 'bottom',
padding: '10px'
}
}
}
}
};
The table element should be aligned to the left
side by default. Its size should be 550x450px
. The border style should be dashed
, 3px
of its width, and the color specified as Light green
.
The content should be away about 10px
from the cell’s edges (padding
), vertically aligned to bottom
and horizontally to center
.
The same will be applied for new tables and cells if they are inserted into the editor.
Before people could leave the cradle of humanity and enter the cosmic void, tests were required. A number of animals risked and sometimes lost their lives to open the gates for their owners to be able to reach the stars.
The animal spaceflights started in the late 1940s. German A4 rockets were used for the initial launches, later on each country developed their own carriers. Even though these simian, canine and rodent space farers were the most important test subjects during the first stage of the space race, before launching actual human astronauts, the animal spaceflight is very much a thing even today. In 2018 a rodent crew arrived at International Space Station!
Animal astronauts by country of origin | |
American: fruit flies, primates first flew in the 1940s. The most memorable was Ham, a chimpanzee. |
Soviet: mostly dogs, sent to space since the 1950s. The most memorable was Laika who died during the first part of the journey. |
French: rats and cats (1960s). Félicette was the most notable and the only French cat to survive the landing. |
Chinese: mice, rats and dogs (1960s). |
Read more about all supported properties for the table and table cell features in their API documentation.
The default table and table cell styles do impact the data loaded into the editor. Default properties will not be kept in the editor model.
# Block vs inline content in table cells
The table feature allows for creating block content (like paragraphs, lists, headings, etc.) inside table cells. However, if a table cell contains just one paragraph and this paragraph has no special attributes (like text alignment), the cell content is considered “inline” and the paragraph is not rendered.
This means that a table cell can have two states: with inline content or with block content. The reason for this differentiation is that most tables contain only inline content (e.g. in the demo above) and it is common for “data tables” to not contain any block content. In such a scenario, printing out <p>
elements would be semantically incorrect and also unnecessary. There are, however, scenarios where the user wants to create, for example, a list inside a table cell and then the support for block content is necessary.
“Rendering” here refers to the view layer. In the model, a cell is always filled with at least a <paragraph>
. This is because of consistency, as — since a cell always has some block content — the text is never directly inside the <tableCell>
. This also allows features like Enter support to work out of the box (since a <paragraph>
exists in the model, it can be split despite the fact that it is not present in the view).
# Inline content
The following is the model representation of table cells with inline content only (a single <paragraph>
inside):
<table>
<tableRow>
<tableCell>
<paragraph>Foo</paragraph>
</tableCell>
<tableCell>
<paragraph>Bar</paragraph>
</tableCell>
</tableRow>
</table>
The above model structure will be rendered to the data as:
<figure class="table">
<table>
<tbody>
<tr>
<td>Foo</td>
<td>Bar</td>
</tr>
</tbody>
</table>
</figure>
In the editing view (the editable container in which the user edits the content), additional <span>
elements are created to compensate for the hidden <paragraph>
elements:
<figure class="table">
<table>
<tbody>
<tr>
<td><span>Foo</span></td>
<td><span>Bar</span></td>
</tr>
</tbody>
</table>
</figure>
# Block content
If a table cell contains any other block content than a single <paragraph>
with no attributes, these block elements will be rendered.
The following is a sample table with some block content (model representation):
<table>
<tableRow>
<tableCell>
<paragraph>Foo</paragraph>
<paragraph>Bar</paragraph>
</tableCell>
<tableCell>
<heading1>Some title</heading1>
</tableCell>
<tableCell>
<paragraph textAlign="right">Baz</paragraph>
</tableCell>
</tableRow>
</table>
The above model structure will be rendered to the data and to the editing view as:
<figure class="table">
<table>
<tbody>
<tr>
<td>
<p>Foo</p>
<p>Bar</p>
</td>
<td>
<h2>Some title</h2>
</td>
<td>
<p style="text-align: right;">Baz</p>
</td>
</tr>
</tbody>
</table>
</figure>
At the moment, it is not possible to completely disallow block content in tables. See the discussion on GitHub about adding a configuration option that would enable that. Feel free to upvote 👍 if this feature is important to you.
# Disallow nesting tables
By default, the editor allows nesting a table inside another table’s cell.
In order to disallow nesting tables, you need to register an additional schema rule. It needs to be added before the data is loaded into the editor. Due to that, it is best to implement it as a plugin:
function DisallowNestingTables( editor ) {
editor.model.schema.addChildCheck( ( context, childDefinition ) => {
if ( childDefinition.name == 'table' && Array.from( context.getNames() ).includes( 'table' ) ) {
return false;
}
} );
}
// Pass it via config.extraPlugins or config.plugins:
ClassicEditor
.create( document.querySelector( '#editor' ), {
extraPlugins: [ DisallowNestingTables ],
// The rest of the configuration.
} )
.then( ... )
.catch( ... );
Check the plugin development guide if you need more information about the technical side of this solution.
# Common API
# UI components
The table plugins register the following UI components:
Component name | Registered by |
---|---|
The 'insertTable' dropdown |
Table |
The 'tableColumn' dropdown |
|
The 'tableRow' dropdown |
|
The 'mergeTableCells' split button |
|
The 'tableProperties' button |
TableProperties |
The 'toggleTableCaption' button |
TableCaption |
The 'tableCellProperties' button |
TableCellProperties |
# Toolbars
The TableToolbar
plugin introduces two balloon toolbars for tables.
- The content toolbar shows up when a table cell is selected and it is anchored to the table. It is possible to configure its content. Normally, the toolbar contains the table-related tools such as
'tableColumn'
and'tableRow'
dropdowns and'mergeTableCells'
split button. - The table toolbar shows up when the whole table is selected, for instance using the widget handler. It is possible to configure its content.
# Editor commands
Command name | Command class | Belongs to (top–level plugin) |
---|---|---|
'insertTable' |
InsertTableCommand |
Table |
'insertTableColumnLeft' |
InsertColumnCommand |
|
'insertTableColumnRight' |
InsertColumnCommand |
|
'insertTableRowAbove' |
InsertRowCommand |
|
'insertTableRowBelow' |
InsertRowCommand |
|
'removeTableColumn' |
RemoveColumnCommand |
|
'removeTableRow' |
RemoveRowCommand |
|
'selectTableColumn' |
SelectColumnCommand |
|
'selectTableRow' |
SelectRowCommand |
|
'setTableColumnHeader' |
SetHeaderColumnCommand |
|
'setTableRowHeader' |
SetHeaderRowCommand |
|
'mergeTableCellRight' |
MergeCellCommand |
|
'mergeTableCellLeft' |
MergeCellCommand |
|
'mergeTableCellUp' |
MergeCellCommand |
|
'mergeTableCellDown' |
MergeCellCommand |
|
'splitTableCellVertically' |
SplitCellCommand |
|
'splitTableCellHorizontally' |
SplitCellCommand |
|
'toggleTableCaption' |
ToggleTableCaptionCommand |
TableCaption |
'tableBorderColor' |
TableBorderColorCommand |
TableProperties |
'tableBorderStyle' |
TableBorderStyleCommand |
|
'tableBorderWidth' |
TableBorderWidthCommand |
|
'tableAlignment' |
TableAlignmentCommand |
|
'tableWidth' |
TableWidthCommand |
|
'tableHeight' |
TableHeightCommand |
|
'tableBackgroundColor' |
TableBackgroundColorCommand |
|
'tableCellBorderStyle' |
TableCellBorderStyleCommand |
TableCellProperties |
'tableCellBorderColor' |
TableCellBorderColorCommand |
|
'tableCellBorderWidth' |
TableCellBorderWidthCommand |
|
'tableCellHorizontalAlignment' |
TableCellHorizontalAlignmentCommand |
|
'tableCellWidth' |
TableCellWidthCommand |
|
'tableCellHeight' |
TableCellHeightCommand |
|
'tableCellPadding' |
TableCellPaddingCommand |
|
'tableCellBackgroundColor' |
TableCellBackgroundColorCommand |
|
'tableCellVerticalAlignment' |
TableCellVerticalAlignmentCommand |
We recommend using the official CKEditor 5 inspector for development and debugging. It will give you tons of useful information about the state of the editor such as internal data structures, selection, commands, and many more.
# Known issues
While the table nesting functionality is fully functional, the Markdown code generated with the Markdown output feature will not properly render nested tables (#9475). Feel free to upvote 👍 this issue on GitHub if it is important for you.
# Contribute
The source code of the feature is available on GitHub in https://github.com/ckeditor/ckeditor5/tree/master/packages/ckeditor5-table.
Every day, we work hard to keep our documentation complete. Have you spotted an outdated information? Is something missing? Please report it via our issue tracker.