枠で囲む

LaTeX で文章を枠で囲もうと思って最初に打つのは、たいてい \fbox{...} です。うまくいきます——中身が 1 行に収まっているあいだは。段落をまるごと渡した瞬間、枠は折り返さずに紙面の外まで伸び、ログには Overfull \hbox と出ます。この一点の制約が、framedmdframedtcolorbox という枠囲みパッケージ群が存在する理由そのものです。このページでは、標準の \fbox\framebox から、ページをまたげる枠、そして色とタイトルの付いたパネルまでを、「枠はなぜ切れないのか」という一本の筋でたどります。

\fbox\framebox——標準で引ける枠と、その壁

\fbox{...} は何も読み込まなくても使えて、引数の中身にぴったり合う細い枠を引きます。幅や寄せ方まで指定したいときは \framebox[幅][位置]{...} です。第 1 任意引数の幅で枠の横幅を決め、第 2 任意引数の位置で中身の置き方を選びます——c(中央、既定)、l(左寄せ)、r(右寄せ)、s(両端そろえ)。任意引数を付けない \framebox\fbox とまったく同じ動きです。どちらも行の途中に置ける行内ボックスで、ベースラインに乗るので \hspace や前後の文字と自然に並びます。

latex
\fbox{a framed word}

% width 5cm, content flush left inside the box
\framebox[5cm][l]{flush left}

% multi-line: frame a \parbox, not the text itself
\fbox{\parbox{0.8\linewidth}{%
  Several lines of text. The inner box wraps them
  first, and only then does the frame go around.}}

そしてここが壁です。\fbox\framebox も中身を折り返しません。長い段落を渡すと 1 行のまま右へ伸び続け、Overfull \hbox (... too wide) という警告とともに枠が紙面からはみ出します。これはバグではなく定義どおりの動作です——\fbox は内部で中身を 1 個の水平ボックス(\hbox)に組むので、そのボックスの中には改行点そのものが存在しません。複数行を囲みたいなら、上の例のようにまず \parboxminipage で段落を組み立て、そのボックスを \fbox で囲みます。\parboxminipage そのものの使い方は「ボックス」のページにあります。ただしこの手も、枠がページをまたぐ必要が出たとたんに行き詰まります。その理由は少し先で見ます。

\fboxrule\fboxsep——線を太く、内側の余白を広く

枠の見た目は長さ 2 つだけで決まります。\fboxrule が罫線の太さで、標準クラスの既定値は 0.4pt\fboxsep が枠と中身のあいだの余白(パディング)で、既定値は 3pt です。どちらも \setlength で変えられます。既定の 0.4pt は本文と同じくらい細いので、注意書きとして目立たせたいときはたいてい足りません。とはいえ、これらは通常のグローバルな長さなので、プリアンブルで変えると文書中のすべての \fbox に効きます。1 箇所だけ太くしたいなら、下のようにグループ {...} の中で \setlength してください。colorxcolor を読み込むと同じ 2 つの長さに従う \fcolorbox{枠色}{背景色}{...} が使えるようになります——色名や混色の書き方は「色(xcolor)」のページにあります。

latex
% global: every \fbox in the document becomes thicker
\setlength{\fboxrule}{1pt}
\setlength{\fboxsep}{8pt}

% local: the group limits the change to this one box
{\setlength{\fboxrule}{2pt}\fbox{a heavy frame}}

% same two lengths, plus colour (needs color or xcolor)
\fcolorbox{red}{yellow!20}{warning}

なぜ枠はページをまたげないのか——「折り返せる枠」の正体

答えは単純で、枠を引いた材料は 1 個のボックスになるからです。TeX のページ分割器(page builder)は縦に並んだ要素の「あいだ」でしか切れません。ボックスの内側は切れない一かたまりとして扱われます。だから、囲んだ瞬間にその材料はページ分割の候補から消えます。ここから「折り返せる枠」の正体が見えてきます——本当は 1 個の枠が切れているのではありません。パッケージは先に中身をページに収まる分量へ分割し、断片ごとに別々の枠を描いて、継ぎ目が見えないように積み上げているのです。

