Table placement & styling

It is not your imagination that a table caption looks glued to the table. LaTeX’s standard classes set \abovecaptionskip to 10pt and \belowcaptionskip to 0pt — identically in article, report and book — and those defaults are tuned for figures. Since convention puts a table’s caption above the table, the side with air ends up on top and the zero side touches the table. That is where the cramped look comes from. This page covers everything around the tabular: placement and captioning through the table environment, what to do with a table wider than the page, rotating one sideways, and threeparttable for notes. Building the contents themselves belongs to “tabular basics” and “Column spec, alignment & width”.

Why tables float — the difference between table and tabular

Because a table cannot be broken across a page. What tabular builds is one large box, and a box cannot be split at a page boundary. If LaTeX tried to set it exactly where it appears in the source and the space left were too small, you would get a gap or a wrecked page. So it treats tables and figures as floats, detaching them from the running text and sending them somewhere they fit. The mechanism for using that is the table environment: you put a tabular inside it, give it a numbered heading such as “Table 1” with \caption{…}, and make it referenceable with \label{…} and \ref{…}. In your prose you then write a reference by number — “as Table~\ref{tab:sales} shows” — and no matter how many pages the table drifts, the number comes out right. The ~ is a tie, keeping the word and its number from being split across a line break.

document.tex
\usepackage{booktabs}
\usepackage{float}   % needed only for the [H] specifier

\begin{table}[htbp]
  \centering
  \caption{Quarterly sales}
  \label{tab:sales}          % \label always AFTER \caption
  \begin{tabular}{@{}lrr@{}}
    \toprule
    Quarter & Sales & YoY \\
    \midrule
    Q1 & 1{,}200 & +5\% \\
    Q2 & 1{,}350 & +8\% \\
    \bottomrule
  \end{tabular}
\end{table}

% in the body: as Table~\ref{tab:sales} shows ...

The difference between the [htbp] and [H] specifiers

[htbp] is a set of places you permit; [H] is an instruction to stop floating. In the brackets right after \begin{table} you list h (here), t (top of a page), b (bottom of a page) and p (a float-only page). Write nothing and the default in both article and book is tbph is not a candidate to begin with. The important part is that the order you write them does not change the order LaTeX tries them: it always attempts t, then b, then p, so [htbp] and [bpht] behave identically. Think of the brackets not as a statement of preference but as an enumeration of permissions.

A leading !, as in [!ht], says “for this float only, ignore the internal limits and try to place it” — it does not mean “put it here”. Those internal limits are actual numbers: in article the defaults are \topfraction = 0.7 (the share of a page floats may occupy at the top), \bottomfraction = 0.3, \textfraction = 0.2 (the minimum share the body text must keep), \floatpagefraction = 0.5 (the threshold for making a float-only page), and at most two floats at the top, one at the bottom and three in total per page (\topnumber, \bottomnumber, \totalnumber). When a table refuses to appear, one of those is usually the reason, and ! merely relaxes the test. If you genuinely want it pinned, use [H] from the float package: with \usepackage{float}, \begin{table}[H] makes the table stop floating and set exactly where it stands in the source — which can leave a large gap at the foot of the page. Reading H as “a float that does not float” prevents a lot of surprises.

SpecifierMeaningRelated default
hHere, at the source position. h alone is not allowed; t is added automaticallyNot part of the default tbp
tTop of a text page\topfraction = 0.7, \topnumber = 2
bBottom of a text page\bottomfraction = 0.3, \bottomnumber = 1
pA float-only page with no body text\floatpagefraction = 0.5
!For this float only, ignore the fractions and counts above. Not a positionAlso covers \textfraction = 0.2 and \totalnumber = 3
HStop floating and pin in place. Requires the float packageNot a specifier of standard LaTeX

Caption above a table, below a figure — and \label after \caption

These two account for most caption mishaps. \caption{…} gives a float a numbered heading, labelling it “Table 1:” in an article or “Table 1.1:” in a book. Tables and figures use separate counters, so their numbers never mix. With the optional argument, \caption[short]{full caption}, the list of tables shows the short form while the body shows the full one. And since \caption is what advances the counter, \label must come after \caption; reverse them and \ref points at the previous number — silently, with no error. As for placement, convention puts the caption above a table and below a figure: you read a table’s heading before entering the data, but look at a figure before reading its explanation. In LaTeX you get the caption above by writing \caption before the tabular, and below by writing it after.

