Votre tableau dépasse du bloc de texte — l’Overfull \hbox que tout le monde rencontre tôt ou tard. Le voici, mesuré. Un tableau booktabs de douze colonnes dans article fait 404,83pt contre une \textwidth de 345pt, et le journal affiche Overfull \hbox (74.83432pt too wide). La plupart des gens essaient alors \small, et découvrent que cela ne suffit pas : même \scriptsize (7pt) laisse le tableau à 351,90pt, encore trop large. La raison : réduire la police ne réduit pas l’espace entre les colonnes. Cette page rassemble toutes les façons de faire tenir ce tableau sur le papier : déclarer la largeur avec tabularx et tabulary, le reconstruire avec tabularray (environnement tblr), le mettre à l’échelle avec \resizebox et adjustbox, tourner la page avec pdflscape et rotating, et le laisser déborder dans les marges avec \makebox.
Pourquoi réduire la police n’arrête pas le débordement
Parce que \tabcolsep, l’espace entre colonnes, est une longueur absolue qu’un changement de corps ne touche pas. Un tableau de douze colonnes reçoit \tabcolsep (6pt de chaque côté) à vingt-quatre endroits, bords extérieurs compris. Recomposez le même tableau avec \tabcolsep=0pt et 404,83pt deviennent 260,83pt : un écart d’exactement 144pt, soit 35% du tableau en blanc de garde. Ces 144pt ne diminuent pas d’un seul point quand la police rétrécit — mesuré en \scriptsize, le blanc totalisait encore 144pt. D’où le plancher de 351,90pt.
| Remède | Largeur mesurée (textwidth = 345pt) | Résultat |
|---|---|---|
(none) | 404,83pt | Overfull \hbox (74.83432pt too wide) |
\small | 385,27pt | toujours trop large |
\footnotesize | 365,70pt | toujours trop large |
\scriptsize | 351,90pt | encore trop large, même en corps 7 |
\tabcolsep=3pt | 332,83pt | tient, et le corps reste à 10pt |
\resizebox | 345,01pt | tient, mais le corps tombe à 8,52pt effectifs |
Ce tableau donne l’ordre de travail : rogner d’abord les blancs, repenser ensuite la conception des colonnes, et seulement après mettre à l’échelle ou faire pivoter. \tabcolsep à 3pt suffit à ramener le tableau à 332,83pt tout en gardant le corps 10 lisible du texte : c’est donc par là qu’on commence (\tabcolsep et @{} sont traités en détail dans « Spécification des colonnes, alignement et largeur »). Mais il n’y a qu’une quantité limitée de blanc à récupérer. Si le coupable n’est pas les chiffres mais une colonne remplie de texte long, rogner ne sert à rien : c’est la colonne elle-même qui doit se replier. C’est l’objet de la section suivante.
tabularx : fixer la largeur d’abord, la colonne X s’étire
tabularx prend la largeur cible du tableau comme premier argument et laisse les colonnes X absorber le reste : \begin{tabularx}{width}{column spec}. Un X est une colonne p qui prend automatiquement la largeur restante ; plusieurs X se la partagent également. Si le débordement vient d’un long texte descriptif, c’est la sortie la plus courte : déclarez la largeur \textwidth et, par construction, le tableau ne peut plus déborder. Il est dû à David Carlisle, l’auteur de longtable, et fait partie du bundle tools : rien à installer.
Le mécanisme est un peu inhabituel : tabularx trouve les largeurs en composant le tableau plusieurs fois. Il donne d’abord à chaque X toute la largeur cible — le tableau est alors trop large —, divise l’excès par le nombre de colonnes X, réduit chacune d’autant, puis recompose, jusqu’à convergence. Au final, X devient ce que définit \tabularxcolumn, dont la valeur par défaut est \newcommand{\tabularxcolumn}[1]{p{#1}} : une colonne de paragraphe alignée en haut. Redéfinissez-la avec m{#1} pour centrer verticalement. Une cellule X est justifiée par défaut ; pour l’aligner à gauche, préfixez la colonne par >{\raggedright\arraybackslash}X. Le point crucial est \arraybackslash, qui annule la redéfinition de \\ par \raggedright et ses parents. Si le même préfixe revient souvent, \newcolumntype lui donne un alias d’une lettre et la spécification redevient lisible.
\usepackage{tabularx}
\newcolumntype{Y}{>{\raggedright\arraybackslash}X}
% ...
\begin{tabularx}{\textwidth}{l Y Y}
\hline
Package & Strength & Weakness \\
\hline
tabular & simple and fast & you compute the widths yourself \\
tabularx & the table hits a fixed width & slower: the body is set several times \\
\hline
\end{tabularx}Deux réserves. D’abord, comme le corps est développé plusieurs fois, les commandes à effets de bord — incrémenter des compteurs, écrire des fichiers, \footnote, \verb — peuvent mal se comporter dans tabularx. Le remède habituel est d’enfermer la cellule dans une boîte ou une minipage. Ensuite, tabularx seul ne connaît aucune pondération : X X partage toujours à égalité, et pour un rapport 2:1 il faut soit le X[2] de tabularray ci-dessous, soit un p{} calculé à la main via \newcolumntype.
tabulary : répartir la largeur selon le contenu de chaque colonne
Là où tabularx partage ses colonnes X à égalité, tabulary distribue la largeur proportionnellement à la largeur naturelle du contenu de chaque colonne. Quand une colonne porte un libellé court et l’autre une longue description, un partage égal paraît maladroit. La syntaxe est la même : \begin{tabulary}{width}{column spec}, avec quatre types de colonnes — L à gauche, C centrée, R à droite, J justifiée. On peut mélanger des l, c, r et p{width} ordinaires, mais ils sont exclus de la mesure et gardent leur largeur naturelle. Chaque colonne mesurée est pondérée par la largeur naturelle de sa cellule la plus large, puis redimensionnée pour que le total atteigne la largeur demandée ; une colonne déjà plus étroite que sa part reste telle quelle. Pour éviter les répartitions extrêmes, une colonne mesurée est encadrée par \tymin (par défaut 10pt) et \tymax (par défaut 2\textwidth) : la soupape contre une entrée démesurément longue qui monopoliserait la colonne.
\usepackage{tabulary}
% ...
\begin{tabulary}{\textwidth}{L L}
\hline
Term & Description \\
\hline
X column & Shares the width left over after the fixed columns, equally with the other X columns. \\
\hline
\end{tabulary}Les deux colonnes sont ici L, et pourtant « Term », au contenu court, sort étroite tandis que « Description », remplie de texte, reçoit la part la plus large. Avec tabularx et X X, elles seraient identiques ; pour un tableau libellé + texte, tabulary paraît donc plus naturel. Mais tabulary traite lui aussi le corps plus d’une fois : les mêmes précautions sur les notes et les compteurs s’appliquent.
tabularray : l’environnement tblr réunit largeur et filets dans une seule syntaxe
tabularray ramène à une seule interface clé-valeur ce qui exigeait auparavant la coopération d’array, booktabs, multirow, colortbl et diagbox. Écrit par Jianrui Lyu (lvjr), il abandonne l’ancienne mécanique \halign et analyse et compose les tableaux directement avec LaTeX3 (expl3). La version livrée avec TeX Live 2024 est datée du 2024-02-16, version interne 2024A. L’environnement principal est tblr ; chargez-le par \usepackage{tabularray}.
La structure de tblr diffère un peu de celle de tabular : avant le corps vient un argument d’options clé-valeur séparées par des virgules, la spécification interne, comme dans \begin{tblr}{ … inner spec … }. L’alignement des colonnes se déclare avec la clé colspec. La forme à une lettre habituelle colspec={lcr} fonctionne toujours, mais la puissance vient de Q[…] (colonne générique recevant alignement, largeur et autres options entre crochets) et de X[…] (colonne extensible, comme dans tabularx). X[c] est une colonne extensible centrée ; X[2,l] une colonne extensible alignée à gauche avec coefficient 2, deux fois plus large qu’un X simple. Dans le contexte du débordement, l’essentiel est que width= et colspec= figurent entre les mêmes accolades et que ces coefficients permettent de fixer le rapport. Mesuré, un tblr avec width=\textwidth et colspec={X[2,l] X[1,r] X[1,r]} a produit une boîte d’exactement 345,0pt, pile la largeur visée.
La largeur dans laquelle les colonnes X s’étendent est donnée par la clé width (\linewidth si elle n’est pas fixée). Les espaces entre lignes et colonnes sont contrôlés par rowsep et colsep, dont les valeurs par défaut dans tblr sont rowsep=2pt et colsep=6pt. Les filets sont déclaratifs : hlines / vlines tracent tous les filets horizontaux / verticaux, et hline{n} / vline{n} stylent une ligne précise, par exemple hline{2}={1pt,solid} (Z est l’indice spécial de la dernière ligne). On n’écrit jamais \hline dans le corps. Les réglages récurrents se factorisent avec \SetTblrInner{rowsep=2pt}.
Les fusions de cellules se font dans le corps avec \SetCell. \SetCell[c=2]{c} est une cellule centrée qui couvre 2 colonnes (équivalent de \multicolumn), et \SetCell[r=2]{c} couvre 2 lignes (équivalent de \multirow) ; c= et r= donnent l’étendue en colonnes et en lignes, l’argument entre accolades l’alignement. Pour styliser des lignes ou colonnes entières, utilisez \SetRow et \SetColumn ; \SetRow{cyan8} colore une ligne en cyan pâle, les noms de couleurs étant intégrés au package. On peut déclarer les mêmes choses depuis la spécification interne, sous la forme row{1}={font=\bfseries}, column{2}={halign=r}, cell{2}{3}={c=2}, ce qui garde le corps propre.
\usepackage{tabularray}
% ...
\begin{tblr}{
width = \textwidth,
colspec = {Q[l] X[c] X[2,l]},
rowsep = 3pt,
hline{1,Z} = {1pt,solid},
hline{2} = {0.5pt,solid},
row{1} = {font=\bfseries},
}
Item & Kind & Description \\
\SetCell[r=2]{l} Table environment & fixed width & The table width is fixed; X columns share the rest. \\
& content width & Width is apportioned by how much each column holds. \\
Note & --- & Rules, colour and spans are all set through keys. \\
\end{tblr}Ce tblr fixe la largeur du tableau à celle du texte avec width=\textwidth. Les trois colonnes sont Q[l] (colonne de base alignée à gauche), X[c] (colonne extensible centrée) et X[2,l] (colonne extensible alignée à gauche, coefficient 2) ; les deux colonnes X se partagent donc la largeur restante 1 : 2, et la colonne 3, « Description », devient la plus large. Aucun \hline n’apparaît dans le corps : les filets viennent seulement des clés hline{…} de la spécification interne. La première ligne est en gras via row{1}={font=\bfseries}, et la cellule « Table environment » de la première colonne couvre deux lignes avec \SetCell[r=2]{l}. Arriver là sans charger booktabs, multirow et array est précisément l’intérêt de tabularray.
Quand le tableau est long autant que large, deux environnements dérivés prennent le relais. longtblr est un tblr qui s’étend sur plusieurs pages, avec lignes d’en-tête répétées, légendes et notes ; talltblr est un tableau d’une seule page portant des notes en dessous, dans l’esprit de threeparttable. Dans les deux, la légende, le label, note{…} et éléments similaires vont dans l’argument optionnel […] avant le corps, la spécification externe. Répéter un en-tête dans longtblr se réduit à rowhead=1 — un simple compte de lignes —, plus concis que les quatre marqueurs de longtable.
resizebox ment sur la taille de vos caractères
\resizebox{\textwidth}{!}{...} de graphicx met son contenu à l’échelle en bloc jusqu’à la largeur indiquée. C’est le moyen le plus rapide de faire tenir un tableau sur le papier, et cela réduit la police d’un facteur qui n’apparaît nulle part dans la source. Mesuré : en confiant le tableau de 404,83pt à \resizebox{\textwidth}{!}, on obtient une boîte de 345,01pt de large, la hauteur passant de 26,07pt à 22,22pt. Les deux rapports valent 0,8522. Le corps que vous croyez à 10pt est donc à 8,52pt sur la page. Le document affiche \documentclass[10pt] et le papier 8,52pt : accident garanti partout où un relecteur ou un règlement de soumission contrôle la taille des caractères.
Pourquoi \resizebox tient-il là où \scriptsize (corps 7) échoue ? Pour la même raison qu’en tête de page : \resizebox réduit aussi le blanc entre les colonnes. Un changement de corps ne retire pas un seul point à ces 144pt, alors qu’une mise à l’échelle de 0,8522 les ramène à 122,7pt. Voilà comment un corps apparent de 8,52pt sous \resizebox bat un vrai 7pt sous \scriptsize. Autrement dit, \resizebox fabrique un tableau dont le blanc de garde a lui aussi été comprimé : double handicap pour la lisibilité.
Et \resizebox cache un piège bien plus visible : donnez-lui un petit tableau et il l’agrandit. Mesuré, un tableau minuscule de 4,44pt de large confié à \resizebox{\textwidth}{!} est ressorti à 345,46pt — un monstre étiré environ soixante-dix-huit fois. Appliquez-le par réflexe à tous vos tableaux, comme on le fait avec \includegraphics, et les étroits enflent. C’est ici que adjustbox et son max width=\textwidth gagnent leur place : le même tableau de 4,44pt est resté à 4,44pt, seul celui de 404,83pt descendant à 345,01pt. Réduire quand il le faut, jamais agrandir : voilà le réglage par défaut le plus sûr.
\usepackage{graphicx} % \resizebox
\usepackage{adjustbox} % \adjustbox and the adjustbox environment
% ...
% scales in BOTH directions -- a narrow table gets blown up
\resizebox{\textwidth}{!}{\begin{tabular}{...}...\end{tabular}}
% only ever shrinks; a narrow table is left alone
\begin{adjustbox}{max width=\textwidth}
\begin{tabular}{...}...\end{tabular}
\end{adjustbox}Mettre la page en paysage : lscape, pdflscape et rotating
Seul pdflscape fait réellement basculer la page dans un lecteur PDF. Les trois font pivoter le contenu de quatre-vingt-dix degrés, via \begin{landscape} ou sidewaystable, mais seul pdflscape inscrit dans le PDF l’instruction « afficher cette page pivotée », c’est-à-dire l’entrée /Rotate 90. Voici le même document composé de trois façons, vérifié avec pdfinfo.
| Package | Environnement | Ce que pdfinfo indique pour rot et la taille de page |
|---|---|---|
lscape | landscape | rot: 0 sur chaque page, toujours 612 x 792. Contenu seul |
pdflscape | landscape | rot: 90 sur cette page seule, 612 x 792. Le lecteur la tourne |
rotating | sidewaystable | rot: 0, 612 x 792. Pivote comme flottant numéroté |
Notez que dans les trois cas la taille de page reste 612 x 792 : rien n’a été mis physiquement en paysage, seul le contenu pivote. Le choix en découle. Pour un PDF lu à l’écran, prenez pdflscape et épargnez le torticolis à votre lecteur ; pdflscape charge lscape et y ajoute le /Rotate, la syntaxe de lscape reste donc valable. Pour un document imprimé et relié, lscape suffit : on tourne la feuille. Si le tableau doit rester un flottant numéroté avec légende, utilisez sidewaystable de rotating (ou sidewaysfigure pour une figure). rotating propose aussi les options figuresright et figuresleft pour choisir le sens de rotation.
\usepackage{pdflscape} % loads lscape and adds /Rotate 90 to the page
\usepackage{rotating} % sidewaystable / sidewaysfigure
% ...
% a whole page turned sideways in the viewer
\begin{landscape}
\begin{tabular}{...}...\end{tabular}
\end{landscape}
% a rotated float that still says "Table N"
\begin{sidewaystable}
\centering
\begin{tabular}{...}...\end{tabular}
\caption{A very wide table}
\end{sidewaystable}Laisser le tableau déborder dans les marges avec makebox
Le bloc de texte fait 345pt de large, mais le papier offre davantage. Avec les valeurs par défaut d’article, la marge de gauche mesure 134,27pt et celle de droite 135,03pt : 269pt de blanc inoccupé à côté du texte. L’idiome pour y puiser est \noindent\makebox[\textwidth]{...}. \makebox place son contenu dans une boîte de largeur \textwidth ; si le contenu est plus large, il déborde également des deux côtés. Pour le tableau de 404,83pt, cela fait 29,92pt dans chaque marge : le tableau s’élargit, le centre optique de la page ne bouge pas.
Une chose à accepter : le contenu dépassant la boîte, TeX continue de signaler Overfull \hbox. C’est le seul cas où l’on peut ignorer cet avertissement — le débordement est voulu. Pour ne déborder que d’un côté, \makebox[\textwidth][l]{...} fixe le bord gauche et laisse le tableau filer vers la droite. Pour quelque chose de plus maîtrisé, l’environnement adjustwidth du package changepage élargit le bloc de texte sur une portion du document ; c’est plus propre et cela garde notes et titres courants cohérents. Les valeurs réelles des marges dépendent du papier et des réglages geometry : vérifiez toujours le PDF réel dès que vous concevez quelque chose qui empiète sur la marge (la façon de fixer les marges relève de « Marges et zone de page »).
Scinder le tableau : le couper en deux ou le transposer
Certaines réponses ne demandent aucun package. Coupez les colonnes en deux tableaux et répétez la colonne clé dans chacun : pour un tableau à douze colonnes, placez les noms de régions en première colonne de chaque moitié et répartissez les années en 2–6 et 7–12. L’œil n’a jamais à franchir une coupure, et le corps reste celui du texte. Rien n’est mis à l’échelle ni pivoté : c’est souvent le résultat le plus lisible. L’autre geste est de transposer. Un tableau de douze années sur cinq régions s’étale en largeur ; cinq régions sur douze années s’étire en hauteur — et un tableau haut relève de longtable.
Lequel choisir
La cause décide. Si c’est une colonne de texte qui déborde, prenez tabularx — le X[2] de tabularray si les colonnes doivent être pondérées, tabulary si le partage doit suivre le contenu ; déclarer la largeur d’emblée est la solution la plus propre. Si c’est une forêt de colonnes numériques, commencez par \tabcolsep, puis demandez-vous si toutes ces colonnes sont vraiment nécessaires ensemble. Si toutes les colonnes doivent absolument tenir sur une feuille, utilisez max width d’adjustbox plutôt que \resizebox. Si c’est trop large même pour cela, tournez la page avec pdflscape. Pour un tableau écrit de zéro, allez vers tabularray : largeur, filets, couleur et fusions dans une seule syntaxe. Si le tableau est long autant que large, passez à longtblr ou longtable. Quel que soit le chemin, regardez le PDF final et demandez-vous si un chiffre en 8,5pt reste lisible.
| Package | Détermination de la largeur | Idéal pour |
|---|---|---|
tabularx | Total fixe ; colonnes X partagées également | Colonnes de texte de même largeur ajustées |
tabulary | Total fixe ; réparti selon le contenu | Tableaux libellé plus texte déséquilibrés |
tabularray | clé width plus colonnes X, avec coefficients | Tableaux modernes unifiant filets, couleurs et fusions |
adjustbox | réduit seulement en cas de débordement (max width) | Poser un plafond sûr sur un tableau existant |
pdflscape | ne touche pas à la largeur et fait pivoter la page de 90 degrés | Tableaux qui ne tiendront jamais à la verticale |
Le détail des spécifications de colonnes elles-mêmes (\multicolumn, le >{…} du package array, etc.) relève de « Spécification des colonnes, alignement et largeur », les bases de la fusion de cellules de « Fusion de cellules », et les très longs tableaux multipages de la page « longtable ».