页边距与版面

在 LaTeX 里把 \oddsidemargin 设成 0pt,左边距并不会变成零,而是恰好 1 英寸。看着像是设计上的毛病,其实是 TeX 从 DVI 继承下来的约定:页面的基准点位于纸张左上角向内各 1 英寸处,而所有页边距参数都是相对这一点的 增减量。知不知道这一件事,整个页边距设置看起来完全不同。本页会讲清这 1 英寸的来历、标准文档类实际排出的版心尺寸,以及如何用今天的标准答案 geometry 宏包精确达到规定的页边距——全部给出实测数值。

为什么 \oddsidemargin=0pt 得到的是 1 英寸页边距

因为基准点不是纸张的角,而是从角向内 1 英寸的那一点。这可以实测验证:在 article 中把 \oddsidemargin\topmargin 都设为 0pt,再向 pdfTeX 询问正文第一个字符的绝对位置,得到距左边缘 72.26999pt,也就是恰好 1.00000 英寸。因此实际左边距由下面这个加法决定。\hoffset 是移动基准点本身的旋钮,\oddsidemargin 则是在此之上再偏移的量。把 \hoffset 设为 20pt 重新测量,左边缘正好移到 92.27pt(即 72.27 + 20)。

latex
% How the page is actually built up (all measured, article, letterpaper)
%   left margin        = 1in + \hoffset + \oddsidemargin
%   top of header      = 1in + \voffset + \topmargin
%   top of body        = top of header + \headheight + \headsep
%   first baseline     = top of body + \topskip

% The classical way, by hand. Correct, but you own every consequence.
\setlength{\oddsidemargin}{0pt}   % real left margin = 1in + 0pt = 1in
\setlength{\topmargin}{0pt}       % header top at 1in; body starts 37pt lower
\setlength{\textwidth}{16cm}      % the RIGHT margin is now whatever is left
\setlength{\textheight}{24cm}     % likewise the bottom margin

% Measured with the two margins above: left edge 72.26999pt = 1.00000in,
% first baseline 119.27pt from the paper top = 1in + 0 + 12 + 25 + 10

这个 1in 的内部也值得一看。TeX 的 pt美式活字点,每英寸 72.27 点,与 DTP 或 PostScript 每英寸 72 点的点不是一回事。TeX 把后者称作 bp(大点),实测 1bp = 1.00374pt。也就是说 12pt12bp 相差约 0.37%。一行之内根本看不出来,但把同样的比例乘到 \textwidth 的 345pt 上就是 1.29pt,接近半毫米。在以毫米规定页边距的文件里,选错单位就可能超出规定。pdfTeX 把这 1 英寸偏移保存为 \pdfhorigin\pdfvorigin,默认都是 72.26999pt

参数含义
\paperwidth / \paperheight纸张本身的尺寸,是 LaTeX 一侧的认知,与 PDF 的物理页面尺寸不是一回事(见下文)
\textwidth / \textheight正文(版心)的宽和高;10pt 的 article 中为 345.0pt × 550.0pt
\oddsidemargin奇数页(单面时为所有页)左边距相对基准点的增量;加上 1in 才是实际边距
\evensidemargin双面(twoside)时偶数页左边距的增量;10pt 的 book 默认为 89.0pt
\topmargin从基准点到 页眉 上端的距离,不是到正文上端
\headheight容纳页眉的盒子高度;默认 12.0pt
\headsep页眉下端与正文上端之间的距离;article 中默认 25.0pt
\footskip从正文最后一行基线到页脚基线的距离;默认 30.0pt
\marginparwidth / \marginparsep边注的宽度及其与正文的间距;10pt 的 article 中为 65.0pt 与 11.0pt
\hoffset / \voffset移动基准点本身;通常保持 0pt 不动

