
CSS writing-mode完全ガイド、縦書きと横書きを自在に操る方法
writing-modeとは? 基本構文と初期値

writing-modeプロパティは、テキストの行を水平方向に配置するか垂直方向に配置するか、そしてブロックと行がどの方向に進むかを設定する。主に日本語や中国語、韓国語など、縦書きが使われる言語で役立つプロパティだ。英語圏では、見出しをブロックテキストの中に縦に配置するような、美的な理由で使われることが多い。
基本的な構文
.element {
writing-mode: vertical-rl;
}writing-modeプロパティは、以下の5つのキーワード値を受け取る。
writing-mode: horizontal-tb | vertical-rl | vertical-lr | sideways-rl | sideways-lr;- 初期値: horizontal-tb
- 適用対象: テーブル行グループ、テーブル列グループ、テーブル行、テーブル列、ルビベースコンテナ、ルビ注釈コンテナを除くすべての要素
- 継承: あり
- アニメーションの種類: アニメーション不可
各値は2つの部分から成り立っている。最初の部分はテキストが水平(horizontal)か垂直(vertical)かを示し、2番目の部分は行とブロックが進む方向を示す。tbは上から下(top-to-bottom)、rlは右から左(right-to-left)、lrは左から右(left-to-right)を意味する。
初期値と継承のポイント
writing-modeの初期値はhorizontal-tbだ。つまり、明示的に指定しない限り、Webページのテキストは水平方向に左から右へ流れ、行は上から下へ積み重なる。このプロパティは継承されるため、親要素に設定すれば子要素にも自動的に適用される。ただし、table関連の要素やrubyコンテナには直接適用されない点に注意が必要だ。
プロパティがアニメーション不可であることも覚えておきたい。writing-modeを動的に切り替えると、レイアウト全体が再計算されるため、スムーズなトランジションは期待できない。状態の切り替えは即座に行われる。
各値の詳細と使用例

writing-modeプロパティには5つの値が存在する。それぞれの挙動を詳しく見ていこう。
horizontal-tb(デフォルト)
テキストは水平方向に左から右へ流れる。行とブロックは上から下へ進行する。これがWebページの標準的な表示だ。
.default-text {
writing-mode: horizontal-tb;
}この値は、特に指定しなくてもブラウザが適用する初期値であるため、通常は明示的に書く必要はない。ただし、上位の要素で別のwriting-modeが設定されている場合に、意図的に水平書きに戻す目的で使われることがある。
vertical-rl(縦書き右から左)
テキストは垂直方向に配置され、行やブロックは右から左へ進む。新しい行は前の行の左側に配置される。主に日本語の縦書きで使われる値だ。
.vertical-text {
writing-mode: vertical-rl;
}上のデモでは、右側のボックスから左へテキストが進むvertical-rlの特徴が分かる。日本の書籍や新聞の縦書きと同じ方向だ。
vertical-lr(縦書き左から右)
テキストは垂直方向に配置されるが、行は左から右へ進む。新しい行は前の行の右側に追加される。モンゴル語の縦書きなどで使われる。
.vertical-left-right {
writing-mode: vertical-lr;
}vertical-rlと比べると、左側の行から読み始め、徐々に右へ進む点が異なる。日本ではあまり馴染みがないが、国際的なWebサイトを構築する際に考慮すべき書字方向だ。
sideways-rl と sideways-lr
sideways-rlとsideways-lrは、テキストを縦書きにしつつ、文字の方向を水平書きの慣習に沿って回転させる。sideways-rlでは文字が右を向き、sideways-lrでは左を向く。
これらの値は、主に表の見出しや、狭いスペースに横向きの文字を縦に並べたい場合に使われる。ただし、ブラウザの実装状況にばらつきがあり、すべての環境で意図した表示になるとは限らない。使用前にブラウザの対応状況を確認する必要がある。
論理軸とCSSレイアウトの関係

