1. 双栏版面里的“跨栏”难题
1.1 双栏浮动体的基础机制
在学术论文、期刊投稿和学位论文排版中,双栏(twocolumn)版面几乎是理工科论文的标配。这种版式在节省版面、提升阅读密度方面优势明显,但也引入了不少布局上的麻烦。最典型的场景就是:一篇双栏论文里,你有一张宽幅实验照片、一个覆盖多列数据的表格,或者一张需要横向摆放的大图,希望它能横跨整个页面的两栏——也就是所谓的“跨栏浮动体”。
LaTeX 对此有专门的解决方案:figure*和table*环境。普通的figure环境只能在当前栏内浮动,宽度上限是\columnwidth;而带星号的figure*、table*环境则允许浮动体横跨两栏,宽度上限是\textwidth。理论上,你只要把图表放进星号环境里,编译器就会自动把它放到页面顶部或底部,横跨两栏显示。
听起来很简单,对吧?但真正用过的人都知道,跨栏浮动体在双栏版面里的表现并不让人省心。默认情况下,figure*和table*只能出现在页面顶端,不能出现在页面底部,也不能单独占一页(至少在旧版 LaTeX 内核下,位置控制的自由度非常有限)。在长文档中,这种限制会直接导致浮动体堆积、跑到很靠后的位置,甚至干脆找不到合适的位置而报Float(s) lost错误。这时dblfloatfix宏包就是最直接的救火队员。
dblfloatfix 的核心作用,是给跨栏浮动体补上“底部位置”的支持,并优化它在页面上的放置算法,同时修复一些已知的跨栏浮动体丢失问题。通俗点说,它让figure*和table*的[!b]参数真正生效,让跨栏图表可以去页面底部,而不再被强制“按在头顶”。
1.2 为什么默认的跨栏浮动体总“乱跑”
要理解 dblfloatfix 到底解决了什么问题,得先弄明白 LaTeX 在双栏模式下到底怎么处理跨栏浮动体。
普通浮动体(单栏内的figure、table)的放置由三个基本位置参数控制:h(当前位置)、t(本页顶部)、b(本页底部),以及p(独立浮动页)。编译器会依次尝试这些位置,直到找到放得下的地方。整个过程受\topfraction、\bottomfraction、\textfraction等参数约束,防止浮动体把版面撑爆。
跨栏浮动体就不一样了。在双栏模式下,它是在“整个页面”的层面上处理的,而不是针对某一栏。早期 LaTeX 内核(LaTeX2e 的原始实现)对跨栏浮动体的位置支持非常有限,只允许t和p,不支持b。也就是说,即使你写了\begin{figure*}[!b],这个[b]也会被忽略或处理得很别扭,想让它出现在页面底部根本没门。
这就带来一个很实际的影响:当页面顶部已经被前面的跨栏浮动体占满,或者当前页顶部的空间不够大时,编辑器只能把这个跨栏浮动体推迟到后续页面,再找顶部落点。于是,你写在第 2 页的跨栏图,可能会漂到第 5 页甚至更远,打乱上下文的阅读顺序。更麻烦的是,当浮动体太多、页面空间不足时,LaTeX 还会出现“浮动体堆积”现象,文档中间插入一大片空白,把段落和图表硬生生隔开。这在期刊投稿中是比较伤版面观感的。
dblfloatfix 就是为处理这些问题而生的。它修改了跨栏浮动体的内部算法,允许[b]和[!b]将跨栏浮动体放到页面底部,并且修正了\clearpage之后跨栏浮动体丢失的 bug——这是个在长章节、多图表文档里很容易触发的老问题。
2. dblfloatfix 宏包:功能与使用准备
2.1 它到底解决了什么问题
dblfloatfix 是一个相当老牌的宏包,作者是知名的 LaTeX 开发者 Frank Mittelbach 等。它的定位非常明确:修复双栏跨栏浮动体的放置缺陷,并扩展位置支持。具体来说,它的主要功能可以归纳为三个层面。
第一,跨栏浮动体支持底部位置。加载宏包后,figure*[b]和table*[b]就能把图表放到页面底部两侧栏之间,也就是横跨两栏的底部区域。这就给了排版者更多的落点选择:顶部放不下、底部有空间时,不用再把整块内容推到下一页。
第二,修复\clearpage后跨栏浮动体被遗弃的问题。在旧版 LaTeX 内核中,当文档执行\clearpage或进入新章节时,如果还有未放置的figure*、table*浮动体,可能会直接消失或报错。dblfloatfix 修正了这个处理逻辑,让未放置的跨栏浮动体能在页面分页时正常输出。
第三,提供更合理的放置策略控制。它扩展了跨栏浮动体在页面上的布局判断,让顶部和底部空间都能被更高效地利用。
不过要说明白,dblfloatfix 不是万能的。它不影响普通单栏浮动体的行为,也不解决浮动体数量过多导致的版面崩坏问题。如果一页里塞了七八张图,什么宏包都救不了,得靠作者自己控制图表密度。
2.2 安装与基本加载方式
dblfloatfix 在 TeX Live 和 MiKTeX 的完整安装包中都是自带的,基本不需要单独下载。如果你用的发行版比较精简,或者报错提示File dblfloatfix.sty not found,再考虑手动安装。
在 TeX Live 环境下,可以先在终端里确认宏包是否可用:
kpsewhich dblfloatfix.sty如果输出一个.sty文件的路径,说明宏包已经安装好了。如果什么都没输出,说明发行版里没有这个文件,需要手动安装。最简单的做法是去 CTAN 下载 dblfloatfix.zip,解压后把.sty文件放到当前文档目录下,或者放到本地texmf树目录里(推荐放~/texmf/tex/latex/dblfloatfix/),然后刷新文件库:
mktexlsr ~/texmf基本加载方式很简单,在导言区加上一行即可:
\usepackage{dblfloatfix}需要注意加载顺序。如果你还用了stfloats、fixltx2e(在较新的 LaTeX 内核中已合并)这类同样控制浮动体表现的宏包,建议不要重复加载。fixltx2e的浮动体修复功能随 2015 年的 LaTeX 内核更新已经并入内核,而stfloats是另一个提供跨栏底部浮动支持的宏包,功能与 dblfloatfix 有重叠。同时使用可能出现位置参数冲突或行为异常,这一点实测下来要特别留意。
如果你平时用 VSCode + LaTeX Workshop 写文档,加载宏包后正常编译即可。LaTeX Workshop 默认的 texlive 发行版通常已经包含 dblfloatfix,所以基本不会有环境配置问题。要是遇到编译不过,先检查 main 文件是否有语法错误,再看 LaTeX Workshop 的日志输出面板,很多情况下问题并不在宏包本身,而是别的环节出了错。
3. 跨栏图表排版的完整实操配置
3.1 从模板到可用:最小可运行示例
先看一个最小可运行的例子。这个例子我实测过,可以直接复制到空文档里编译,方便你快速感受 dblfloatfix 的效果。
\documentclass[twocolumn]{article} \usepackage[demo]{graphicx} \usepackage{dblfloatfix} % 必要时调整跨栏浮动体占用页面的比例 \renewcommand{\dbltopfraction}{0.9} \renewcommand{\dblfloatpagefraction}{0.5} \begin{document} \section{实验设置} 这里演示跨栏浮动体的底部放置效果。在没有任何跨栏浮动体占据顶部的情况下, 用 \texttt{[!b]} 参数强制把图片放到页面底部。 % 跨栏表格,放在页面底部 \begin{table*}[!b] \centering \begin{tabular}{|c|c|c|} \hline 项目 & 数值 & 说明 \\ \hline A & 1.23 & 第一组数据 \\ B & 4.56 & 第二组数据 \\ C & 7.89 & 第三组数据 \\ \hline \end{tabular} \caption{跨栏表格放在页面底部的示例} \label{tab:bottom} \end{table*} 正文内容,用于填充版面空间。可以写几行描述实验参数的段落, 让页面足够长,方便观察底部跨栏表格的实际排版效果。 \section{结果分析} % 跨栏图片,放在页面底部 \begin{figure*}[!b] \centering \includegraphics[width=\textwidth]{sample-figure} \caption{跨栏图片放在页面底部的示例} \label{fig:bottom} \end{figure*} \end{document}这里的关键点是[!b]参数。加了感叹号!表示覆盖 LaTeX 默认的“位置参数限制”,尽量满足b(底部)的请求;b则表示把浮动体放在页面底部。在未加载 dblfloatfix 时,对figure*或table*使用[!b],很多情况下不会生效,浮动体仍然跑到顶部或后续页面;加载后,它会老老实实待在底部。
\renewcommand{\dbltopfraction}{0.9}这一行也很关键,它表示页面顶部最多允许 90% 的空间被跨栏浮动体占据。LaTeX 默认的这个值比较保守(通常是 0.7 左右),在图片偏大时容易导致放不下。\dblfloatpagefraction则控制独立浮动页中浮动体占页面的最小比例,值设得太高,浮动页容易出现;设得太低,又可能把零散的浮动体聚成一页。这两个参数在微调跨栏浮动体时非常有用,后面细说。
3.2 核心参数与位置控制的精细调节
dblfloatfix 让“位置参数选择”变得更灵活,但最终放置是否合理,还要靠一系列比例参数来控制。我建议你把下面这几个参数当成固定的调试工具箱,而不是死记硬背。
\dbltopfraction控制页面顶部允许被跨栏浮动体占据的最大比例。默认值约 0.7。如果你的跨栏图比较长(例如高度接近一页的一半),或者页面顶部同时要放多个浮动体,建议调高到 0.85~0.95。但不要调到 1.0,否则正文和标题会很拥挤,观感很差。
\dblfloatpagefraction控制独立浮动页中跨栏浮动体必须达到的页面占比阈值。默认值约 0.5。如果想避免出现大块空白页,可以适当降低到 0.4 左右,但太低又容易让浮动体过早被拼成一页。
\dblbotfraction是bottom区域相关的比例参数,但注意它在旧版 LaTeX 中并不直接支持跨栏浮动体。加载 dblfloatfix 后,跨栏浮动体的底部放置逻辑才真正可用。实际使用时,底部空间的管理主要和\bottomfraction以及页面布局参数相关,需要一起调整。
下表是我实测中比较稳定的一组参数组合,适用于大多数期刊模板:
| 参数 | 默认值 | 推荐范围 | 适用场景 |
|---|---|---|---|
\dbltopfraction | 0.7 | 0.85~0.95 | 顶部有多张跨栏图或大表格 |
\dblfloatpagefraction | 0.5 | 0.4~0.6 | 大量浮动体需要撑起独立页 |
\bottomfraction | 0.3 | 0.4~0.5 | 底部单栏浮动体较多 |
\textfraction | 0.2 | 0.1~0.2 | 页面文字与浮动体比例失衡时 |
注意:修改这些参数时,建议把它放在导言区,并加上注释说明你是在为哪个模板做调整。投稿换模板时,这些参数很可能导致版面异常,方便快速回滚。
3.3 单栏内容与跨栏浮动体的混排技巧
跨栏浮动体虽然横跨两栏,但正文仍然是双栏排列。这就产生了一个排版上的“空间争夺”问题:跨栏浮动体在页面顶部占据一个横向长条,下面的两栏文字宽度就变成比较窄的两条;跨栏浮动体在底部时同理。
在实际排版中,我经常遇到“顶部放一张跨度很大的图,下面的两栏文字被压得非常窄,阅读起来特别不舒畅”的情况。这时我一般会考虑两个调整方向。
第一个方向是调整跨栏图表的尺寸。很多情况下,图片的高度并不需要占满整个\textwidth。比如一张宽度为 16cm 的实验曲线图,如果原始长宽比是 16:6,放进\textwidth(假设 17cm)里,高度就有 6.4cm,在顶部会占掉将近三分之一页,把两栏文字压得太扁。这时候可以适当把宽度缩小到 0.8 倍\textwidth,画布高度也跟着降下来,整体感觉会均衡很多。
第二个方向是让跨栏图表和正文段落穿插得更自然。LaTeX 默认的浮动机制是“找到一个位置,然后插入”,它不会自动考虑这个位置是否打断了段落的阅读节奏。如果你需要图表紧跟在某一段落后面出现,可以使用[ht]参数组合,或者在同一位置用一个table*环境紧邻正文后写,配合\FloatBarrier命令(由placeins宏包提供)强制在某一位置刷新浮动体队列。这一点在双栏论文里格外重要,因为跨栏浮动体一旦跑远,读者经常找不到图表和正文的对应关系。
dblfloatfix 的主要贡献就是补上了[b]这个落点选项,让“顶部放不下就放底部”成为可能,等于给排版者多了一个灵活的方案。
4. 实战中容易踩的坑与排查实录
4.1 跨栏浮动体跑到下一页或直接丢失
这个是我在实际代码里碰到最多的问题,也是最让新手抓狂的。现象很典型:正文里写了\begin{figure*},编译后正文后面的整段内容被推到下一页,图片却出现在后面好几页,有时候甚至查无此图,控制台上冒出Float(s) lost的警告。
先说Float(s) lost的常见原因。在旧版 LaTeX 内核中,figure*和table*在处理跨页分栏时,如果碰到\clearpage、章节结束、文档结束等强制分页点,浮动体可能没来得及放置就直接“丢了”。dblfloatfix 修复的正是这个逻辑:加载宏包后,未放置的跨栏浮动体会被正确传递到后面的页面继续尝试放置。
如果是“浮动体跑到下一页”的情况,问题通常出在位置参数选择和页面空间估算上。LaTeX 放置浮动体时,会先判断当前页面剩余空间是否足够,不够就推迟到下一页面。跨栏浮动体需要占据整页顶部的整行空间,所以在双栏模式下它往往比普通浮动体更难找到落点。尤其在文档前几页,顶部已经有论文标题、作者信息、摘要等大块非浮动内容时,跨栏浮动体很容易被挤到后面。
处理这种问题的思路,一是检查是否加载了 dblfloatfix,二是在figure*或table*的位置参数上明确指定[!t]、[!b]或[!tb],三是控制页面中其他浮动体的数量和大小,避免“抢位置”。
4.2 图片尺寸与宽度设置的常见错误
跨栏图表的宽度,应优先使用\textwidth,而不是\columnwidth。这是很多新手容易忽略的细节。普通figure环境里,图片默认宽度上限是\columnwidth,即一栏的宽度;但在figure*环境里,如果还用\columnwidth,图片就会显得特别窄,在跨栏版式里只占了一部分的宽度,两侧留白巨大,非常难看。
正确的写法是:
\begin{figure*}[!t] \centering \includegraphics[width=\textwidth]{my-wide-figure} \caption{跨栏图片示例} \label{fig:span} \end{figure*}如果图片原始分辨率不高,width=\textwidth按比例放大后可能会模糊。这时建议限制图片高度,用height参数控制,比如:
\includegraphics[width=0.9\textwidth, height=7cm, keepaspectratio]{my-figure}keepaspectratio参数保证图片在同时指定宽高时保持原始比例,避免拉伸变形。
另一种常见错误是在双栏模板里使用了超过\textwidth的表格列宽。跨栏表格如果设置了很宽的列,在窄的两栏正文里会出现“表格宽度超出页面”的警告,甚至导致内容溢出页面边缘。处理方式是:要么把表格放在table*环境里,要么用tabularx、longtable等宏包控制列宽,确保表格总宽度不超过\textwidth。在table*环境里,可以这样设定总宽度:
\begin{table*}[!t] \centering \begin{tabularx}{\textwidth}{lXr} ... \end{tabularx} \caption{跨栏表格宽度控制} \label{tab:span} \end{table*}tabularx的X列会自动伸展填满剩余宽度,配合\textwidth总宽度,基本不会溢出版面。
4.3 编译报错的定位思路
LaTeX 编译报错时,业界共识是:先看.log文件,再推断是哪一行的代码出了问题。很多人一看到控制台输出一屏红色提示就慌了,实际上 LaTeX 的错误定位相对清晰,只要掌握基本套路,处理起来并不难。
最典型的错误是! LaTeX Error: Float(s) lost。这个错误出现时,先在后端日志里查找,看有没有浮动的figure、table或figure*。将figure*环境的位置参数改为[!t]或[!tb],加载 dblfloatfix,基本能解决。
另一种常见错误是! File dblfloatfix.sty not found。这种情况多半是发行版太精简或本地文件库没刷新。按前面的安装方法处理即可。如果你用 VSCode + LaTeX Workshop,可以在.latexmain文件所在的目录下依次查看.log文件开头部分,确认宏包加载顺序和系统搜索路径。
有时候错误信息显示为Missing \endgroup inserted,这多半是浮动体内部出现了配对错误,比如\begin{figure*}漏写了\end{figure*},或者\caption、\label写在了\begin{center}外层。排查时直接搜索.log中第一个出错位置,翻到源码那一行对照检查。
还有一个容易被忽略的点:在双栏模板中,figure*和table*在旧版 LaTeX 中不能与multicol环境混用,否则会出现“浮动体跑到 multicol 环境内部”的诡异现象。简单说就是,如果你把跨栏浮动体放在multicols环境里面,它无法正确横跨整个页面。解决办法是:要么把跨栏浮动体移到multicols环境外面,要么改用标准的twocolumn模式。这个坑我踩过好几次,审稿意见里也经常被提到,这里专门列出来。
5. 进阶技巧:与标题、参考文献、模板配合的细节
5.1 跨栏图表的标题与标签处理
跨栏浮动体的标题处理与普通浮动体稍有区别。因为标题要横跨两栏,所以它的宽度也是\textwidth。默认情况下,\caption在figure*和table*环境中会正确占据整行宽度,无需额外设置。但如果你给图片配了很长的标题,导致标题换行后的行数较多,版面观感会受影响。这时可以考虑用caption宏包对标题字号和间距做微调。
\usepackage[font=small,labelfont=bf]{caption}font=small会把标题字号改小,labelfont=bf让“图 1”“表 2”这类标签加粗,整个版面的协调性会好很多。
\label的位置建议放在\caption后面,即:
\begin{figure*}[!t] \centering \includegraphics[width=\textwidth]{data} \caption{不同温度下的性能变化曲线} \label{fig:perf} \end{figure*}这样做可以保证\ref{fig:perf}能够正确引用到图表的编号。
另外一个细节:跨栏浮动体的编号顺序是按它在源码中出现的顺序分配的,不是按它在页面上放置的位置。如果文档中大量使用figure*和普通figure混排,编号顺序可能和视觉顺序不一致。这种情况一般不影响审稿,但如果你对“图 1 应该在正文里先出现”的阅读逻辑有要求,可以借助\counterwithin或自定义计数器来调整,不过这属于进阶操作了,多数模板不需要。
5.2 与双栏模板和参考文献配合的注意事项
投期刊或者写学位论文时,模板往往已经定义好了版面结构,加载 dblfloatfix 的位置和方式就显得特别重要。我的习惯是:在模板的导言区里,\documentclass之后立刻加载 dblfloatfix,然后再加载其他宏包。这样可以避免一些宏包以默认的双栏模式重定义浮动体环境,产生冲突。
参考文献方面,双栏论文里的参考列表通常也用两栏排布。使用\bibliography{}让 BibTeX 自动生成时,跨栏浮动体不会影响参考文献的生成顺序,但如果参考文献列表太长,排版上可能出现大块空白。这时可以考虑在thebibliography环境前后调整页面的浮动体位置,或者手动用\clearpage分开章节。真正的坑在于:如果你在figure*里使用了引用标签,而这些标签对应的参考文献条目在浮动体移动到很远之后才出现,阅读时找不到来源的体验会很差。建议跨栏图表的标题里尽量引用“对比文献”按钮上的关键标记,确保引用关系一目了然。
数学建模国赛、计算机学报等常见双栏模板里,跨栏浮动体的用法基本是一致的。只要模板基于article类或ctexart类,加载 dblfloatfix 大多都能直接工作。万一模板自定义了浮动体环境(比如重命名了figure环境),优先检查模板的手册或注释,再看是否需要改用 stfloats。实测下来,大部分主流模板都没有这种深度定制,所以 dblfloatfix 的兼容性相当好。
5.3 多图并排与跨栏浮动体的组合
跨栏浮动体里放多图并排在论文里相当常见,比如把两张对比图并排放在一个figure*环境里。基础用法是minipage加subfigure或subcaption宏包。
用minipage时,两张图各占一半宽度:
\begin{figure*}[!t] \centering \begin{minipage}[b]{0.48\textwidth} \centering \includegraphics[width=\linewidth]{method-a} \caption{方法 A 的实验结果} \label{fig:a} \end{minipage} \hfill \begin{minipage}[b]{0.48\textwidth} \centering \includegraphics[width=\linewidth]{method-b} \caption{方法 B 的实验结果} \label{fig:b} \end{minipage} \end{figure*}如果在跨栏浮动体里用普通figure的\caption,编号会乱掉。正确做法是加载subcaption宏包,用subfigure环境实现子图编号:
\usepackage{subcaption} \begin{figure*}[!t] \centering \begin{subfigure}{0.45\textwidth} \includegraphics[width=\linewidth]{a} \caption{第一组} \label{fig:sub-a} \end{subfigure} \hfill \begin{subfigure}{0.45\textwidth} \includegraphics[width=\linewidth]{b} \caption{第二组} \label{fig:sub-b} \end{subfigure} \caption{总体对比结果} \label{fig:total} \end{figure*}这里用到\linewidth,在 minipage 和 subfigure 内部,\linewidth会自动变成子环境的宽度,比硬编码0.4\textwidth更稳妥。当我写双栏论文的对比实验部分时,这个方法几乎是标准操作,配合 dblfloatfix 放在页面顶部或底部,整体版面会很均衡。
6. 把跨栏浮动体“驯服”的几点心得
写完全套流程,最后分享几个我在实际项目里反复验证过的操作习惯,算不上什么高深理论,但对排版的稳定性和效率帮助很大。
第一,先整体设计图表在论文中的分布,再动手逐段写。如果一篇双栏论文里会出现 5 张以上的宽幅图表,建议先在结构上规划好哪些放顶部、哪些放底部,避免同一个页面顶上两张、底部一张挤成一团。dblfloatfix 提供了“底部可选”的能力,但最终布局还是要靠内容数量和尺寸控制来保证。
第二,跨栏浮动体和正文的阅读顺序,不一定完全一致。LaTeX 的浮动机制本质上是“推迟放置”,只要位置参数合理,编译器总能找到合适的落点。如果审稿人对图表顺序有严格要求,可以用\FloatBarrier在关键位置强制刷新浮动体队列,但要注意,这会在页面上留下较大空白,所以在双栏模板中要谨慎使用。
第三,调试时善用.log文件。某张图跑到很远,或者某页出现大面积空白,打开.log搜索float、overfull等关键词,基本能找到线索。不要靠肉眼猜,那样容易浪费大量时间。
第四,投稿前一定要按目标期刊或会议的模板重新编译一遍,绕开所有多余的个人设置。很多期刊编辑会直接用官方模板编译,如果你在自己的环境里加了一堆宏包和参数,到了那边可能编译不过或者版面错乱。把 dblfloatfix 和其他辅助设置统一放在导言区并加注释,是负责任的做法。
从我自己的使用经历来看,dblfloatfix 是一个“体积小、副作用小、收益直接”的宏包。它不需要你重写文档结构,只是把 LaTeX 在跨栏浮动体处理上的历史缺陷补平。只要你愿意花几分钟把页面比例参数调一遍,双栏模板里的宽图表排在合适位置的难度会大幅下降。这个方案我在多个双栏期刊模板和学位论文模板里都用过,稳定可靠,推荐你直接上手试。