一旦想手动设置,这张表就同时成了陷阱清单。加宽 \textwidth 并不会自动收窄右边距——右边距是“纸宽 − 左边距 − \textwidth”剩下的部分,会在你不知情时改变。而 \topmargin 只量到页眉上端,所以要把正文压到 1 英寸处,就得自己减去 \headheight\headsep。实测:给 geometrymargin=1in\topmargin 得到 −37.0pt,正好是 −(12 + 25)。如今已没有理由再自己做这道减法。

标准文档类的页边距为何这么宽:articlebook 的实测值

是为了把每行的字符数控制在易读的范围内。10pt 的 article 不论纸张多宽,都把 \textwidth 固定在 345.0pt:在 Letter 纸(宽 614.295pt)上左右各留约 134pt,而在 A4(宽 597.5pt)上正文仍是 345.0pt。纸张变宽并不会换来更长的行,因为行长本该由可读性决定。字号变大时版心会略微加宽——11pt 为 360.0pt,12pt 为 390.0pt——因为字大了,同样的行长里能容下的字反而更少。

文档类(Letter 纸)textwidthtextheightoddsidemarginevensidemargin
article345.0pt550.0pt62.0pt62.0pt
article, 11pt360.0pt541.4pt54.0pt55.0pt
article, 12pt390.0pt548.5pt39.0pt40.0pt
book345.0pt550.0pt35.0pt89.0pt

book 那一行完整地体现了双面版式的设计思路。奇数页左侧(装订侧)为 1in + 35.0pt = 107.27pt,作为外侧的右边则拿到剩下的 162.02pt。也就是说,LaTeX 的 book外侧比装订侧更宽,看起来与“为装订留出内侧”的通行说法相反。原因是外侧边距被留作边注(\marginpar)的安置处,\marginparwidth 高达 65.0pt 也正是因此。偶数页上左右互换,改用 \evensidemargin 的 89.0pt。如果文档不使用边注却照搬这套版面,外侧就会显得空落——这正是 geometry 登场的地方。

geometry 的用法:一行搞定纸张与页边距

一行 \usepackage[a4paper, margin=25mm]{geometry} 就能同时定下纸张和四边页边距。选项写在 \usepackage 的方括号里,或稍后用 \geometry{...} 命令写,二者等价;导言区中可以调用任意多次,同一键后写的会覆盖先写的。顺序无关紧要。作者是 Hideo Umeki,版权行始于 1996 年,2018 年起由 David Carlisle 维护(TeX Live 2024 收录 v5.9,2020 年 1 月)。它之所以四分之一个世纪以来一直是页边距的标准答案,是因为它的接口契合人的思考顺序:从纸边往里多少。

选项含义
a4paper / letterpaper / …按名称选择纸张;提供 A0–A6、B0–B6、b5papera5paperlegalpaperexecutivepaper
paperwidth= / paperheight= / papersize=自定义尺寸;也可写成 papersize={210mm,297mm} 一次给出
margin=一次设定四边;margin={A,B} 表示左右=A、上下=B
left= / right= / top= / bottom=分别指定各边;lmarginrmargintmarginbmargin 是别名
hmargin= / vmargin=成对给出:hmargin={左,右}vmargin={上,下}
inner= / outer=双面版式中的装订侧与切口侧;是 leftright 的别名
textwidth= / textheight= / total=从版心而非页边距一侧指定;total={宽,高} 给出整个正文块的尺寸,width=height= 属同一系列
bindingoffset=装订偏移;把该长度加到内侧(单面时为左侧)
includehead / includefoot把页眉(\headheight\headsep)或页脚(\footskip)计入正文块高度
landscape横向;交换宽度与高度
asymmetric双面时也不交换奇偶页的左右,使边注始终位于同一侧
showframe真正画出版心、页眉、页脚的框线;用于目视核对是否符合规定

精确达到规定的页边距