writing-modeプロパティは、単にテキストの向きを変えるだけではない。より根本的に、CSSがコンテンツをレイアウトする際に使う「ブロック方向」と「インライン方向」の軸を確立する。
インライン軸とブロック軸
インライン軸は、行の中でコンテンツが流れる方向だ。水平書きでは横方向、縦書きでは縦方向になる。ブロック軸は、ブロックや行が積み重なる方向で、水平書きでは縦方向、縦書きでは横方向になる。
行が積み重なる
↓
テキストの流れ
↓
writing-modeが変わると、これらの軸の物理的な方向が入れ替わる。デフォルトのhorizontal-tbではインライン軸は水平、ブロック軸は垂直だが、vertical-rlではインライン軸が垂直に、ブロック軸が水平になる。
論理プロパティの活用
CSSのモダンレイアウトであるFlexboxやGrid、位置調整のプロパティは、この論理軸の考え方に基づいている。物理的な方向(top, right, bottom, left)に縛られず、start, end, block, inlineといった論理的方向で記述するため、writing-modeが変わってもレイアウトが適応できる。
.element {
inline-size: 20rem;
block-size: 10rem;
margin-inline-start: 1rem;
padding-block-end: 0.5rem;
}inline-sizeは、インライン軸に沿った要素のサイズ(横書きではwidth、縦書きではheightに相当)block-sizeは、ブロック軸に沿ったサイズ(横書きではheight、縦書きではwidthに相当)margin-inline-startは、インライン軸の開始側のマージン(横書きではmargin-left、縦書きではmargin-topに相当)padding-block-endは、ブロック軸の終了側のパディング(横書きではpadding-bottom、縦書きではpadding-leftに相当)
これらの論理プロパティを使うことで、writing-modeを変更してもCSSを書き直す必要がなくなる。複数言語に対応するWebサイトを構築する際に、特に強力な武器となる。
FlexboxとGridへの影響
Flexboxでは、flex-direction: row がインライン軸に沿ってアイテムを配置する。writing-modeがhorizontal-tbなら横並び、vertical-rlなら縦並びになる。同様に、flex-direction: column はブロック軸に沿って積み重ねる。
Gridもwriting-modeに従う。グリッドの行と列は、物理的な上下左右に固定されているわけではなく、インライン軸とブロック軸に応じて自動的に方向が変わる。そのため、縦書きレイアウトでグリッドを使用する際も、特別な指定は不要だ。
位置調整プロパティ(align-items や justify-items など)も同様に、ブロック軸とインライン軸を基準に動作する。このモデルを理解しておけば、縦書きレイアウトを作成しない場合でも、FlexboxやGridの挙動をより深く理解できる。物理的な方向に依存しない、柔軟なレイアウト設計が可能になる。
実践的なデモとブラウザ対応

writing-modeを使いこなすには、実際の挙動を確認するのが一番だ。ここでは言語や方向の設定を切り替えられるデモを用意した。ブラウザの対応状況も合わせて解説する。
インタラクティブなデモ
以下のデモでは、ドロップダウンから言語やwriting-modeの値、テキストの方向(directionプロパティ)を変更できる。テキストの表示だけでなく、コンテナとインライン・ブロック軸のインジケーターがどのように変化するかを観察してほしい。
言語セレクターは各スクリプトの典型的な値を設定するが、自由に上書きして実験できる。writing-modeがテキストの向きだけでなく、コンテナ全体とその内容物のフローにどう影響するかを確認しよう。
writing-modeを変更すると、単に文字の向きが変わるだけではない。テキストのフロー全体、ブロックの進行方向、インライン要素の並び方までもが再構成される。縦書きを導入する際は、レイアウト全体への影響を考慮する必要がある。
ブラウザの対応状況
writing-modeプロパティは、CSS Writing Modes Level 4 仕様で定義されており、主要なモダンブラウザで広く利用可能だ。Chrome、Firefox、Safari、Edgeのいずれも基本的な値をサポートしている。
ただし、sideways-rl と sideways-lr は実装状況にやや差がある。Firefoxではサポートされているが、Chrome系では部分的または未サポートの場合がある。使用する際は、Can I use などで最新の対応状況を確認することをおすすめする。
関連プロパティと注意点

