writing-mode:テキストの書字方向やブロックのフローを指定する

初期値 horizontal-tb
適用対象 全ての要素。ただし表の行、列、行グループ、列グループを除く
継承 する
アニメーション 離散値
対応ブラウザ caniuseで確認

writing-modeプロパティの説明

CSSのwriting-modeプロパティは、テキストの書字方向やブロックのフローを指定します。具体的には、行のレイアウトを横書きにするか縦書きにするか、ブロックのフローを左向きにするか右向きにするかを設定します。

一般的に英語や日本語で書かれたウェブドキュメントは、左から右へ文字が並び、上から下へボックスが重なります。文字の方向は言語によって変わりますが、日本語であっても縦書きであれば右から左へと文字が並ぶ方向が変わります。

このように要素や内容が並べられるアルゴリズムをフローと言います。ブラウザは指定された言語と書字方向のモードを識別してレイアウトを行います。この判断を製作者側で意図した通りに行えるようにするのが、writing-modeの役目です。

横書きの書字方向を指定するにはdirectionプロパティを使います。指定できる値は2種類で、ltr(Left To Right)であれば左から右へ、rtl(Right To Left)であれば右から左へ表記されます。

writing-modeに指定できる値

horizontal-tb
テキストを水平に並べます。ltrの言語では左から右へ、rtlの言語では右から左へ配置されます。行が折り返されると、前の行の下に配置されます。
vertical-rl
テキストを垂直に並べます。ltrの言語では上から下へ流れ、次の行に折り返されると、前の行の左に配置されます。rtlの言語では下から上へ流れ、次の行に折り返されると、前の行の右に配置されます。
vertical-lr
テキストを垂直に並べます。ltrの言語では上から下へ流れ、次の行に折り返されると、前の行の右に配置されます。rtlの言語では下から上へ流れ、次の行に折り返されると、前の行の左に配置されます。
sideways-rl(β)
テキストを垂直に並べます。ltrの言語では下から上へ流れ、rtlの言語では上から下へ流れます。縦書きに対応した書体を含む全ての文字を右へ横倒しにします。
sideways-lr(β)
テキストを垂直に並べます。ltrの言語では上から下へ流れ、rtlの言語では下から上へ流れます。縦書きに対応した書体を含む全ての文字を左へ横倒しにします。

writing-modeの使い方とサンプルコード

writing-modeプロパティの構文は以下の通りです。


/* キーワードの値 */
writing-mode: horizontal-tb;
writing-mode: vertical-rl;
writing-mode: vertical-lr;
writing-mode: sideways-rl; /* (β) */
writing-mode: sideways-lr; /* (β) */

/* グローバルの値 */
writing-mode: inherit;
writing-mode: initial;
writing-mode: revert;
writing-mode: unset;

writing-modeの実例

それでは実際にwriting-modeプロパティの書き方を見ていきましょう。以下の例は、単純な構造のボックスに値の異なるwriting-modeを指定した場合の比較です。段落には改行を含むテキストが配置されています。これがどのように並ぶのかは、書字方向とフローによって決まります。


<div class="samp_box">
	<section id="wm_1">
		<h1>writing-mode: horizontal-tb;</h1>
		<p>あいうえお<br>かきくけこ<br>さしすせそ</p>
	</section>
	<section id="wm_2">
		<h1>writing-mode: vertical-rl;</h1>
		<p>あいうえお<br>かきくけこ<br>さしすせそ</p>
	</section>
	<section id="wm_3">
		<h1>writing-mode: vertical-lr;</h1>
		<p>あいうえお<br>かきくけこ<br>さしすせそ</p>
	</section>
</div>

.samp_box {
	overflow: auto;
	padding: 0 1rem 1rem;
	background-color: #eee;
}
.samp_box > section {
	overflow: auto;
	margin: 1rem 0 0;
	padding: 0 1rem 1rem;
	background-color: #fff;
}
section > h1 {
	margin: 1rem 0 0;
	font-size: 1rem;
}
section > p {
	margin: .5rem 0 0;
}
#wm_1 > p {
	writing-mode: horizontal-tb;
}
#wm_2 > p {
	writing-mode: vertical-rl;
}
#wm_3 > p {
	writing-mode: vertical-lr;
}

フレックス・ボックスのレイアウト

フレックス・ボックスでは、コンテナの中に並ぶアイテムのフローにも影響します。以下の例では、displayの値にflexを指定したリストに対して、値の異なるwriting-modeを付加した場合の比較です。

縦書きモードにした場合、アイテムは上から順に重なりますが、directionの値をrtlにすると下から上の順で重なります。


