Skip to main content

Section 4.17 Tables and Tabulars

A <table> is a container that houses a <tabular>, which is the actual rows and columns of table entries.

Note that <tabular> may be constructed using the Complex Table Editor 1  tool online and then exported in PreTeXt syntax. This produces verbose PreTeXt syntax that is usually equivalent to much simpler PreTeXt syntax once you understand the borders and alignment considerations below.

Subsection 4.17.1 Tables

A <table> is similar to other blocks in PreTeXt (Section 4.2) and is most similar to a <figure>. It will earn a number, which is likely to be a part of the text of a cross-reference pointing to the table. Rather than a <caption>, it will have a <title>. The main difference is that the principal content must be a <tabular>. Only.

Subsection 4.17.2 Tabular

A <tabular> is the actual headers, rows, and columns of a table. As discussed above, a typical use is to place it inside a <table>, though it can be placed all by itself, typically in among a run of paragraphs.

Fundamentally a <tabular> is a sequence of <row> and each <row> is a sequence of <cell>, which could also be called “table entries.”

Subsection 4.17.3 Table Cells

A given cell can span multiple columns, by providing the @colspan attribute with a value that is a positive number, the cell will extend to occupy additional columns.

Subsection 4.17.4 Table Rows

A <row> of a table is a sequence of <cell> elements. Each row should occupy the same number of cells, when considering the @colspan, as discussed above.

To achieve column headers, you indicate that a row contains headers. Typically, the contents of every cell in this row will then be rendered in bold, or some other style. The <row> element accepts a @header attribute with possible values of no (the default), yes, or vertical. The latter is useful if space is at a premium (which always seems to be the case with tables), and the cells of a column are narrow and the header is long. Note that only the first (top) rows can be treated as column headers and these rows must be contiguous. If you think you need column headers mid-tabular, maybe you really have two tables?

Subsection 4.17.5 Table Columns

Prior to all of the <row> within a <tabular>, there may be a sequence of empty <col/> elements. Having these is optional, but once there is one, then there needs to be as many as the number of columns of the table. These elements do not have any content that appears in the table, but are used to hold attributes that influence the borders or alignment of the cells within a column. These are described below.

So it should now be clear that, after much consideration, that we have chosen a “row first” approach to describing a table.

We plan to support row headers, in a manner similar to column headers, with an attribute possible on the initial <col/> elements.

Subsection 4.17.6 Table Borders and Rules

You can view each cell of your table as having four borders. Or you can imagine rows and columns separated by horizontal or vertical rules. These additions to your table do not change the arrangement of information into rows and columns (a doubly-indexed data set), though you may think it makes the presentation clearer. But less is actually more.

Best Practice 4.17.1. Vertical Rules in Tables.

One of the goals of PreTeXt is to gently guide authors towards good choices in the design of their documents, even if we do not claim to know it all ourselves. Take a close look at Table 4.1.3. What's missing? No vertical rules. Try living without them, you will not really miss them. If you think you need to divide a table into two halves, maybe you really need two tables (and then see the “side-by-side” capabilities, Section 4.21).

In the documentation for his excellent package, booktabs 2 , Simon Fear gives two rules for what he calls “formal tables”: (1) Never, ever use vertical rules, and (2) Never use double rules. We have resisted the temptation to enforce the former and have provided an alternative to the second (three thicknesses). He refers to using tables for layout as creating “tableau.” If you are finicky about the look of your work, the first three pages of the documentation is recommended reading.

A given <cell> can have a border on its bottom edge, and on its right edge. This is accomplished with the @bottom and @right attributes. The possible values are minor, medium, and major, which control thickness. (Not every conversion can produce three distinct thicknesses, so this should be considered a hint to the conversion.) A value of none is the default behavior when the attribute is not used, but can be given explicitly.

How to get a left border on the first cell of a row? The <row> element allows a @left attribute which will put a border on the left end of the row, which is also the left border of the first cell.

How to get a top border on a cell? Put a bottom border on the cell above it. But what if the cell is already in the top row and has no cell above it? The relevant <col> element allows a @top attribute which will place the necessary border on the top-row cell.

Borders and rules verge on presentation, so we are not concerned about which cell a border (or rule) belongs to. So, generally @bottom and @right can be used in many places, and the exceptional @top and @bottom maybe used to get the missing border \(n+1\) for a vertical or horizontal sequence of \(n\) cells.

The attributes described for cells may also be used on <row>, <col>, and <tabular>. For example a thick horizontal rule after two rows of headers could be accomplished with

<row header="yes">...</row>
<row header="yes" bottom="major">...</row>

We will not detail all the combinations that are possible, so experiment and you should be able to create any rational look (and some irrational ones).

Subsection 4.17.7 Table Cell Alignment

The horizontal alignment of the contents of a <cell> can be influenced by the @halign attribute with values left, right, center, and for “paragraph cells,” justify. Similarly the @valign attribute will influence the vertical alignment through values top, middle, and bottom. Default alignments are left and middle.