最短的路径就是把要求的数值原样抄进 geometry 的键里。来做一次实测核对。把“A4、装订侧 30mm、切口侧 20mm、装订偏移 5mm、双面”这样写出来后测量,\oddsidemargin\evensidemargin 分别为 27.31464pt−15.36449pt。加上 1 英寸,奇数页装订侧为 99.5846pt = 35mm(30 + 5),偶数页左侧(切口侧)为 56.9055pt,恰好 20mm。无论左右怎样互换,装订侧始终是 35mm,切口侧始终是 20mm。

document.tex
\documentclass[twoside]{book}
\usepackage{geometry}
\geometry{
  a4paper,
  inner=30mm,        % binding side
  outer=20mm,        % fore-edge
  bindingoffset=5mm, % added to the inner side
  includehead,       % count the header into the block height
}
% Measured result: \oddsidemargin 27.31464pt, \evensidemargin -15.36449pt
% -> binding side 35mm, fore-edge 20mm, on both odd and even pages
\begin{document}
Body text goes into this block.
\end{document}

还要记住怎么验证结果。在导言区加上 showframe 会真正画出版心、页眉和页脚的框线;layout 宏包的 \layout 命令会输出一页标注各参数的图示。想看原始数值,就用 \typeout 打印 \the\textwidth 之类,再去看日志。有一点要注意:同时指定页边距和版心过多时,geometry 会给出 Package geometry Warning: Over-specification in h-direction. 并悄悄忽略其中之一。左边距、右边距和 textwidth 三个都写,能对上纯属巧合——原则是 最多指定两个,剩下的交给它算

明明指定了纸张大小,PDF 却是 A4

类选项只是告诉 LaTeX 纸张有多大,并不触及 PDF 的物理页面尺寸。两者是彼此独立的变量。实测:使用 \documentclass[a5paper]{article} 时,LaTeX 一侧的 \paperwidth 变成 421.10078pt,而 pdfTeX 一侧的 \pdfpagewidth 仍停留在 597.50787pt——那是 A4 的宽度。[letterpaper][b5paper] 亦然:PDF 的纸张会一直停在 TeX 发行版的默认值(TeX Live 2024 出厂设置为 a4)。结果就是一个不上不下的 PDF:版面按 A5 计算,纸张却是 A4。

加载 geometry 会自动消除这种不一致。在把纸张交给 geometry 的四个实测案例中,\pdfpagewidth\pdfpageheight 都与 \paperwidth\paperheight 一致。把纸张大小写给 geometry,而不是写成类选项——这是一条值得记住的实务规则。

在文档中途改变页边距:\newgeometry\restoregeometry

在正文中调用 \newgeometry{...},从该处起换用新的版心。它会先把之前的设置(纸张大小相关除外)重置,再只应用你传入的选项,所以 若把它当作只改几个值来写,就会出事。实测:在 A4、margin=1in 的文档中调用 \newgeometry{margin=1cm}\textwidth 从 452.9679pt 变为 540.60239pt(即 597.50787 − 2×28.4526),随后 \restoregeometry 又回到 452.9679pt。两个命令都会插入 \clearpage,因此切换不会落在页面中途。若要反复使用同一套版面,可用 \savegeometry{名称} 保存,再用 \loadgeometry{名称} 调出。

latex
\usepackage[a4paper, margin=1in]{geometry}
\savegeometry{normal}          % remember this layout under a name
% ... in the body:
\newgeometry{margin=1cm}       % wide pages start here (a \clearpage is inserted)
%   a big landscape table, an appendix, a fold-out figure ...
\restoregeometry               % back to the preamble layout (another \clearpage)
% \loadgeometry{normal}        % or recall a saved one by name

若只想插入一页横向页面,可与 \newgeometry{landscape, ...} 组合,或使用专用的 lscapepdflscape 宏包提供的 landscape 环境(pdflscape 还会让 PDF 阅读器中的显示一并旋转,适合在屏幕上阅读的文档)。另外,如果要改的不是页面形状,而是 标题的样式 或页眉页脚的内容,那分别归 titlesecfancyhdr 管。分栏排版也有专门的页面。