俳句や小説の引用、和風デザインの見出しなど、「Webページの一部を縦書きにしたい」という場面は意外とよくあります。これを実現するのが CSS の writing-mode プロパティです。値を1つ指定するだけで、横書き(左から右)だったテキストを、日本語の本のような縦書き(上から下・行は右から左)へ切り替えられます。この記事では、writing-mode の基本的な使い方から、各値の意味、縦書きで英数字が横に倒れてしまうときの対処、行の進む方向の違いまでを、実際に動かせるデモを交えてコーディング初心者〜中級者の方に向けて解説します。
目次
writing-modeとは何か
writing-mode は、テキストを並べる方向(行が水平に流れるか、垂直に流れるか)と、行が積み重なっていく向きを指定するプロパティです。Webページは初期状態では「文字が左から右へ進み、行は上から下へ重なる」横書きですが、writing-mode に縦書き用の値を与えると、「文字が上から下へ進み、行は右から左(または左から右)へ重なる」縦書きに変わります。
このプロパティは要素単位で効きます。ページ全体を縦書きにすることも、特定の div や見出しだけを縦書きにすることもできます。日本語の縦書き表現はもちろん、モンゴル文字のような縦方向に書く言語の表示にも使われます。
基本の使い方:vertical-rlで縦書きにする
もっとも基本的な縦書きは、writing-mode: vertical-rl; を指定するだけです。vertical(垂直)に文字が流れ、rl(right to left)で行が右から左へ進む、という意味で、日本語の本や新聞でおなじみの並び方になります。下のデモでは、縦書きにしたい要素にこの1行を指定しています。コードを書き換えて動きを確かめてみてください。
<div class="tategaki">
<h2>吾輩は猫である</h2>
<p>吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。</p>
</div>
.tategaki {
/* これだけで縦書きになる(右から左へ行が進む) */
writing-mode: vertical-rl;
height: 220px;
padding: 16px;
border: 1px solid #ddd;
border-radius: 8px;
background: #fdfcf7;
font-family: "Yu Mincho", "YuMincho", serif;
line-height: 1.8;
}
.tategaki h2 {
margin: 0 0 1em;
font-size: 18px;
color: #b0413e;
}
.tategaki p {
margin: 0;
font-size: 15px;
}
縦書きにすると、width と height の感覚も入れ替わります。横書きでは文字が増えると横に広がりますが、縦書きでは文字が下方向に増え、行が増えると左へ広がっていきます。そのため、縦書きの要素では height で「1行に入る文字数(行の長さ)」を、おおまかにコントロールすることになります。
writing-modeの主な値
writing-mode には複数の値があります。横書きに戻すための値や、行の進む方向が異なる縦書きの値など、それぞれの意味を整理すると次のようになります。日本語の縦書きで実用的なのは vertical-rl で、ほかは特殊な用途や他言語向けと考えると分かりやすいです。
| 値 | 文字の進む向き | 行の進む向き | 主な用途 |
|---|---|---|---|
horizontal-tb | 水平(左→右) | 上→下 | 初期値。通常の横書き |
vertical-rl | 垂直(上→下) | 右→左 | 日本語などの一般的な縦書き |
vertical-lr | 垂直(上→下) | 左→右 | 行を左から右へ重ねたい縦書き |
tb は top to bottom(上から下)、rl は right to left(右から左)、lr は left to right(左から右)の略です。このほか文字体系専用の sideways-rl / sideways-lr という値もありますが、対応ブラウザが限られるため、日本語の縦書きでは基本的に vertical-rl を使えば十分です。
縦書きで英数字が横に倒れるときはtext-orientation
縦書きにしたとき、全角の日本語はきれいに縦に並ぶのに、半角の英数字(ABC や 123 など)だけが横に倒れて表示されることがあります。これは不具合ではなく、text-orientation プロパティの初期値 mixed の挙動です。mixed は、縦書きにふさわしい文字(日本語など)は直立させ、ラテン文字や数字は横倒しにする、という混在表示を行います。
英数字も縦書きの文字と同じように直立させたい場合は、text-orientation: upright; を指定します。下のデモは、同じ縦書きの中で mixed(初期値)と upright を並べたものです。英数字の見え方がどう変わるか比べてみてください。
<div class="row">
<div class="card mixed">
<p class="label">text-orientation: mixed(初期値)</p>
<p class="body">縦書きで全角は縦、半角の英数字 ABC 123 は横に倒れます。</p>
</div>
<div class="card upright">
<p class="label">text-orientation: upright</p>
<p class="body">英数字 ABC 123 も直立して縦に並びます。</p>
</div>
</div>
.row {
display: flex;
gap: 16px;
font-family: "Yu Mincho", "YuMincho", serif;
}
.card {
writing-mode: vertical-rl;
height: 240px;
padding: 14px;
border: 1px solid #ddd;
border-radius: 8px;
background: #fdfcf7;
line-height: 1.9;
}
/* 半角英数字を横倒しのままにする(初期値) */
.mixed .body {
text-orientation: mixed;
}
/* 半角英数字も直立させる */
.upright .body {
text-orientation: upright;
}
.label {
margin: 0 0 1em;
font-size: 13px;
color: #b0413e;
}
.body {
margin: 0;
font-size: 15px;
}
upright はすべての文字を直立させるため、英単語が縦に1文字ずつ並んで読みにくくなることもあります。年号や数桁の数字を縦書きの中で読みやすく見せたい場合は、upright のほかに、数桁の数字をまとめて直立させる「縦中横」を実現する text-combine-upright という別プロパティもあります。まずは text-orientation で英数字の向きを調整し、必要に応じて使い分けるとよいでしょう。
vertical-rlとvertical-lrの違い
縦書き用の値には vertical-rl と vertical-lr の2つがあります。どちらも文字は上から下へ流れますが、行が積み重なっていく方向が逆です。vertical-rl は行が右から左へ進み、日本語の書籍と同じ並びになります。一方 vertical-lr は行が左から右へ進みます。下のデモで、最初の行(先頭の文字列)がどちら側に表示されるかを見比べてみてください。
<div class="row">
<div class="box rl">
<p class="label">vertical-rl</p>
<p>一行目です。</p>
<p>二行目です。</p>
<p>三行目です。</p>
</div>
<div class="box lr">
<p class="label">vertical-lr</p>
<p>一行目です。</p>
<p>二行目です。</p>
<p>三行目です。</p>
</div>
</div>
.row {
display: flex;
gap: 16px;
font-family: "Yu Mincho", "YuMincho", serif;
}
.box {
height: 200px;
padding: 14px;
border: 1px solid #ddd;
border-radius: 8px;
background: #fdfcf7;
line-height: 1.9;
}
/* 行が右から左へ進む(縦書きの一般的な向き) */
.rl {
writing-mode: vertical-rl;
}
/* 行が左から右へ進む */
.lr {
writing-mode: vertical-lr;
}
.box p {
margin: 0;
font-size: 15px;
}
.label {
color: #b0413e;
font-size: 13px;
margin-bottom: 1em !important;
}
日本語の自然な縦書きを再現したいなら、ほとんどの場合 vertical-rl を選びます。vertical-lr は、行を左から右へ重ねたい特殊なレイアウトや、左横書きと組み合わせた特殊な表現で使う程度と考えておけば問題ありません。
縦書きが意図どおりに表示されないとき
高さが足りずに行が折り返してしまう
縦書きの要素では、height が1行に入る文字数の上限になります。高さが小さすぎると、1行に収まりきらない文字が左隣の新しい行へ折り返され、意図しない見た目になります。長い文章を1行で見せたいときは height を十分に確保するか、行の折り返し自体を許容したうえで全体の幅(縦書きでは横方向の広がり)を調整します。横書きで width を考える感覚を、そのまま height に置き換えて考えると分かりやすくなります。
英数字や記号の向きが思った通りにならない
前述のとおり、縦書きでの英数字の向きは text-orientation が制御しています。英数字が横倒しになるのは初期値 mixed の正常な挙動なので、直立させたいときは text-orientation: upright; を加えます。逆に、すべての文字を横倒しにしたい特殊な表現では sideways という値もありますが、対応状況に差があるため利用時はブラウザの対応を確認してください。向きの問題は writing-mode 単体ではなく text-orientation とセットで考えるのがコツです。
マージンやパディングの向きが入れ替わる
縦書きにすると、見た目の上下左右と、margin-top などの物理的なプロパティの関係が直感とずれることがあります。たとえば横書きでの「上の余白」は、縦書きでは見た目の右側に現れるといった具合です。文章の流れに沿って余白を指定したいときは、margin-block / margin-inline や padding-block / padding-inline といった論理プロパティを使うと、writing-mode を切り替えても破綻しにくくなります。論理プロパティは「行が進む方向(block)」と「文字が進む方向(inline)」を基準にするため、縦書き・横書きのどちらでも同じ意味で効きます。
まとめ
writing-mode は、テキストの流れる方向を切り替えて縦書きを実現するプロパティです。日本語の縦書きには writing-mode: vertical-rl; を指定するのが基本で、行は右から左へ進みます。行を左から右へ重ねたいときは vertical-lr、横書きに戻すには初期値の horizontal-tb を使います。縦書きで半角英数字が横に倒れるのは初期値 mixed の正常な挙動で、直立させたいときは text-orientation: upright; を併用します。縦書きでは height が行の長さを決めること、余白の向きが入れ替わるため論理プロパティが扱いやすいことも押さえておけば、和風デザインや引用の縦書き表現を素直に組み立てられます。