To align the cells of an entire <row>, <col>, or <tabular> identically, place the relevant attribute on the relevant element. Note that these choices can be overridden by different values on individual consituents.

Subsection 4.17.8 Multi-line Cells

A cell of a table may contain more text that fits onto one line. If you know exactly where you want the line-breaks to be, then structure the entire cell as a sequence of <line> elements.

Or, if you want the contents of a cell to look and feel more like a paragraph (or several), structure the cell as a sequence of <p>, which can contain the usual content of a <p>, excepting “larger” content such as display mathematics or lists. Now, in this case, you must constrain the width of the cell's column, to force the line-breaking necessary to render a paragraph as several lines. Use the relevant <col/> element, and specify a percentage of the tabular's overall width, like this:

<col width="40%"/>

A paragraph cell can be right-justified with the @halign attribute set to justify. But be aware that if the column is skinny, this can lead to awkward inter-word spaces.

Subsection 4.17.9 Breakable Tabulars

A <tabular> may be specified as breakable, inside of a <table> or not. Use the attribute @break set to yes. (The default is no.) This only affects conversions to formats with page breaks, such as PDF. Usually the motivation will be a <table> or <tabular> that is too long for a page, but even a shorter table can be allowed to page break.

As of 2022-07-28 this is effective for simple tables, but introduces some variations for more complex constructions. This is implemented with the longtable package, which suggests it may take up to four passes with to obtain the final version. It is also not effective for a <tabular> that is a side-by-side panel. Consult the sample article for examples where more progress is necessary.

Subsection 4.17.10 Table Philosophy

The Chicago Manual of Style (15e, 13.1) says:

A table offers an excellent means of presenting a large number of individual similar facts so that they are easy to scan and compare. A simple table can give information that would require several paragraphs to present textually, and it can do so more clearly. … A table should be as simple as the material allows and understandable on its own; even a reader unfamiliar with the material presented should be able to make general sense of a table.

While our implementation allows for some presentational elements (borders, rules, alignment) our conversions will presume your table hews to the purposes described by CMOS. In particular, it is not a device for spatial layout of complex elements. You might find that the <sidebyside> and <sbsgroup> layout devices will suit that purpose better (see Section 4.21).

Best Practice 4.17.2. Tables are Difficult.

Width is always at a premium, and then when a <tabular> has more than a few columns, the width becomes even more dear. When a <cell> has text that looks like a phrase or a sentence, rather than numerical data or symbols, it can be even harder to pack it all in. A common example is a schedule of talks at a small professional conference where each time slot (rows) might have two or three talks simultaneously in parallel sessions (columns).

We offer paragraph cells which automatically break lines, but you need to specify a @width on the <col> as a percentage to indicate where line-breaking happens. For manual line-breaking, a <cell> can be structured entirely by <line> elements.

The next complication is that the used for PDF output tends to make columns as wide as necessary and will not break lines without the devices mentioned in the previous paragraph. The HTML output can sometimes be a bit more forgiving and flexible. So we suggest building the output first and getting that right, and then the HTML is likely to follow along and not need much futher refinement.

In contrast to most of PreTeXt, you may need to experiment, refine your approach, iterate, and maybe do things contrary to usual best practices elsewhere. For example, the clickables for URLs and knowls might need to be short and less-informative in order to save some width. Abbreviations, initialisms, and acronyms can also save some width.

Subsection 4.17.11 Summary: Table Reference

Finally, we summarize the available options for a table with…a table. Because it would take too much text to describe fully.

This table describes how to construct tables via the tabular element. The table element may be used to enclose the raw table, so as to associate a title and get vertical separation with horizontal centering.

The tabular element contains a sequence of row elements, and must contain at least one. Each row contains a sequence of cell elements and must have the same number in each row (acccounting for the use of the colspan attribute). The contents of the cell elements are the text to appear in entries of the table.

A sequence of col elements may optionally be used. But if one appears, then there must be the right number for the width of the table. They are empty elements always, and just carry information about their respective column.

Where the body of the table below has an entry, it means the attribute may be used on the element, and affects the range of the tabular described by the element. Employment of an attribute on elements to the right in the table will supersede use on elements to the left. Generally, every cell has right and bottom borders, but only cells at the left side of the table have a left border and only cells across the top have a top border. Only one cell has four borders.

Table 4.17.3. Tabular Elements and Attributes (p = potential)
Attributes Elements Values
tabular col row cell * = default
top × × none*, minor, medium, major
left × × none*, minor, medium, major
bottom × × × none*, minor, medium, major
right × × × none*, minor, medium, major
halign × × × × left*, center, right, justify
halign p decimal, character
header p × yes/vertical/no*
valign × × top, middle*, bottom
colspan × 1*, positive integer
rowspan p 1*, positive integer
width × percentage
colors p p p p