<div class="samp_box">
	<section id="wm_1">
		<h1>writing-mode: horizontal-tb;</h1>
		<ul>
			<li>1</li>
			<li>2</li>
			<li>3</li>
			<li>4</li>
		</ul>
	</section>
	<section id="wm_2">
		<h1>writing-mode: vertical-rl;</h1>
		<ul>
			<li>1</li>
			<li>2</li>
			<li>3</li>
			<li>4</li>
		</ul>
	</section>
	<section id="wm_3">
		<h1>writing-mode: vertical-lr;</h1>
		<ul>
			<li>1</li>
			<li>2</li>
			<li>3</li>
			<li>4</li>
		</ul>
	</section>
</div>

.samp_box {
	overflow: auto;
	padding: 0 1rem 1rem;
	background-color: #eee;
}
.samp_box > section {
	overflow: auto;
	margin: 1rem 0 0;
	padding: 0 1rem 1rem;
	background-color: #fff;
}
section > h1 {
	margin: 1rem 0 0;
	font-size: 1rem;
}
section > ul {
	display: flex;
	gap: 3px;
	width: 100%;
	margin: .5rem 0 0;
	padding: 0;
}
ul > li {
	flex: 1;
	padding: .3rem;
	border: 1px solid #999;
	list-style: none;
}
#wm_1 > ul {
	writing-mode: horizontal-tb;
}
#wm_2 > ul {
	writing-mode: vertical-rl;
}
#wm_3 > ul {
	writing-mode: vertical-lr;
}

小説のような日本語の縦書き文章を表現する

縦書きモードを使用すると、小説のような縦書きの文書をウェブで表現できます。もちろん、出版物の形式を厳密に再現しようとすると複雑なプロパティの指定が必要になりますが、最低限の仕組みであれば次のような記述で達成できます。

縦書きモードの文字の向きを指定する場合は、text-orientationを使用します。また、一文字分の空間に横並びの半角数字などを収めるには、text-combine-uprightを使用します。


<div class="vtext_box">
	<section>
		<h1>第一章</h1>
		<p>私はこの文書を<em>何も考えず</em>に書き始めた。言葉は言の葉と言われるように積み重ねることで意味を織り成す。それは時間の矢と同じで、先へ読み進めることでしか達成できない。</p>
		<p>もし去年の今ごろ、自分は何をしていたのだろうかと振り返れば、その思い出すという行為自体が時間の流れに乗っているのだ。</p>
		<p><em>あなたが</em>、と言われて、あなたがあなたを意識した時、あなたは時間から少しだけ自由になれる。</p>
		<p>さて、ここで少し考えてみよう。今あなたは時間を使って文章を読んでいる。読んでいる文章は単なる模様に過ぎないが、なぜそこから意味を読み取れるのだろうか。</p>
		<p><em>文字は情報を可視化したものだから</em>、と言い切ってしまえば話は簡単だが、情報が<em>それそのもの</em>を指していると、なぜ分かるのだろうか。このあたりは哲学の領域である。興味を持ったら探求してみると良いだろう。</p>
		<p>時間には空間が不可欠であるように、情報には認識が必要である。ならば、単に無意識的な時間を過ごすのではなく、空間の相互作用によって生まれるものが何か、突き止めようとする好奇心が情報の本質を理解することではないだろうか。</p>
	</section>
	<section>
		<h1>第二章</h1>
		<p>第二章は<em>ありません</em>。</p>
	</section>
</div>

.vtext_box {
	overflow: auto;
	width: 100%;
	padding: 1rem;
	background: #eee;
	line-height: 1.5;
	writing-mode: vertical-rl;
}
.vtext_box > section {
	overflow: auto;
	padding: 1rem 0 1rem 1rem;
	background: #fff;
	font-family: serif;
}
section > h1 {
	margin: 0 1rem 0 0;
	font-size: 1.5rem;
}
section > p {
	margin: 0 1rem 0 0;
	text-indent: 1em;
}
p > em {
	font-style: normal;
	text-emphasis: filled sesame;
}

writing-modeに関連するCSSプロパティ

文字揃え・段落の振る舞い
direction 文字表記の方向(左右)を指定する
hanging-punctuation 句読点、括弧、引用符などの禁則処理を指定する
letter-spacing 文字同士の間隔を指定する
line-break 句読点や記号などの禁則処理を指定する
line-height 行の高さを指定する
tab-size タブ(tab)文字の表示幅を指定する
unicode-bidi Unicodeのアルゴリズムを上書きして文字表記の方向を変更する
white-space 要素内のホワイトスペースの扱い方を指定する
word-break 要素の幅を超過するテキストの自動改行について指定する
word-spacing 単語同士の間隔を指定する
word-wrap インライン要素に対して単語の途中で改行処理を行うかどうかを指定する
writing-mode テキストの書字方向やブロックのフローを指定する
widows ブロックが区切られた場合に次の行の先頭に表示される内容の最小行数を設定する