Multiline tables

Article last updated at November 3, 2026

Tables that support not only simple content inside cells, such as inline formatting, links, etc., but also complex content, for example, lists, code blocks, and even other tables.

Multiline tables support cell merging.

Syntax

  • the table starts with #| and ends with |#;
  • rows start and end with ||;
  • cells are separated by the | character.

Table headers

To mark header rows, use the table attribute header-rows. For more details, see the section Header rows.

#|
|| Header1 | Header2 ||
|| Text | Text ||
|#

Result:

Header1

Header2

Text

Text

Multiline text

You can place any multiline text in a table cell. For example, lists.

#|
||Text
on two lines
|
- Text 1
- Text 2
- Text 3
- Text 4||
|#

Result:

Text
on two lines

  • Text 1
  • Text 2
  • Text 3
  • Text 4

Or even another table:

#|
|| 1
|

Text above the nested table

#|
|| 5
| 6||
|| 7
| 8||
|#

Text below the nested table||
|| 3
| 4||
|#

Result

1

Text above the nested table

5

6

7

8

Text below the nested table

3

4

Table attributes

You can set attributes for a table at three levels: for the entire table, for an individual row, and for an individual cell.

Level Syntax Where it is located
Table |:{ ... } On a separate line between #| and the first row ||
Line ||:{ ... } On the same line as ||, immediately after it
Cell ::{ ... } At the beginning of the cell content, immediately after | (or after ||:{ ... } for the first cell of a row)

Attributes for the entire table are set on a separate line between #| and the first row ||:

#|
|:{class="example"}
|| Header1 | Header2 ||
|| Text | Text ||
|#

Row attributes are set immediately after the opening ||:

#|
||:{class="example"} Header1 | Header2 ||
|| Text | Text ||
|#

Cell attributes are set at the beginning of its content. For the first cell of a row, immediately after || (or after the row attributes, if any), and for the rest, immediately after |:

#|
||::{align="center"} Header1 | Header2 ||
|| Text |::{align="top-right"} Text ||
|#

Formatting rules

  • Each attribute block must be on the same line as its delimiter: a line break between || / | and the attribute block disables their recognition, and the text becomes part of the cell content.
  • Spaces are not allowed between || and :{ (row attributes).
  • Spaces are not allowed between | and ::{ (cell attributes, except for the first cell of a row).
  • After ||:{...} before ::{...} of the first cell on the same line, spaces and tabs are allowed.
  • A line with table attributes (|:{ ... }) can occur multiple times between #| and the first line ||; when keys match, later values override earlier ones.

Header rows

To mark the first N rows of a table as header rows, use the table attribute header-rows="N". Header rows are rendered as <th scope="col"> instead of <td>.

The value of N must be a positive integer.

#|
|:{header-rows="1"}
|| Header1 | Header2 | Header3 ||
|| Text | Text | Text ||
|| Text | Text | Text ||
|#

Result

Header1

Header2

Header3

Text

Text

Text

Text

Text

Text

Custom cell sizes

Cell sizes can be controlled using attributes.

To set a custom cell width, use the syntax {style="width: 400px"} inside the cell.

#|
|:{header-rows="1"}
|| Header1 {style="width: 400px"} | Header2 ||
|| Text | Text ||
|#

Result

Header1

Header2

Text

Text

To set a custom cell height, use the syntax {style="height:100px"} inside the cell.

#|
|:{header-rows="1"}
|| Header1 {style="height:100px"} | Header2 ||
|| Text | Text ||
|#

Result

Header1

Header2

Text

Text

Merging cells

Cells can be merged vertically using a cell with the "^" character:

#|
|:{header-rows="1"}
|| Header1         | Header2   ||
|| Text spanning two rows  | Another text ||
|| ^                  | More text    ||
|#

Result

Header1

Header2

Text spanning two rows

Another text

More text

Horizontal merging is supported via the ">" character:

#|
|:{header-rows="1"}
|| Header1            | Header2   ||
|| Text spanning two columns  | >            ||
|| Another text          | More text    ||
|#

Result

Header1

Header2

Text spanning two columns

Another text

More text

Cell merge characters can be used together:

#|
|:{header-rows="1"}
|| Header1                       | Header2   | Header3 ||
|| Text spanning two columns and two rows  | >            | Text      ||
|| ^                                | >            | More text  ||
|#

Result

Header1

Header2

Header3

Text spanning two columns and two rows

Text

More text

Escaping cell merge characters

To get a cell with one of the merge characters, you can use escaping with "",
i.e. "^" and ">".

#|
|:{header-rows="1"}
|| Header1                       | Header2 | Header3 ||
|| Text in one cell             | \>         | Text      ||
|| \^                               | \>         | More text  ||
|#

Result

Header1

Header2

Header3

Text in one cell

>

Text

^

>

More text

Text alignment in cells

To control the alignment of cell content, use the cell attribute align:

#|
|:{header-rows="1"}
|| Header1                              | Header2 | Header3 ||
||::{align="center"} Text spanning two columns and two rows | >          | Text      ||
|| ^                                       | >          | More text  ||
|#

Result

Header1

Header2

Header3

Text spanning two columns and two rows

Text

More text

The following values are available:

  • top-left
  • top-center
  • top-right
  • center
  • bottom-left
  • bottom-center
  • bottom-right

Deprecated syntax

Warning

Previously, the class syntax {.cell-align-*} was used for alignment inside the cell content. It still works for backward compatibility, but is considered deprecated — use the attribute ::{align="..."} instead.

#|
|:{header-rows="1"}
|| Header1                                           | Header2 | Header3 ||
|| Text spanning two columns and two rows {.cell-align-center} | >          | Text      ||
|| ^                                                    | >          | More text  ||
|#

Deprecated values:

  • cell-align-top-left
  • cell-align-top-center
  • cell-align-top-right
  • cell-align-center
  • cell-align-bottom-left
  • cell-align-bottom-center
  • cell-align-bottom-right

Opening in a modal window

Wide tables are convenient to open in a modal window. In multiline tables, this is implemented using the attribute {wide-content}. The attribute is added immediately after the characters closing the table |#.

#|
|:{header-rows="1"}
|| Header1 | Header2 ||
|| Text | Text ||
|| Text | Text ||
|| Text | Text ||
|# {wide-content}

Result

Header1

Header2

Text

Text

Text

Text

Text

Text

For simple and multiline tables, you can limit the height by adding the attribute {sticky-header}. If the table exceeds the screen size of the user's device, its header becomes fixed, the height is limited to the screen height, and the table content starts scrolling.

#|
|:{header-rows="1"}
|| Header1                       | Header2 | Header3 ||
|| Text in one cell             | \>         | Text      ||
|| \^                               | \>         | More text  ||
|| Text in one cell             | \>         | Text      ||
...
|| \^                               | \>         | More text  ||
|| Text in one cell             | \>         | Text      ||
|| \^                               | \>         | **More text**  ||
|#

{sticky-header}

Header1

Header2

Header3

Text in one cell

>

Text

^

>

More text

Text in one cell

>

Text

^

>

More text

Text in one cell

>

Text

^

>

More text

Text in one cell

>

Text

^

>

More text

Text in one cell

>

Text

^

>

More text

Text in one cell

>

Text

^

>

More text

Text in one cell

>

Text

^

>

More text

Text in one cell

>

Text

^

>

More text

Text in one cell

>

Text

^

>

More text

Text in one cell

>

Text

^

>

More text

Text in one cell

>

Text

^

>

More text

Text in one cell

>

Text

^

>

More text

Next