Advanced table markup
Everything on this page builds on the basic pipe syntax.
The short version of the grammar: attributes go before a single |, content
after it — on cells, rows, the caption, and the table itself.
Spanning rows and columns
colspan and rowspan work exactly as in HTML:
{|
! Name !! colspan="2" | Contact
|-
| rowspan="2" | Ada
| email || [email protected]
|-
| phone || 555-0100
|}Attributes — where they go
| On | Written as | Useful attributes |
|---|---|---|
| the table | {| style="…" | style, class, border, width |
| a row | |- style="…" | style, class, align, valign, bgcolor |
| a cell | | style="…" | content | style, class, colspan, rowspan, scope, align, valign, width, bgcolor |
| the caption | |+ style="…" | text | same global set |
{| style="width: 100%"
|+ style="caption-side: bottom" | Figures are estimates
|- style="background: #f6efe3"
! Region !! style="width: 8em" | Total
|-
| style="text-align: right" | East || 1,204
|}Attributes are sanitized: only the allowlisted names survive, and style
values are filtered (no expression(), javascript:, imports, or other
tricks). Anything not allowed is silently dropped, never rendered.
Pipes inside cells
The attribute separator is a raw |, which collides with wikitext that uses
pipes. The rules:
- A cell that starts with
[[treats every pipe as content — so| [[Page|label]]just works, no escaping needed. - Anywhere else, put pipe-bearing markup after an explicit attribute
block, or use
{{!}}-free alternatives: wrap the cell content so the first pipe you write is the attribute separator:| style="…" | [[Page|label]] and {{Include|param}}. - Templates are expanded before table parsing, so a
|produced by an include does not break the table.
Nested and indented tables
Open another {| on its own line inside a cell to nest; close each table
with its own |}:
{|
| outer cell
|
{|
| inner || table
|}
|}Prefix the {| line with : characters to indent the whole table — each
colon is one level.
Forgiving parsing
The parser repairs sloppy tables instead of failing:
- You can skip the first
|-— the first cell line opens a row for you. - Unclosed rows and cells are closed automatically at
|-and|}. - A table with no cells at all still renders (as one empty cell), so a half-written table never swallows the rest of the page.
How wikitable-card really works
The responsive helpers are pure
CSS with one exception: on a wikitable-card table the parser records
the plain text of your ! header cells, column by column, and stamps every
td with a data-label attribute. The phone view hides the header row and
prints each cell as a “Header: value” pair from those labels.
Practical consequences:
- Card tables need a proper header row (
!cells) — no headers, no labels. - Labels are per-column position: a
colspanin the header row will shift the labels of the columns after it. - Header markup is stripped to plain text for the label (
'''Bold'''becomesBold).
For genuinely huge tables, prefer wikitable-scroll (+ wikitable-pinfirst
if the first column is the key) over shrinking fonts — horizontal scroll
preserves readability; 9px text does not.