This is where the measurement in the opening pays off. In the standard classes \abovecaptionskip is 10pt and \belowcaptionskip is 0pt, so the air sits only on the outside of the caption and nothing separates the caption from the body of the float. For a figure, whose caption goes below, that is fine; for a table, whose caption goes above, the caption touches the table. There are two cures. In plain LaTeX, declare \setlength{\belowcaptionskip}{6pt}. With the caption package, write \usepackage[skip=6pt]{caption}, or restrict it to tables with \captionsetup[table]{skip=6pt}. Styling the caption itself — font, separator, width — is also the caption package’s job, and is detailed on the “Captions & subfigures” page.

To centre the contents, use \centering. Inside a float the idiom is \centering, not the center environment (\begin{center}…\end{center}): center adds extra vertical space above and below, whereas \centering is only a declaration and adds none. To push the table to the right margin instead of centring it, put \hfill before the contents and all the slack collects on the left. Worth noting: \centering inside a float is safe, but \centering inside a p{width} column is a different story — if that column is the table’s last, the row terminator \\ breaks and you get ! Extra alignment tab has been changed to \cr. How to handle \centering written into a column specification belongs to “Column spec, alignment & width”.

When a LaTeX table is wider than the text

Before you shrink anything, measure where the width is going. Columns of type l, c and r do not wrap, so a table with many columns overruns \textwidth. But the overrun is usually not letters — it is the space between columns. Take a real case: a booktabs table of twelve columns, one heading row and one data row, measures 412.95pt wide, while \textwidth in the default article is 345pt, so it spills by 68pt. Set the same table with \tabcolsep = 0pt and it becomes 268.95pt — a difference of exactly 144pt, which is 2 × 12 columns × 6pt. In other words 35% of the table’s width was padding, not text.

Knowing that changes the order in which you try the fixes. The usual advice — drop the type down a size — gives 392.77pt at \small and 372.55pt at \footnotesize for the same table; neither reaches 345pt. The reason is that \tabcolsep is a length, not something that scales with the font, so the 144pt of padding survives the smaller type intact. Halve it with \setlength{\tabcolsep}{3pt} and the table comes to 340.95pt — it fits, at full body size. \small combined with \tabcolsep = 4pt gives 344.77pt. Work through the options in that order: padding first, then type size, and scaling last.

latex
\usepackage{graphicx}   % for \resizebox

% 1. trim the padding first -- \tabcolsep is 6pt on EACH side of EVERY column
\begingroup
\setlength{\tabcolsep}{3pt}
\begin{tabular}{@{}lrrrrrrrrrrr@{}}  % @{} also removes the outer 2 x 6pt
  ...
\end{tabular}
\endgroup

% 2. only then consider a smaller size, or scaling as a last resort
\resizebox{\textwidth}{!}{%
  \begin{tabular}{lrrrrr}
    ...
  \end{tabular}%
}

Putting @{} at both ends of the column specification also drops the outer \tabcolsep, aligning the table with the left edge of the text — measured, exactly 2 × 6pt = 12pt. It is the familiar idiom in booktabs tables. When none of that is enough, the last resort is graphicx’s \resizebox{width}{height}{material}, where setting one of the two to ! scales proportionally. But it scales its contents: run the earlier table through \resizebox{\textwidth}{!} and the factor is 345 ÷ 412.95 = 0.836, so 10pt type comes out at about 8.4pt and the 0.8pt \toprule at 0.67pt. Neither the letters nor the rules match the surrounding text any more, so treat it as a stopgap. In place of \resizebox, adjustbox offers an environment form, \begin{adjustbox}{width=\textwidth}…\end{adjustbox}. To open the rows up a little, \renewcommand{\arraystretch}{1.2} (the default is 1) makes a three-row table in a 10pt document taller by 0.2 × 3 × 12pt = 7.2pt.

If none of that fits, it is a signal to change tools. The X column of tabularx, which stretches columns to a target width, and tabularray’s tblr are covered on the “Advanced table environments” page. If the problem is too many rows for a page, that is length rather than width, and the answer is longtable, which can break across pages — the “Page-spanning tables” page. Both are worth considering before the scaling and rotation on this page.

Turning a table sideways — sidewaystable and rotatebox