writing-modeと密接に関連するプロパティがいくつかある。縦書きレイアウトを正確に制御するために、これらも合わせて理解しておきたい。
direction
.element { direction: rtl; }テキストの書字方向(左から右か、右から左か)を指定する。writing-modeがhorizontal-tbの場合、direction: rtl を指定すると、テキストは右から左へ流れる。アラビア語やヘブライ語など、右横書きの言語で使用される。writing-modeと組み合わせることで、より多様な言語に対応できる。
text-orientation
.element { text-orientation: mixed; }縦書きモードのときに、文字の向きを制御するプロパティだ。mixed(横文字は横向き、縦文字は縦向き)、upright(すべての文字を縦向き)、sideways(すべての文字を横向きに回転)などの値を取る。縦書きの中に英数字が混ざる場合の見た目を調整するのに役立つ。
unicode-bidi
.element { unicode-bidi: embed; }双方向テキスト(右から左と左から右の文字が混在する場合)の埋め込みレベルを制御する。directionプロパティの効果を適切に反映させるために、一緒に使われることが多い。
text-combine-upright
span { text-combine-upright: all; }縦書きの中で、複数の文字(主に2桁の数字など)を1文字分のスペースに水平に組み合わせて表示する。縦中横(たてちゅうよこ)と呼ばれる組版技法を実現するために使われる。
この記事のポイント
- writing-modeプロパティは、テキストの水平・垂直配置とブロックの進行方向を制御する
- 5つのキーワード値(horizontal-tb, vertical-rl, vertical-lr, sideways-rl, sideways-lr)があり、それぞれ異なる書字方向を実現する
- インライン軸とブロック軸の概念を理解することで、FlexboxやGridといったモダンレイアウトをより深く扱える
- 論理プロパティ(inline-size, block-size, margin-inline-start など)を使用すると、writing-modeの変更に強い柔軟なCSSを書ける
- 縦書きレイアウトは、日本語などの言語対応だけでなく、デザインのアクセントとしても活用できる

・ 複数業界における17年間のデジタルビジネス開発経験
・ ウェブサイト開発のためのHTML、PHP、CSS、JavaScript等の実用的知識
・ 15ヶ国語対応の多言語SaaSの開発経験
・ 17年間にも及ぶ、Eコマース長期運営経験
・ 幅広い業界でのSEO最適化の豊富な経験

CSS translateY()の基本と使い方、垂直移動をマスター
translateY() の基本構文と引数

translateY() は CSS の transform プロパティで使用する関数の一つだ。指定した値の分だけ要素を垂直方向に移動させる。正の値なら下へ、負の値なら上へ動く。
構文の基本
構文は極めてシンプルだ。
transform: translateY(値);値には長さ(px, em, rem など)またはパーセンテージを指定できる。パーセンテージは要素自身の高さを基準とする。例えば高さ 100px の要素に translateY(50%) を指定すると、50px 下に移動する。
なお、親要素の高さや余白には一切影響しない。あくまで視覚的な位置だけが変わる点が重要な特徴だ。
length と percentage の使い分け
length(px, rem など)は固定量の移動が必要な場合に使う。一方、percentage は要素のサイズに応じて相対的に位置を変えたいときに便利だ。たとえば、高さが可変するコンテナ内で要素を半分だけ上にずらすには translateY(-50%) と書く。この手法はモーダルやツールチップの中央揃えでもよく使われる。
アニメーションへの応用、カードのスライドイン

translateY() は CSS アニメーションやトランジションと組み合わせることで、自然な動きを生み出せる。特に「下からスライドイン」「フェードインしながら上昇」といった演出に適している。
カードの表示アニメーション
たとえば、ダッシュボードに統計カードを並べる場合を考えてみよう。初期状態では各カードを少し下にずらし、透明度を 0 にしておく。ページが読み込まれたタイミングやスクロールに合わせて translateY(0) かつ opacity: 1 へトランジションさせる。
.stat-card {
opacity: 0;
transform: translateY(50px);
transition: opacity 0.8s ease-in, transform 0.8s ease-in;
}
.dashboard.active .stat-card {
opacity: 1;
transform: translateY(0);
}この変化が実際は 0.8 秒かけて連続的に行われる。ユーザーは要素が「下から浮き上がってくる」ように感じる。
ホバー時のマイクロインタラクション
表示されたカードにマウスを重ねたとき、ほんの少し上へ移動させる演出もよく使われる。translateY() に負の値を指定すれば良い。
.dashboard.active .stat-card:hover {
transform: translateY(-8px);
}このわずかな動きが、クリック可能な要素であることを直感的に伝える。影(box-shadow)の変化と組み合わせると、よりリッチな表現になる。
フォームラベルの移動アニメーション