Donald Arseneau の framed パッケージは、その仕組みを設計としてそのまま表に出しています。ドキュメントによれば、分割された環境の最初の断片には \FirstFrameCommand、途中の断片には \MidFrameCommand、最後の断片には \LastFrameCommand が適用されます。oframed 環境が「ページ分割点で上下だけ開いた枠」になるのは、この 3 つを使い分けて、途中の切り口には横罫を引かないようにしているからです。framed.sty の著作権表示は 1992 年から始まっていて、この問題が LaTeX2e よりも古いことを物語っています。仕組みが「分割してから飾る」である以上、限界も想像がつきます——折り返せる枠の中の脚注・フロート・段抜きは壊れやすく、tcolorboxmdframed のマニュアルもそこは注意事項として挙げています。

framed パッケージ——framed / shaded / leftbar の 3 環境

\usepackage{framed} を書くだけで、ページをまたげる環境が 3 つ手に入ります。framed は本文幅いっぱいの枠線、shaded は枠線の代わりに背景を塗るもの、leftbar は左端に太い縦罫を 1 本引くもので、引用や補足のブロックによく使われます。shaded 系を使うときは shadecolor という名前の色をあらかじめ定義しておく必要があります——\definecolor{shadecolor}{gray}{0.9} のように直接定義するか、xcolor を読み込んで \colorlet{shadecolor}{gray!15} と書きます。定義を忘れると ! Undefined control sequence ではなく色が未定義だというエラーで止まります。

latex
\usepackage{framed}
\usepackage{xcolor}
\colorlet{shadecolor}{gray!15}

% these lengths are the framed counterparts of
% \fboxrule and \fboxsep
\setlength{\FrameRule}{1pt}
\setlength{\FrameSep}{10pt}

\begin{framed}
  A long note. If it reaches the bottom of the page the
  frame is split and continues on the next one, which is
  precisely what \fbox cannot do.
\end{framed}

\begin{shaded}
  Filled background instead of a rule.
\end{shaded}

\begin{leftbar}
  A single vertical rule in the left margin.
\end{leftbar}

寸法は \FrameRule\FrameSep で調整します——パッケージのドキュメントが明言しているとおり、これは framed 環境の内側で \fboxrule\fboxsep の代わりに使われる長さです。環境の前後の縦の空きは \OuterFrameSep で、既定では \topsep と同じになります。派生環境もいくつかあり、shaded* は塗りの端を本文幅に揃え(無印の shaded は余白側へ少しはみ出します)、snugshadesnugshade* は中身に密着した塗り、oframed は前節で触れた上下の開く枠です。さらに、\FrameCommand を自分で定義して \MakeFramed ... \endMakeFramed で挟めば、独自の「折り返せる装飾」を作れます——このパッケージの本来の目的はむしろそちらだとドキュメントは述べています。逆に言えば、framed には角丸も影もタイトルもありません。そこが欲しくなったら次の段階へ進みます。

数式を囲む \boxed——中身は結局 \fbox