A table too big for a portrait page can use a full page by turning 90°: put it in the sidewaystable environment from the rotating package instead of table. The caption and number rotate with it, and it still appears in the list of tables. In two-sided documents the package chooses the direction of rotation automatically so the spread reads naturally. For figures there is the matching sidewaysfigure. To rotate only part of a table, at an arbitrary angle, use \rotatebox{angle}{material}, also from graphicx/rotating; standing a single header cell on end with \rotatebox{90}{long column name} is the typical use (positive angles turn counter-clockwise).

document.tex
\usepackage{rotating}
\usepackage{booktabs}

\begin{sidewaystable}
  \centering
  \caption{A wide table turned 90 degrees}
  \label{tab:wide}
  \begin{tabular}{@{}lrrrrrrrr@{}}
    \toprule
    Region & Q1 & Q2 & Q3 & Q4 & Total & Prev & Diff & Ratio \\
    \midrule
    East & 120 & 135 & 128 & 142 & 525 & 500 & +25 & 105\% \\
    \bottomrule
  \end{tabular}
\end{sidewaystable}

There is one boundary to watch. rotating deals in rotated boxes, and a box always stays on one page, so it cannot produce landscape running text across several pages. When you need that, use lscape, which sets the body text sideways, or pdflscape, which rotates the PDF page itself. pdflscape is especially suited to documents read on screen, since the viewer turns the page for you. A table that is both landscape and multi-page means combining pdflscape with longtable.

Notes under a table — threeparttable

Use \footnote inside a tabular and the note either jumps to the foot of the page or fails to print at all. Donald Arseneau’s threeparttable solves this. As the name says, it treats a table as three parts — title (caption), body (tabular) and notes (tablenotes) — and sets the notes to the width of the table, directly beneath it. As the package’s own documentation states, a threeparttable does not float by itself, so to get a number and placement you wrap the whole thing in a table (or table* for full width in a two-column layout).

document.tex
\usepackage{booktabs}
\usepackage{threeparttable}

\begin{table}[htbp]
  \centering
  \begin{threeparttable}
    \caption{Yield by variety}
    \label{tab:yield}
    \begin{tabular}{@{}lrr@{}}
      \toprule
      Variety & Yield\tnote{a} & Price\tnote{b} \\
      \midrule
      Koshihikari & 540 & 380 \\
      Akitakomachi & 520 & 360 \\
      \bottomrule
    \end{tabular}
    \begin{tablenotes}
      \footnotesize
      \item[a] Kilograms per 10 a.
      \item[b] Wholesale price per kilogram.
    \end{tablenotes}
  \end{threeparttable}
\end{table}

Inside a threeparttable environment you simply place, in order, \caption, the tabular, then tablenotes. Linking the notes is manual: put a marker such as \tnote{a} in a cell and write the note with the same letter as \item[a] … inside tablenotes. The author left his reason for not automating it at the top of the .sty file: “At present, there is nothing automatic about the notes… I chose this method because automatic numbering with \footnote would be very hard to use, particularly because many tables make repeated reference to a single note. If someone has a convenient, elegant, automatic system, I’ll listen!” The package still ships with that design intact.

OptionEffect
paraRuns several notes together in a single paragraph, without line breaks
flushleftRemoves the hanging indentation from the notes
onlinePrints the \item tag at normal size instead of as a superscript
normalRestores the default formatting, overriding a document-wide option for one table

These can be set document-wide, as in \usepackage[para]{threeparttable}, or per table, as in \begin{tablenotes}[flushleft]. threeparttable does not style the caption itself, so pair it with the caption package when you want a proper heading look. To put notes on a page-spanning table (longtable), use the sister package threeparttablex.

  • The table will not go where you want — first review the [htbp] letters as a set of permissions, not an order. If it still will not move it is hitting \topfraction and friends, so try [!ht]; to pin it for real, [H] from float.
  • The caption is glued to the table\belowcaptionskip defaults to 0pt. Use \setlength{\belowcaptionskip}{6pt} or the caption package’s skip=.
  • The table is wider than the page\tabcolsep and @{} first, then \small, and \resizebox last. If the columns may wrap, use p{width} or tabularx.
  • Too many rows — that is length, not width, so use longtable; combine it with pdflscape if it must also be landscape.
  • You want a footnote on a cell — not \footnote but \tnote and tablenotes from threeparttable.