translateY() は UI コンポーネントの動きを設計する上でも重宝する。代表例が、入力フィールドのラベルがフォーカス時に上へ移動する「フローティングラベル」パターンだ。
ラベルの初期配置
まず、label 要素を input フィールドの内側に絶対配置で重ねる。ポインターイベントを無効化しておけば、ラベルをクリックしても input にフォーカスが当たる。
label {
position: absolute;
left: 15px;
top: 15px;
pointer-events: none;
transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}フォーカス時の移動
input にフォーカスが当たったとき、もしくはプレースホルダーが表示されていない(入力済み)ときに、ラベルを translateY(-32px) で上へ移動させる。同時に少し縮小すると、より洗練された動きになる。
input:focus ~ label,
input:not(:placeholder-shown) ~ label {
transform: translateY(-32px) scale(0.8);
color: #6200ee;
font-weight: bold;
}このアニメーションは実際には約 0.25 秒でスムーズに行われる。ラベルが単に上に動くだけでなく、縮小と色の変化が加わることで、UI に統一感が生まれる。
translateY() の特性、他の要素に影響しない

transform 系の関数全般に言えることだが、translateY() はドキュメントフローを一切変更しない。つまり、要素を移動させても周囲の要素は元の位置を保ったままになる。
ドキュメントフローへの影響
例えば、3つのブロックが縦に並んでいるとする。中央のブロックに translateY(40px) を適用しても、上下のブロックはピクリとも動かない。あくまで中央のブロックの「描画位置」だけが変わる。
margin との違い
似たような位置調整として margin-top がある。しかし margin は要素自体の「占有領域」を変化させるため、後続の要素が押し出される。レイアウト全体に影響を与えたくない場合、translateY() のほうが安全だ。
/* 非推奨: レイアウトシフトを起こす */
.element {
margin-top: 30px;
}
/* 推奨: 描画位置だけを変える */
.element {
transform: translateY(30px);
}また、translateY() は GPU による合成処理が行われるため、アニメーションのパフォーマンス面でも優れる。リフローやリペイントが発生しないからだ。頻繁に動かす要素には積極的に使いたい。
ポインター擬似クラスでの問題と解決策

translateY() を :hover に直接指定すると、意図しないちらつきを起こすことがある。CSS-Tricks の記事でも指摘されている点だ。
ちらつきが起きる仕組み
ホバー時に要素を大きく移動させると、マウスカーソルが要素から外れてしまう。すると :hover 状態が解除されて要素が元の位置に戻り、再びカーソルが要素に重なってまた移動する……という無限ループが発生する。
親要素で包む解決策
最も簡単な対策は、移動させたい要素を親コンテナでラップし、:hover 擬似クラスを親に適用することだ。これでホバー領域が親のサイズで固定され、子要素がどこに移動してもカーソルが外れにくくなる。
.card-container:hover .card {
transform: translateY(-12px);
}この書き方は、ホバーでカードが浮き上がる演出など、あらゆる translateY() アニメーションに応用できる。親要素のサイズに余裕を持たせておけば、より大きな変位にも対応可能だ。
この記事のポイント
- translateY() は要素を垂直方向に移動させる。正の値で下、負の値で上。
- パーセンテージ指定は要素自身の高さが基準。中央配置などに便利。
- アニメーションでは opacity と組み合わせ、スライドインに使える。
- フォームラベルの浮上アニメーションは translateY(-32px) と scale(0.8) で実装。
- ドキュメントフローを壊さないため、margin よりパフォーマンスが良い。
- :hover のちらつきは親要素に擬似クラスを付ければ解消する。

・ 複数業界における17年間のデジタルビジネス開発経験
・ ウェブサイト開発のためのHTML、PHP、CSS、JavaScript等の実用的知識
・ 15ヶ国語対応の多言語SaaSの開発経験
・ 17年間にも及ぶ、Eコマース長期運営経験
・ 幅広い業界でのSEO最適化の豊富な経験