結論の式を枠で囲みたいときは、\usepackage{amsmath} を読み込んで数式モードの中で \boxed{...} を使います。中身を数式として組んだうえで枠を付けてくれる命令です。おもしろいのはその定義で、amsmath の中では \boxed\fbox{\m@th$\displaystyle#1$} とほぼそのまま書かれています。つまり別系統の描画をしているのではなく、数式を $...$ で包んで \fbox に渡しているだけです。ここから実務上の帰結が 3 つ出てきます。\fboxrule\fboxsep がそのまま効くこと。当然ながらページをまたげないこと。そして \displaystyle が強制されるので、添字の中に \boxed を書くと囲まれた式だけ本文サイズのまま大きく出てしまうことです。

latex
\usepackage{amsmath}

\[
  \boxed{E = mc^2}
\]

% \fbox inside math sets its argument in TEXT mode:
% upright roman letters, not math italic
$\fbox{x+y}$ \quad versus \quad $\boxed{x+y}$

この違いは実際に並べてみるとはっきりします。$\fbox{x+y}$ は引数を文字モードで組むので、xy も立体(ローマン体)になり、+ の前後の空きも数式のものではありません。$\boxed{x+y}$ なら数式イタリックと数式の空きが保たれます。数式の中で枠が必要なら、迷わず \boxed を選んでください。式番号までまとめて囲みたい、align の複数行にまたがって囲みたい、といった込み入った要求には mathtools に同梱の empheq パッケージが向いています。数式モードそのものについては「数式モードの基本」のページを参照してください。

tcolorbox——色・タイトル・breakable の決定版

色・タイトル・改ページを一度に片づけたいなら tcolorbox です。\usepackage[most]{tcolorbox} で読み込み、tcolorbox 環境に colback=(背景色)、colframe=(枠線の色)、title=(タイトル帯)、breakable(ページをまたぐ)を渡します。ここでいちばん引っかかりやすいのが most の役割です。tcolorbox は本体と多数のライブラリに分かれていて、breakable はオプション名であると同時に ライブラリの名前 でもあります。\usepackage{tcolorbox} とだけ書いて breakable を指定しても、ライブラリが読み込まれていないので枠は分割されません。[most] を付けるか \tcbuselibrary{breakable} と明示する必要があります。ソースを見ると mostmanyrasterskinsbreakablehookstheoremsfitting)に listingsutf8externalmagazinevignetteposter を足したもので、外部ツールに依存する minted だけが外れています。

latex
\usepackage[most]{tcolorbox}

\begin{tcolorbox}[colback=blue!5, colframe=blue!60!black,
                  title=Remarks, fonttitle=\bfseries, breakable]
  A coloured box with a title bar. Because breakable was
  given, a long body is split across the page boundary.
\end{tcolorbox}

% inline, fitted to its content, no page breaks
\tcbox[colback=red!5, colframe=red!60!black]{inline box}

形は数値のキーで整えます。boxrule= が枠線の太さ(既定 0.5mm)、arc= が角丸の半径(既定 1mm)で、角を直角にしたければ sharp corners、丸めたければ rounded corners です。タイトル帯の背景色は colbacktitle=、見出しの書体は fonttitle=\bfseries などを渡します)。行内に小さな枠を 1 個置くだけなら環境ではなく \tcbox{...} を使います——\fbox と同じく中身に合わせて縮み、同じく折り返しません。土台には pgf があり、本体は pgf を、most に含まれる skins ライブラリは tikz そのものを読み込みます。だから enhanced を指定すると TikZ の描画力がそのまま前に出てきて、影・二重枠・透過・装飾的なタイトルまで扱えます。定理環境を仕立てる theorems ライブラリ、\tcblower で箱を上下 2 段に割ってソースと出力を並べる使い方など、機能は際限がありません。

「際限がない」というのは比喩ではありません。TeX Live 2024 に入っている tcolorbox のマニュアル(texdoc tcolorbox で開きます)は 548 ページ あります。箱を描くためのパッケージ 1 個の説明書として、これはちょっとした専門書です。作者は Thomas F. Sturm で、CSV ファイルを LaTeX から読み込む csvsimple や、家系図を組む genealogytree も同じ人の手によるものです。実務上の助言としては、548 ページを読み通そうとしないこと。colback / colframe / title / breakable の 4 つで大半の用は足ります。凝りたくなったときにマニュアルの索引を引く、くらいの距離感が現実的です。

\newtcolorbox で同じ枠を使い回す

