Ce qui fait reconnaître un tableau LaTeX au premier coup d’œil, ce sont ses filets. Les traits tracés avec \hline et | paraissent collés aux lettres — et cela se mesure au lieu de se ressentir : \hline n’ajoute à la rangée que ses propres 0,4pt d’épaisseur, avec zéro espace au-dessus et au-dessous. Le \midrule de booktabs apporte quant à lui un filet de 0,5pt plus 4,52pt de blanc. Ce sont précisément ces quelques points d’air qui séparent un tableau de revue d’un tableau LaTeX par défaut. Cette page parcourt les filets standard \hline, \cline et \vline, puis booktabs avec \toprule / \midrule / \bottomrule, puis hhline pour les croisements que ni l’un ni l’autre n’atteint — chiffres mesurés à l’appui.
Pourquoi \hline, \cline et | paraissent à l’étroit
La réponse : ils n’ajoutent aucun espace. Mesurez un tabular de deux rangées, il fait 24,0pt de haut ; insérez un \hline entre les rangées, il passe à 24,4pt. L’accroissement vaut exactement \arrayrulewidth (0,4pt par défaut) — l’épaisseur du filet lui-même, rien de plus. Aucun blanc n’est inséré, d’où l’impression que le filet touche les lettres. \cline va plus loin encore : ajouter \cline{2-3} laisse la hauteur à 24,0pt, soit un accroissement rigoureusement nul. Le filet n’écarte pas les rangées, il est tracé dans l’interligne déjà présent.
Les commandes elles-mêmes sont simples. \hline, placé après le \\ d’une rangée (ou tout en haut ou tout en bas du tableau), trace un filet sur toute la largeur ; deux à la suite, \hline\hline, donnent un double filet séparé par \doublerulesep (2pt par défaut). Pour ne régler qu’une partie d’une rangée, \cline{i-j} : \cline{2-3} trace sous les colonnes 2 et 3, et les intervalles disjoints se juxtaposent, \cline{1-1}\cline{3-4}. Les filets verticaux relèvent de la spécification des colonnes, pas du corps : {|l|c|r|} place un filet pleine hauteur à chaque |, et || un filet double. Il existe aussi \vline pour un filet vertical à l’intérieur d’une seule cellule. L’épaisseur de |, \hline et \vline est entièrement régie par \arrayrulewidth : \setlength{\arrayrulewidth}{0.8pt} les épaissit toutes d’un coup.
% every standard ruling feature at once -- and a specimen of what to avoid
\begin{tabular}{|l|c|r|}
\hline
Item & Qty & Price \\
\hline\hline
Apple & 3 & 380 \\
\cline{2-3}
Orange & 12 & 120 \\
\hline
\end{tabular}Cet exemple encadre chaque colonne avec |, pose un double filet sous l’en-tête avec \hline\hline et coupe le milieu avec \cline{2-3}. Il épuise tout le répertoire standard — et constitue précisément un spécimen de la surcharge de filets à éviter. Dans la tradition typographique, un filet n’est pas une cage autour des données mais un moyen discret d’en marquer la division logique. Les filets verticaux dressent des murs entre les colonnes et arrêtent l’œil ; les doubles filets alourdissent la page sans rien apporter. Si vous restez au simple \hline, au moins n’encadrez pas le tableau : un filet sous l’en-tête, un en haut, un en bas, et rien d’autre. Le package booktabs de la section suivante est cette discipline mise en code.
Utiliser booktabs — \toprule, \midrule, \bottomrule
Il suffit d’écrire \usepackage{booktabs} dans le préambule et de remplacer \hline par trois filets : \toprule tout en haut du tableau, \midrule entre l’en-tête et le corps, \bottomrule tout en bas. Cela suffit à obtenir un tableau de revue, sans filet vertical ni double filet. Deux mécanismes opèrent : le package échelonne les filets en trois épaisseurs et ménage de l’espace au-dessus et au-dessous de chacun. Les chiffres rendent la différence évidente : le même tableau de trois rangées mesure 37,20pt de haut avec \hline et 47,14pt avec booktabs. Contenu identique, environ 10pt de blanc en plus.
Les valeurs par défaut figurent dans booktabs.sty : \heavyrulewidth=.08em (pour \toprule et \bottomrule), \lightrulewidth=.05em (\midrule), \cmidrulewidth=.03em (\cmidrule). Mesurées dans un document en 10pt, elles valent 0,80002pt, 0,50003pt et 0,29999pt — un jeu qui encadre les 0,4pt de \hline par le haut et par le bas. L’élégance tient à l’unité : exprimées en em, elles donnent un filet lourd de 0,876pt dans un document en 11pt et de 0,94pt en 12pt, si bien que les filets s’épaississent proportionnellement au corps du texte. \arrayrulewidth, lui, reste à 0,4pt quelle que soit la classe : rien que pour cela, \hline n’est pas à l’échelle de son propre texte. Côté espace, \aboverulesep=.4ex (1,72218pt en 10pt) et \belowrulesep=.65ex (2,79857pt). Un seul \midrule ajoute donc 0,5+1,72+2,80 = 5,02pt à la rangée, plus de douze fois les 0,4pt de \hline.
\usepackage{booktabs}
% \toprule goes right after \begin{tabular}{...}; the rest follow a row's \\
\begin{tabular}{@{}llr@{}}
\toprule
\multicolumn{2}{c}{Fruit} \\
\cmidrule(lr){1-2}
Kind & Grade & Price \\
\midrule
Apple & premium & 380 \\
Orange & second & 120 \\
\addlinespace
Total & & 500 \\
\bottomrule
\end{tabular}Le petit espace devant la ligne des totaux vient de \addlinespace. Placé après le \\ d’une rangée, il insère \defaultaddspace (.5em, soit 5pt dans un document en 10pt), et l’on peut préciser la quantité avec \addlinespace[1ex]. Cela exprime l’intention plus clairement que d’étirer une rangée avec \\[2pt], et près d’un filet le contrôle de l’écart est exact. Ce n’est que pour fixer soi-même épaisseur et espaces qu’on recourt à \specialrule{width}{above}{below} (les trois arguments sont obligatoires) — une commande pour cas exceptionnels ; les trois filets usuels suffisent d’ordinaire. Les filets doivent se trouver à une frontière de rangée : écrire \toprule au milieu d’une cellule arrête la compilation sur ! Misplaced \noalign., car comme \hline ces commandes opèrent à l’intérieur de \noalign.
| Commande / longueur | Rôle | Valeur par défaut (mesurée en 10pt) |
|---|---|---|
\toprule | Filet tout en haut du tableau | \heavyrulewidth = .08em = 0,80002pt |
\midrule | Filet séparant l’en-tête du corps | \lightrulewidth = .05em = 0,50003pt |
\bottomrule | Filet tout en bas du tableau | \heavyrulewidth = .08em = 0,80002pt |
\cmidrule(lr){a-b} | Filet partiel couvrant seulement les colonnes a–b | \cmidrulewidth = .03em = 0,29999pt ; rognage \cmidrulekern = .5em = 5pt |
\aboverulesep | Espace inséré au-dessus de chaque filet | .4ex = 1,72218pt |
\belowrulesep | Espace inséré au-dessous de chaque filet | .65ex = 2,79857pt |
\addlinespace | Espace supplémentaire entre deux rangées | \defaultaddspace = .5em = 5pt |
\specialrule | Filet dont l’épaisseur et les deux écarts sont donnés | Les trois arguments sont obligatoires (aucun défaut) |
Au passage, si \heavyrulewidth appelle « width » ce qui est une épaisseur, ce n’est pas un anglicisme maladroit. booktabs.dtx comporte une note de terminologie : dans la composition britannique, une ligne s’appelle toujours un « rule », et l’épaisseur d’un rule « est souvent désignée comme sa width » — là où, ajoute l’auteur pince-sans-rire, à peu près tout le monde parlerait de depth ou de height pour un filet horizontal. Il a transporté ce jargon de métier tel quel dans les noms de commandes. Autre chose : la version de booktabs livrée avec TeX Live 2024 est 1.61803398 — φ, le nombre d’or. Une note en bas de la page de titre du .dtx indique, de la main de l’auteur, que le numéro de version « converge vers phi, le nombre d’or », un chiffre de plus à chaque publication. Le résumé énumère 1.618, 1.6180, 1.61803 et 1.618033, et une note précise que ces corrections de bogues ont été publiées par Danie Els en l’absence de l’auteur.
La différence entre \cline et \cmidrule
La différence visible tient à l’espace et au traitement des extrémités. Mesuré sur le même tableau de deux rangées, \cline{2-3} ajoute 0,0pt de hauteur, tandis que \cmidrule{2-3} en ajoute 4,82pt (0,29999pt de filet, plus \aboverulesep 1,72218pt, plus \belowrulesep 2,79857pt). Voilà pourquoi un \cline semble mordre dans les lettres. L’autre différence porte sur les extrémités. Par défaut, un \cmidrule occupe toute la largeur de ses colonnes et vient buter contre un filet partiel voisin ; on lui donne donc un rognage entre parenthèses : (l), (r) et (lr) rentrent l’extrémité gauche, droite ou les deux de \cmidrulekern (.5em = 5pt), et la quantité peut être précisée, comme dans (r{.75em}). La syntaxe complète est \cmidrule, suivi de l’épaisseur entre crochets, du rognage entre parenthèses, puis de {a-b}. En pratique, un \multicolumn qui regroupe des têtes de colonnes appelle presque toujours un \cmidrule(lr){…} en dessous.
En revanche, il ne faut pas les mélanger. L’auteur l’écrit sans détour : ces filets « ne sont pas garantis compatibles avec \hline ou \cline… je ne vois aucune raison de vouloir les mélanger ». De fait, les filets sont conçus pour ne pas se raccorder au | d’une spécification de colonnes, et la documentation présente cela comme une fonctionnalité. Ce n’est que si un filet partiel doublé à une même hauteur s’impose vraiment qu’on glisse \morecmidrules entre deux \cmidrule (\cmidrule{1-2}\morecmidrules\cmidrule{1-2} ; l’écart est \cmidrulesep, par défaut les mêmes 2pt que \doublerulesep). Les doubles filets étant déconseillés d’emblée, ce n’est pas non plus un outil quotidien.
Pourquoi ne jamais utiliser de filets verticaux
Le manuel de booktabs le dit à l’impératif et sans nuance. On ne se trompera guère, écrit-il, en gardant à l’esprit deux consignes simples : « 1. N’utilisez jamais, au grand jamais, de filets verticaux. 2. N’utilisez jamais de doubles filets. » Et de poursuivre : « Ces consignes peuvent sembler extrêmes, mais je n’ai jamais trouvé de bon argument pour les enfreindre. » Si la moitié gauche d’un tableau diffère de la droite au point d’appeler un trait de séparation, la réponse de l’auteur est qu’il faut alors faire deux tableaux. Ailleurs, il est encore plus bref : on ne met pas de filets verticaux dans un tableau, point final.
Le même document énumère trois autres consignes que l’auteur présente comme « généralement méconnues hors du cercle des typographes et secrétaires de rédaction professionnels » — et elles sont très pratiques. Mettez les unités dans la tête de colonne, pas dans le corps du tableau. Faites toujours précéder le séparateur décimal d’un chiffre : 0.1, jamais .1. N’utilisez pas de guillemets d’itération ni aucune convention du même ordre : un blanc suffit le plus souvent, et sinon on répète la valeur. L’auteur reconnaît les limites de ses propres règles : à propos de la deuxième consigne, il note avoir « travaillé pour un éditeur qui exigeait un double filet léger au-dessus d’une ligne de totaux. Mais cela n’aurait pas été mon choix. » Les consignes ne sont pas des absolus : on les enfreint pour une raison.
hhline — décider comment les filets se croisent
hhline trace les mêmes filets horizontaux que \hline, mais permet d’indiquer, caractère par caractère, si un filet vertical est coupé au croisement ou le traverse de part en part. C’est le package de David Carlisle, issu de l’ensemble tools de LaTeX, chargé par \usepackage{hhline}. Avec un simple \hline\hline, on ne peut pas choisir si le filet vertical s’interrompt au double filet ou le franchit. Puisque booktabs proscrit filets verticaux et doubles filets, hhline ne se justifie que là où on ne peut pas suivre ce conseil : un gabarit de revue au format imposé, un document à reproduire, un tableau comptable. En dehors de ces cas, il est inutile.
L’argument de \hhline{…} est une suite de jetons qui ressemble beaucoup à une spécification de colonnes. Côté horizontal : = est un double filet de la largeur d’une colonne, - un filet simple, ~ aucun filet dans cette colonne. Côté vertical : | est un trait vertical qui traverse le filet, : un trait interrompu par lui, et # un segment de double filet entre deux traits verticaux. Il existe aussi t (moitié supérieure d’un segment de double filet) et b (moitié inférieure) pour construire les angles : |t: donne l’angle supérieur gauche, :b| l’angle inférieur droit. La forme de répétition *{n}{…} des spécifications de colonnes est également disponible. À noter : écrire un double trait vertical (|| ou ::) interrompt les filets horizontaux à cet endroit ; pour qu’un filet passe sans rupture, utilisez # ou renoncez aux spécificateurs verticaux.
\usepackage{hhline}
% the example from the package documentation: t/b build the corners,
% ~ leaves a column unruled, # is a double-rule segment between verticals
\begin{tabular}{||cc||c|c||}
\hhline{|t:==:t:==:t|}
a & b & c & d \\
\hhline{|:==:|~|~||}
1 & 2 & 3 & 4 \\
\hhline{#==#~|=#}
i & j & k & l \\
\hhline{||--||--||}
w & x & y & z \\
\hhline{|b:==:b:==:b|}
\end{tabular}La première ligne, |t:==:t:==:t|, construit les moitiés supérieures des doubles filets ainsi que les angles, et la dernière, |b:==:b:==:b|, les moitiés inférieures : le cadre à double filet se raccorde ainsi proprement aux filets verticaux. Les rangées intermédiaires mêlent ~ (aucun filet) et # (segment de double filet entre deux verticales), en changeant rangée par rangée les endroits où l’on coupe et ceux où l’on passe. Une dernière réserve technique : un \hline est une unique \hrule de TeX, tandis qu’une ligne \hhline est assemblée à partir de nombreux petits segments. Leur position dans le DVI est exacte, mais certains lecteurs et pilotes n’alignent pas parfaitement ces segments. La documentation suggère d’essayer un autre pilote, ou d’augmenter légèrement \arrayrulewidth pour que les jointures cessent de se voir.
Lequel utiliser
La conclusion est presque unique : faites de booktabs votre choix par défaut pour les tableaux ordinaires. Les trois filets \toprule, \midrule et \bottomrule, plus un \cmidrule(lr){…} sous un groupe d’en-têtes quand il le faut, donnent les tableaux sobres et lisibles qu’on voit dans les revues. En suivant « pas de filets verticaux, pas de doubles filets », le tracé des filets cesse d’être un sujet de délibération.
booktabs— premier choix pour presque tous les tableaux : filets horizontaux uniquement, épaisseurs et espaces déjà réglés, qualité publication.\hline/\cline/|standard — commodes car sans package ; convenables pour les tableaux en grille et les brouillons rapides. Attention à la surcharge.hhline— uniquement pour le cas particulier où il faut contrôler précisément le croisement des doubles filets et des verticales. Pas un outil quotidien.- Quand l’envie d’ajouter un filet vous prend — demandez-vous d’abord si
\addlinespacene marquerait pas aussi bien le groupe de rangées. Le blanc pèse moins qu’un filet et fait le même travail.
Avant les filets, la disposition et l’alignement des colonnes fixent l’ossature du tableau. Pour les bases de & et \\, et pour déchiffrer Extra alignment tab et Misplaced \noalign, voir « Bases de tabular ». Pour le détail des spécifications de colonnes, p{width} et >{…} compris, voir « Spécification des colonnes, alignement et largeur ». Les en-têtes à plusieurs niveaux associant \multicolumn et \cmidrule sont traités dans « Fusion de cellules ». Placer le tableau dans un environnement table et le légender relève de « Placement et mise en forme des tableaux ».