同じ体裁の枠を本文中で何度も書くのは、色を変えたくなった日に必ず後悔します。プリアンブルで \newtcolorbox を使って一度だけ定義してください。書式は \newtcolorbox[初期化オプション]{名前}[引数の個数][既定値]{オプション} で、\newenvironment と同じように引数を取る環境も作れます。命令版が欲しければ \newtcbox、文書全体の既定値をまとめて変えたければ \tcbset{...} です。名前の付け方にはコツがあります——blueroundbox のような見た目の名前ではなく、notewarningdefinition のように 意味 で名付けること。そうしておけば、後から配色を変える作業がプリアンブルの数行の書き換えで済みます。

document.tex
\usepackage[most]{tcolorbox}

% one argument: the heading text
\newtcolorbox{note}[1]{%
  colback=yellow!10, colframe=orange!70!black,
  fonttitle=\bfseries, title=#1, breakable}

\begin{document}
\begin{note}{Careful}
  The note environment is now defined; its heading
  arrives as an argument.
\end{note}
\end{document}

mdframed——framedtcolorbox の中間

framed より見栄えがして、tcolorbox ほど大がかりでない改ページ可能な枠が欲しい——そこに収まるのが mdframed です。\usepackage{mdframed} で読み込み、mdframed 環境の任意引数に backgroundcolor=roundcorner=linecolor=linewidth= などを渡します。このパッケージが何のために書かれたかは、ソースの先頭に作者自身の言葉で書いてあります——\fbox\fcolorbox を使うとページ送りを手で処理しなければならない、mdframed 環境はそれを自動で扱う、と。このページの出発点だった \fbox の制約が、そのまま別のパッケージの存在理由として明文化されているわけです。実装も framed.sty の考え方を土台にしていると明記されています。

latex
\usepackage{mdframed}

\begin{mdframed}[backgroundcolor=gray!10, roundcorner=5pt,
                 linecolor=gray!60, linewidth=1pt]
  An mdframed box. It breaks across pages.
\end{mdframed}

% a named environment of your own, and a framed theorem
\newmdenv[linecolor=red, linewidth=1.5pt]{alert}
\newmdtheoremenv{prop}{Proposition}

特徴は描画方式を選べることです。framemethod=default は標準の LaTeX 命令で描き、framemethod=TikZframemethod=pstricks に切り替えるとより凝った装飾が使えます。よく使う設定は \mdfsetup{...} にまとめておけます。独自の枠環境は \newmdenv{...}、枠の付いた定理環境は \newmdtheoremenv{...} で定義します。ひとつ知っておくとよいのは、mdframed の最新版がバージョン 1.9b、日付が 2013 年 7 月 1 日だということです——ソースには「現在このパッケージは beta 状態」という一文がいまも残っています。それでも 10 年以上にわたって TeX Live に収録され、実際に動き続けています。新規の文書で本格的にカスタマイズするつもりなら、いまも活発に保守されている tcolorbox のほうが安全な賭けです。

\fboxtcolorbox のどちらを使うか——早見表

選ぶ基準はひとつ、囲みたい材料の大きさです。1 語や 1 行なら \fbox / \framebox、数式なら \boxed、段落のかたまりを地味に囲むだけなら framed、色と角丸がほしいなら mdframed、タイトルと改ページと装飾まで求めるなら tcolorbox。迷ったときは、ページをまたぐ必要があるかどうかを最初に自問してください。この一点で候補は上下 2 グループにきれいに分かれます。もうひとつの現実的な助言として、framedtcolorbox を同じ文書で併用しても衝突はしませんが、文書全体の見た目を揃えたいなら 1 つに絞ったほうが結果はよくなります。

命令・環境囲める対象改ページ向いている場面
\fbox / \framebox1 行に収まる中身不可語や短い一文を手早く囲む
\boxed数式(数式モード)不可結論の式を目立たせる
framed段落のかたまり装飾なしで軽く囲む
mdframed段落のかたまり色や角丸を手頃な手間で
tcolorbox段落・行内・定理環境可(breakable)タイトル・配色・装飾まで揃える