CSSで縦書きテキストをど真ん中に!ズレ・英数字・Safari問題の完全解決ガイド

css-vertical-text-center css
記事内に広告が含まれています。

CSSで縦書きテキストを中央に配置しようとしたとき、「上下の中央が合わない」「左右の中心から微妙にずれる」「Flexboxで中央揃えしたのに位置がずれる」といった悩みを経験された方は多いのではないでしょうか。特に writing-mode: vertical-rl; を使った縦書きでは、ブラウザごとの挙動の違いや、英数字・句読点の向き、文字間隔の扱いなど、横書きにはない独特のクセが存在します。そのため、Figmaやデザインカンプ通りに“ど真ん中”へ配置したいのに再現できず、実装に時間を取られてしまうケースが少なくありません。

さらに、縦書きテキストは各ブラウザ間(Chrome / Safari / Firefox / iOS Safari)で処理の仕方が異なることもあり、コード上では正しく書いているのに、実機ではズレて見える問題も発生します。また、英数字(特に「1」や「0」)が横倒しになったり、句読点だけ位置がズレたりと、細かい部分の調整も必要になります。こうした“縦書き特有の小さなズレ”を一つずつ直していく作業は非常に煩雑で、最適なCSSプロパティの組み合わせを知らないと余計に手間がかかってしまいます。

この記事では、CSSだけで縦書きテキストを上下左右の中央へ正確に配置する方法を、初心者にも分かりやすいステップで解説します。Flexbox・Grid・positionのそれぞれのメリット・デメリットを比較しながら、最も安定した中央揃えの方法を実例付きで紹介。また、文字のズレ・向き・句読点の問題や、iOS Safariで崩れるケースへの対処法もまとめているため、実務でそのまま使える内容になっています。

「縦書きの中央揃え」が難しいと感じている方でも、この記事を読み終える頃には、どの状況でも迷わず実装できるようになるはずです。和風デザイン・雑誌風デザイン・縦書きのバナーなど、さまざまなWebデザインにも応用できるため、是非参考にしてみてください。

この記事を読んでわかること

  • writing-mode を使った縦書きテキストの正しい設定方法
  • 英数字・句読点・数字が横倒しになる問題の解決方法
  • Flexbox・Grid・position を使った中央揃えの実装と比較
  • 縦書き時の文字ズレ(上下・左右)の原因と調整ポイント
  • iOS Safari・Chrome・Firefox などでの表示ズレ対策
  • デザインカンプ通りに縦書きを配置するためのプロパティ設定とレイアウト設計
  • 実務でそのまま使える縦書き中央揃えのCSSスニペット
格安ドメイン取得サービス─ムームードメイン─

CSSで縦書きテキストを中央揃えする基本

CSSで縦書きテキストを実装する際、横書きとは異なる独特の挙動や注意点があります。このセクションでは、縦書きの基本設定から、実務でよく遭遇する文字の向きやレイアウトのズレまで、具体的なコード例とともに解説します。

writing-mode: vertical-rl;で縦書き化する基本コードと注意点

縦書きを実現するにはwriting-modeプロパティを使用します。最も一般的なのがvertical-rlで、テキストが右から左へ流れる縦書きになります。

writing-mode - CSS | MDN
writing-mode は CSS のプロパティで、テキストの行のレイアウトを横書きにするか縦書きにするか、ブロックのフロー方向を左向きにするか右向きにするかを設定します。文書全体に設定する場合は、ルート要素 (HTML 文書の場合は html 要素) に設定してください。
.vertical-text {
  writing-mode: vertical-rl;
  /* テキストの流れ:右→左の縦書き */
}

実践的なサンプルコード:

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    .vertical-container {
      writing-mode: vertical-rl;
      width: 300px;
      height: 400px;
      border: 2px solid #333;
      padding: 20px;
      background-color: #f9f9f9;
    }
  </style>
</head>
<body>
  <div class="vertical-container">
    これは縦書きのテキストです。日本語の文章を自然に縦書きで表示できます。
  </div>
</body>
</html>

注意すべきポイント:

  • vertical-rl:右から左へ流れる縦書き(日本語の一般的な縦書き)
  • vertical-lr:左から右へ流れる縦書き(モンゴル文字などで使用)
  • horizontal-tb:通常の横書き(デフォルト値)

ブラウザ互換性:

  • Chrome 48+、Firefox 43+、Safari 9+、Edge 12+で完全サポート
  • IE11ではms-writing-mode: tb-rl;のベンダープレフィックスが必要な場合あり

親要素にwriting-modeを指定すると、子要素にも継承されます。部分的に横書きに戻したい場合は、該当要素にwriting-mode: horizontal-tb;を明示的に指定しましょう。

月額99円から。容量最大1TB!ブログ作成におすすめのWordPressテーマ「Cocoon」も簡単インストール

英数字・句読点が横向きになる問題を解決するtext-orientation: upright;

縦書きにした際、英数字やアルファベットがデフォルトで横向き(90度回転した状態)になってしまう問題があります。これを解決するのがtext-orientationプロパティです。

text-orientation - CSS | MDN
text-orientation は CSS のプロパティで、行内のテキストの向きを設定します。このプロパティは縦書きのテキスト (writing-mode が horizontal-tb 以外の場合) でのみ効果があります。これは縦書きを使用する言語の表示を制御したり、縦書きの表見出しを作成したりするのに有用です。
.vertical-text-upright {
  writing-mode: vertical-rl;
  text-orientation: upright;
  /* すべての文字を正立(縦向き)にする */
}

text-orientationの値と挙動:

<style>
  .example-mixed {
    writing-mode: vertical-rl;
    text-orientation: mixed; /* デフォルト:日本語は縦、英数字は横 */
    border: 1px solid #ccc;
    padding: 15px;
    margin: 10px;
    height: 200px;
  }

  .example-upright {
    writing-mode: vertical-rl;
    text-orientation: upright; /* すべて縦向き */
    border: 1px solid #ccc;
    padding: 15px;
    margin: 10px;
    height: 200px;
  }

  .example-sideways {
    writing-mode: vertical-rl;
    text-orientation: sideways; /* すべて横向き */
    border: 1px solid #ccc;
    padding: 15px;
    margin: 10px;
    height: 200px;
  }
</style>

<div class="example-mixed">
  mixed: 日本語とABC123の表示
</div>
<div class="example-upright">
  upright: 日本語とABC123の表示
</div>
<div class="example-sideways">
  sideways: 日本語とABC123の表示
</div>

各値の使い分け:

  • mixed(デフォルト):日本語は縦向き、英数字は横向き(90度回転)
  • upright:すべての文字を正立させる。英数字も縦向きになるが、読みづらい場合がある
  • sideways:すべて横向き(90度回転)にする

実際の表示

See the Pen css-vertical-text-center-01 by watashi-xyz (@watashi-xyz) on CodePen.

実務での推奨設定:

.vertical-optimized {
  writing-mode: vertical-rl;
  text-orientation: mixed; /* 日本語テキストが主体の場合 */
  /* または */
  text-orientation: upright; /* 英数字を含む短いタイトルや見出しの場合 */
}

ブラウザ互換性の注意:

  • Safari(特にiOS)ではtext-orientation: sideways;が正しく動作しない場合があります
  • Firefoxではsideways-rightという値もサポートされていますが、標準仕様からは削除される予定です
専門的な知識不要!誰でも簡単に使える『XWRITE(エックスライト)』

縦書き特有のズレを防ぐためのletter-spacingとline-heightの最適値

縦書きでは、文字間隔(letter-spacing)と行間(line-height)の調整が、横書き以上に重要になります。適切な値を設定しないと、文字が詰まりすぎたり、逆に間延びしたりします。

基本的な調整コード:

.vertical-spacing {
  writing-mode: vertical-rl;
  letter-spacing: 0.1em; /* 文字間隔:やや広めが読みやすい */
  line-height: 2; /* 行間:縦書きでは横方向の間隔になる */
  font-size: 16px;
}

実践的なサンプル:

<style>
.container {
  display: flex;
  justify-content: center;
  gap: 20px;
}

.vertical-default {
  writing-mode: vertical-rl;
  width: auto;
  height: 300px;
  border: 1px solid #999;
  padding: 20px;
}

.vertical-optimized {
  writing-mode: vertical-rl;
  letter-spacing: 0.08em; /* 適度な文字間隔 */
  line-height: 1.8; /* 読みやすい行間 */
  width: auto;
  height: 300px;
  border: 1px solid #999;
  padding: 20px;
}

.vertical-title {
  writing-mode: vertical-rl;
  letter-spacing: 0.15em; /* タイトルは広めに */
  line-height: 2.5; /* 余白を持たせる */
  font-size: 24px;
  font-weight: bold;
  width: auto;
  height: 300px;
  border: 1px solid #999;
  padding: 20px;
}

</style>

<div class="container">
  <div class="vertical-default">
    【デフォルト】吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。
  </div>
  <div class="vertical-optimized">
    【最適化済み】吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。
  </div>
  <div class="vertical-title">
    縦書きタイトル例
  </div>
</div>

実際の表示

See the Pen css-vertical-text-center-02 by watashi-xyz (@watashi-xyz) on CodePen.

推奨値の目安:

用途letter-spacingline-height理由
本文テキスト0.05em〜0.1em1.8〜2.0読みやすさと視認性のバランス
タイトル・見出し0.1em〜0.2em2.0〜2.5ゆとりを持たせて印象的に
短文・キャッチコピー0.15em〜0.3em2.5〜3.0デザイン性を重視

トラブルシューティング:

/* 問題:文字が密集して読みづらい */
.too-tight {
  writing-mode: vertical-rl;
  letter-spacing: 0; /* NG */
  line-height: 1; /* NG */
}

/* 解決:適度な間隔を確保 */
.proper-spacing {
  writing-mode: vertical-rl;
  letter-spacing: 0.08em; /* OK */
  line-height: 1.8; /* OK */
}

/* 問題:行が重なって見える(特にiOS Safari) */
.overlapping {
  writing-mode: vertical-rl;
  line-height: 1.2; /* 狭すぎる */
}

/* 解決:line-heightを大きめに */
.fixed-spacing {
  writing-mode: vertical-rl;
  line-height: 2; /* 安全な値 */
  -webkit-text-size-adjust: 100%; /* iOS対策 */
}

レスポンシブ対応のTips:

.vertical-responsive {
  writing-mode: vertical-rl;
  letter-spacing: 0.08em;
  line-height: 1.8;
}

/* スマホでは横書きに切り替える場合 */
@media (max-width: 768px) {
  .vertical-responsive {
    writing-mode: horizontal-tb;
    letter-spacing: 0.05em; /* 横書きでは狭めに */
    line-height: 1.6; /* 横書きの標準値 */
  }
}

ブラウザ別の注意点:

  • iOS Safariline-heightが小さいと文字が重なる場合があるため、最低1.8以上を推奨
  • Firefoxletter-spacingに負の値を指定すると、一部の文字が欠ける可能性がある
  • Chrome/Edge:比較的安定しているが、text-orientation: upright;との併用時はletter-spacingを微調整する必要がある場合がある
新世代レンタルサーバー『シンレンタルサーバー』

縦書きテキストを上下左右のど真ん中に配置する方法:Flexbox・Grid・positionの比較

縦書きテキストを画面やコンテナの中央に配置する方法は複数ありますが、それぞれに特徴とメリット・デメリットがあります。このセクションでは、実務でよく使われる3つの手法を比較し、状況に応じた最適な選択肢を提示します。

Flexboxで中央揃えするdisplay: flex; align-items: center; justify-content: center;

Flexboxは最もシンプルで直感的に中央揃えを実現できる方法です。縦書きテキストでも横書きと同じ感覚で使えるため、初心者にもおすすめです。

基本的な実装コード:

.flex-center-container {
  display: flex;
  align-items: center; /* 垂直方向の中央揃え */
  justify-content: center; /* 水平方向の中央揃え */
  width: 100vw;
  height: 100vh;
  background-color: #f0f0f0;
}

.vertical-text {
  writing-mode: vertical-rl;
  font-size: 24px;
  letter-spacing: 0.1em;
  line-height: 2;
}

実践的なサンプルコード:

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    .flex-center-container {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 100vw;
      height: 100vh;
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    }

    .vertical-text {
      writing-mode: vertical-rl;
      text-orientation: mixed;
      font-size: 28px;
      letter-spacing: 0.12em;
      line-height: 2.2;
      color: #ffffff;
      padding: 30px;
      background-color: rgba(0, 0, 0, 0.3);
      border-radius: 10px;
      box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
    }
  </style>
</head>
<body>
  <div class="flex-center-container">
    <p class="vertical-text">
      縦書きテキストを<br>
      完全に中央配置
    </p>
  </div>
</body>
</html>

複数の縦書きテキストを配置する場合:

<style>
  .flex-multi-container {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 40px; /* テキスト間の間隔 */
    width: 100vw;
    height: 100vh;
    background-color: #2c3e50;
  }

  .vertical-item {
    writing-mode: vertical-rl;
    font-size: 20px;
    letter-spacing: 0.1em;
    line-height: 2;
    color: #ecf0f1;
    padding: 20px;
    border: 2px solid #3498db;
  }
</style>

<div class="flex-multi-container">
  <div class="vertical-item">第一段落</div>
  <div class="vertical-item">第二段落</div>
  <div class="vertical-item">第三段落</div>
</div>

実際の表示

See the Pen css-vertical-text-center-03 by watashi-xyz (@watashi-xyz) on CodePen.

Flexboxのメリット:

  • コードがシンプルで理解しやすい
  • レスポンシブ対応が容易
  • 複数要素の配置も柔軟に対応可能
  • ブラウザ互換性が高い(IE11でも動作)

Flexboxのデメリット:

  • 非常に細かい位置調整が必要な場合はやや不向き
  • 子要素のサイズが親要素を超える場合の制御が複雑になる

ブラウザ互換性:

  • Chrome 29+、Firefox 28+、Safari 9+、Edge 12+で完全サポート
  • IE11ではms-flexboxのプレフィックスが必要な場合あり

レスポンシブ対応のTips:

.flex-responsive {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 20px; /* スマホでの余白確保 */
}

.vertical-text-responsive {
  writing-mode: vertical-rl;
  font-size: clamp(18px, 3vw, 28px); /* レスポンシブなフォントサイズ */
  letter-spacing: 0.1em;
  line-height: 2;
  max-height: 80vh; /* 画面からはみ出さないように */
  overflow: auto; /* 必要に応じてスクロール */
}

/* タブレット以下では横書きに切り替える例 */
@media (max-width: 768px) {
  .vertical-text-responsive {
    writing-mode: horizontal-tb;
    text-align: center;
  }
}
現役エンジニアのパーソナルメンターからマンツーマンで学べるテックアカデミー

Gridで中央揃えするdisplay: grid; place-items: center;

CSS Gridを使った中央揃えは、最も簡潔なコードで実現できる現代的な手法です。place-items: center;一行で水平・垂直の中央揃えが完了します。

基本的な実装コード:

.grid-center-container {
  display: grid;
  place-items: center; /* align-items と justify-items の両方を center に設定 */
  width: 100vw;
  height: 100vh;
  background-color: #ecf0f1;
}

.vertical-text {
  writing-mode: vertical-rl;
  font-size: 24px;
  letter-spacing: 0.1em;
  line-height: 2;
}

実践的なサンプルコード:

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    .grid-center-container {
      display: grid;
      place-items: center;
      width: 100vw;
      height: 100vh;
      background: linear-gradient(to right, #00b4db, #0083b0);
    }

    .vertical-text {
      writing-mode: vertical-rl;
      text-orientation: mixed;
      font-size: 32px;
      letter-spacing: 0.15em;
      line-height: 2.5;
      color: #ffffff;
      padding: 40px;
      background-color: rgba(255, 255, 255, 0.1);
      backdrop-filter: blur(10px);
      border: 2px solid rgba(255, 255, 255, 0.3);
      border-radius: 15px;
    }
  </style>
</head>
<body>
  <div class="grid-center-container">
    <h1 class="vertical-text">
      CSS Grid で<br>
      縦書き中央配置
    </h1>
  </div>
</body>
</html>

複雑なレイアウトの例(グリッドレイアウト内で中央配置):

<style>
  .grid-layout {
    display: grid;
    grid-template-columns: 1fr 2fr 1fr;
    grid-template-rows: 1fr 2fr 1fr;
    width: 100vw;
    height: 100vh;
    gap: 20px;
    padding: 20px;
    background-color: #34495e;
  }

  .center-cell {
    grid-column: 2 / 3;
    grid-row: 2 / 3;
    display: grid;
    place-items: center; /* セル内で中央配置 */
    background-color: #2ecc71;
    border-radius: 10px;
  }

  .vertical-content {
    writing-mode: vertical-rl;
    font-size: 24px;
    letter-spacing: 0.1em;
    line-height: 2;
    color: #ffffff;
  }
</style>

<div class="grid-layout">
  <div class="center-cell">
    <p class="vertical-content">
      グリッド内の<br>
      中央セルに配置
    </p>
  </div>
</div>

実際の表示

See the Pen css-vertical-text-center-04 by watashi-xyz (@watashi-xyz) on CodePen.

place-itemsの詳細解説:

/* place-items は以下の省略形 */
.grid-center {
  display: grid;
  place-items: center;
  /* ↑ これは以下と同じ */
  /* align-items: center; */
  /* justify-items: center; */
}

/* 個別に制御する場合 */
.grid-custom {
  display: grid;
  align-items: start; /* 垂直方向:上揃え */
  justify-items: center; /* 水平方向:中央揃え */
}

Gridのメリット:

  • コードが非常に簡潔(place-items: center;一行で完結)
  • 複雑なレイアウトにも対応しやすい
  • 縦横比を保ちながら中央配置が可能
  • 複数要素のグリッド配置が直感的

Gridのデメリット:

  • IE11では完全にサポートされていない(ms-gridのプレフィックスが必要で挙動も異なる)
  • 古いブラウザをサポートする必要がある場合はFlexboxが安全

ブラウザ互換性:

  • Chrome 57+、Firefox 52+、Safari 10.1+、Edge 16+で完全サポート
  • IE11ではdisplay: -ms-grid;と個別プロパティを使用する必要がある

レスポンシブ対応の実例:

.grid-responsive-container {
  display: grid;
  place-items: center;
  min-height: 100vh;
  padding: 20px;
  background-color: #1abc9c;
}

.vertical-grid-text {
  writing-mode: vertical-rl;
  font-size: clamp(20px, 4vw, 36px);
  letter-spacing: 0.12em;
  line-height: 2.2;
  max-height: 85vh;
  overflow-y: auto;
  padding: 30px;
  background-color: rgba(255, 255, 255, 0.9);
  border-radius: 12px;
}

/* モバイルでは横書きに変更 */
@media (max-width: 600px) {
  .vertical-grid-text {
    writing-mode: horizontal-tb;
    max-height: none;
    max-width: 90vw;
  }
}

コストパフォーマンスに優れた高性能なレンタルサーバー

【Hostinger】

微妙なズレを調整するposition: absolute; transform: translate(-50%, -50%)の実例

positiontransformを組み合わせた手法は、ピクセル単位での細かい位置調整が可能で、デザインの精度が求められる場面で威力を発揮します。

基本的な実装コード:

.position-center-container {
  position: relative;
  width: 100vw;
  height: 100vh;
  background-color: #95a5a6;
}

.vertical-text-absolute {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  writing-mode: vertical-rl;
  font-size: 24px;
  letter-spacing: 0.1em;
  line-height: 2;
}

実践的なサンプルコード:

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    .position-center-container {
      position: relative;
      width: 100vw;
      height: 100vh;
      background: radial-gradient(circle at center, #ee7752, #e73c7e, #23a6d5);
      overflow: hidden;
    }

    .vertical-text-absolute {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      writing-mode: vertical-rl;
      text-orientation: mixed;
      font-size: 28px;
      letter-spacing: 0.12em;
      line-height: 2.3;
      color: #ffffff;
      padding: 35px;
      background-color: rgba(0, 0, 0, 0.5);
      border-radius: 12px;
      box-shadow: 0 15px 40px rgba(0, 0, 0, 0.4);
    }
  </style>
</head>
<body>
  <div class="position-center-container">
    <p class="vertical-text-absolute">
      position と transform で<br>
      完全中央配置
    </p>
  </div>
</body>
</html>

微調整が必要な場合の実例:

<style>
  .fine-tuned-container {
    position: relative;
    width: 800px;
    height: 600px;
    margin: 50px auto;
    background-color: #34495e;
    border: 3px solid #2c3e50;
  }

  .vertical-text-adjusted {
    position: absolute;
    top: 50%;
    left: 50%;
    /* 基本の中央配置 */
    transform: translate(-50%, -50%);
    writing-mode: vertical-rl;
    font-size: 24px;
    letter-spacing: 0.1em;
    line-height: 2;
    color: #ecf0f1;
  }

  /* 特定のブラウザやフォントで微妙にズレる場合の調整 */
  .vertical-text-fine-tuned {
    position: absolute;
    top: 50%;
    left: 50%;
    /* 微調整:右に2px、下に3px移動 */
    transform: translate(calc(-50% + 2px), calc(-50% + 3px));
    writing-mode: vertical-rl;
    font-size: 24px;
    letter-spacing: 0.1em;
    line-height: 2;
    color: #3498db;
  }

  /* iOS Safariでのズレ対策 */
  @supports (-webkit-touch-callout: none) {
    .vertical-text-ios-fix {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      -webkit-transform: translate(-50%, -50%); /* ベンダープレフィックス */
      writing-mode: vertical-rl;
      /* iOS特有のズレを補正 */
      margin-left: -1px;
      margin-top: -1px;
    }
  }
</style>

<div class="fine-tuned-container">
  <p class="vertical-text-adjusted">通常の中央配置</p>
</div>

<div class="fine-tuned-container">
  <p class="vertical-text-fine-tuned">微調整済み</p>
</div>

複数要素を重ねて配置する実例:

<style>
  .layered-container {
    position: relative;
    width: 100vw;
    height: 100vh;
    background: linear-gradient(45deg, #000428, #004e92);
  }

  .vertical-layer-back {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    writing-mode: vertical-rl;
    font-size: 80px;
    letter-spacing: 0.2em;
    color: rgba(255, 255, 255, 0.1);
    z-index: 1;
  }

  .vertical-layer-front {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    writing-mode: vertical-rl;
    font-size: 28px;
    letter-spacing: 0.12em;
    line-height: 2.2;
    color: #ffffff;
    z-index: 2;
    text-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
  }
</style>

<div class="layered-container">
  <div class="vertical-layer-back">背景文字</div>
  <p class="vertical-layer-front">
    前面に配置される<br>
    メインテキスト
  </p>
</div>

実際の表示

See the Pen css-vertical-text-center-05 by watashi-xyz (@watashi-xyz) on CodePen.

transformの詳細な使い方:

/* 基本的な中央配置 */
.basic-center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* 回転を加える場合(縦書きをさらに回転) */
.rotated-center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(10deg);
  writing-mode: vertical-rl;
}

/* 拡大縮小を加える場合 */
.scaled-center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(1.2);
  writing-mode: vertical-rl;
}

/* アニメーション用 */
.animated-center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  writing-mode: vertical-rl;
  transition: transform 0.3s ease;
}

.animated-center:hover {
  transform: translate(-50%, -50%) scale(1.1);
}

positionのメリット:

  • ピクセル単位での精密な位置調整が可能
  • z-indexで重ね順を自由に制御できる
  • アニメーションやトランジションと相性が良い
  • レイヤー構造を作りやすい

positionのデメリット:

  • 親要素にposition: relative;の指定が必須
  • レスポンシブ対応が少し複雑になる
  • 要素のサイズが変わると中央からズレることがある
  • 複数要素の配置管理が煩雑になりがち

ブラウザ互換性:

  • Chrome、Firefox、Safari、Edgeの全バージョンで動作
  • IE9+でも動作するが、transformのベンダープレフィックスms-transformが必要

レスポンシブ対応とトラブルシューティング:

.responsive-absolute {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  writing-mode: vertical-rl;
  font-size: clamp(18px, 3vw, 32px);
  letter-spacing: 0.1em;
  line-height: 2;
  max-height: 90vh; /* 画面からはみ出さないように */
  max-width: 90vw;
  padding: 20px;
  overflow: auto; /* 長文の場合スクロール可能に */
}

/* スマホ横向き対応 */
@media (max-width: 768px) and (orientation: landscape) {
  .responsive-absolute {
    font-size: 16px;
    max-height: 80vh;
  }
}

/* 非常に小さい画面での調整 */
@media (max-width: 480px) {
  .responsive-absolute {
    writing-mode: horizontal-tb; /* 横書きに切り替え */
    text-align: center;
    padding: 15px;
  }
}

各手法の比較まとめ:

手法コードの簡潔さ精密な調整レスポンシブブラウザ互換性推奨用途
Flexbox★★★★★★★★★★★汎用的な中央配置
Grid★★★★★★★★★★★モダンなレイアウト
position★★★★★★★★★★★精密な配置・重ね合わせ

実務での選び方:

  • Flexbox:迷ったらこれ。最も安定していて汎用性が高い
  • Grid:モダンブラウザのみ対応でOKなら最もシンプル
  • position:デザイン性の高いレイアウトや、アニメーションが必要な場合に最適
【不要なパソコンを送るだけ】パソコン無料処分サービス『送壊ゼロ』

縦書き特有のズレ・文字挙動の修正方法

縦書きレイアウトでは、横書きでは問題にならない独特の表示トラブルが発生します。このセクションでは、実務で頻繁に遭遇する「英数字の横倒し」「句読点のズレ」「iOS Safariでの崩れ」といった問題の原因と、確実に動作する解決策を具体的に解説します。

英語・数字(特に「1」「0」)が横倒しになる問題とtext-orientation: upright;の活用

縦書きにすると、英数字が90度回転して横向きになってしまう問題は、縦書き実装で最も頻繁に遭遇するトラブルです。特に「1」「0」「I」などの細長い文字は非常に読みづらくなります。

問題の発生例:

<style>
  .vertical-problem {
    writing-mode: vertical-rl;
    font-size: 24px;
    padding: 20px;
    border: 2px solid #e74c3c;
    background-color: #fadbd8;
    height: 300px;
  }
</style>

<div class="vertical-problem">
  <!-- 英数字が横倒しになって読みにくい -->
  製品番号:ABC-12345
  価格:¥10,000
  在庫数:100個
</div>

基本的な解決方法:

.vertical-fixed {
  writing-mode: vertical-rl;
  text-orientation: upright; /* すべての文字を正立させる */
  font-size: 24px;
  letter-spacing: 0.1em;
  line-height: 2;
}

実践的な完全サンプルコード:

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    .comparison-container {
      display: flex;
      gap: 30px;
      padding: 30px;
      background-color: #ecf0f1;
    }

    /* 問題のある例 */
    .vertical-ng {
      writing-mode: vertical-rl;
      /* text-orientationを指定しない */
      font-size: 20px;
      padding: 25px;
      border: 3px solid #e74c3c;
      background-color: #fadbd8;
      height: 350px;
      position: relative;
    }

    .vertical-ng::before {
      content: "❌ NG例";
      position: absolute;
      top: -30px;
      right: 0;
      writing-mode: horizontal-tb;
      font-size: 14px;
      font-weight: bold;
      color: #e74c3c;
    }

    /* 解決済みの例 */
    .vertical-ok {
      writing-mode: vertical-rl;
      text-orientation: upright; /* 修正ポイント */
      font-size: 20px;
      letter-spacing: 0.05em; /* 微調整 */
      padding: 25px;
      border: 3px solid #27ae60;
      background-color: #d5f4e6;
      height: 350px;
      position: relative;
    }

    .vertical-ok::before {
      content: "✓ OK例";
      position: absolute;
      top: -30px;
      right: 0;
      writing-mode: horizontal-tb;
      font-size: 14px;
      font-weight: bold;
      color: #27ae60;
    }
  </style>
</head>
<body>
  <div class="comparison-container">
    <div class="vertical-ng">
      製品番号:ABC-12345<br>
      価格:¥10,000<br>
      在庫数:100個<br>
      発売日:2025年1月1日
    </div>

    <div class="vertical-ok">
      製品番号:ABC-12345<br>
      価格:¥10,000<br>
      在庫数:100個<br>
      発売日:2025年1月1日
    </div>
  </div>
</body>
</html>

実際の表示

See the Pen css-vertical-text-center-06 by watashi-xyz (@watashi-xyz) on CodePen.

部分的に適用する方法(日本語は横向き、英数字だけ正立):

<style>
  .vertical-partial {
    writing-mode: vertical-rl;
    text-orientation: mixed; /* 基本はmixed */
    font-size: 22px;
    letter-spacing: 0.08em;
    line-height: 2;
  }

  /* 英数字部分だけをspanで囲んで正立させる */
  .upright-text {
    text-orientation: upright;
    font-size: 0.9em; /* やや小さめにして視覚的バランスを取る */
  }
</style>

<div class="vertical-partial">
  商品コード:<span class="upright-text">ABC-12345</span><br>
  通常価格は<span class="upright-text">10,000</span>円です。<br>
  在庫は<span class="upright-text">100</span>個あります。
</div>

特定の数字だけ対策する実用例:

<style>
  .vertical-smart {
    writing-mode: vertical-rl;
    text-orientation: mixed;
    font-size: 24px;
    letter-spacing: 0.1em;
    line-height: 2.2;
    padding: 30px;
    background-color: #ffffff;
    border: 2px solid #3498db;
  }

  /* 1桁の数字だけ正立させる(読みやすさ向上) */
  .digit {
    text-orientation: upright;
    font-size: 0.95em;
    font-weight: bold;
  }

  /* アルファベットの略語 */
  .acronym {
    text-orientation: upright;
    font-size: 0.9em;
    letter-spacing: 0.05em;
  }
</style>

<div class="vertical-smart">
  <span class="acronym">CPU</span>使用率:<span class="digit">95</span>%<br>
  メモリ:<span class="digit">8</span><span class="acronym">GB</span><br>
  ストレージ:<span class="digit">512</span><span class="acronym">GB</span>
</div>

text-orientationの値別の挙動詳細:

<style>
  .orientation-demo {
    display: flex;
    gap: 20px;
    padding: 20px;
    background-color: #34495e;
  }

  .demo-item {
    writing-mode: vertical-rl;
    font-size: 18px;
    padding: 20px;
    background-color: #ecf0f1;
    height: 250px;
    border-radius: 8px;
  }

  .demo-mixed { text-orientation: mixed; }
  .demo-upright { text-orientation: upright; }
  .demo-sideways { text-orientation: sideways; }
</style>

<div class="orientation-demo">
  <div class="demo-item demo-mixed">
    <strong>mixed(デフォルト)</strong><br>
    日本語OK<br>
    ABC123は横向き
  </div>

  <div class="demo-item demo-upright">
    <strong>upright</strong><br>
    日本語OK<br>
    ABC123も正立
  </div>

  <div class="demo-item demo-sideways">
    <strong>sideways</strong><br>
    すべて90度回転<br>
    ABC123も回転
  </div>
</div>

ブラウザ別の注意点と対策:

/* Chrome / Edge / Firefox 対応 */
.vertical-modern {
  writing-mode: vertical-rl;
  text-orientation: upright;
}

/* iOS Safari対策(バージョンによって挙動が異なる) */
@supports (-webkit-touch-callout: none) {
  .vertical-ios-safe {
    writing-mode: vertical-rl;
    -webkit-writing-mode: vertical-rl; /* ベンダープレフィックス */
    text-orientation: upright;
    -webkit-text-orientation: upright;
    /* iOS独自のフォントレンダリング調整 */
    -webkit-font-smoothing: antialiased;
  }
}

/* Firefoxの独自実装対策 */
@-moz-document url-prefix() {
  .vertical-firefox {
    writing-mode: vertical-rl;
    text-orientation: upright;
    /* Firefoxでのレンダリング最適化 */
    letter-spacing: 0.08em;
  }
}

実務でのベストプラクティス:

.vertical-best-practice {
  writing-mode: vertical-rl;
  text-orientation: upright; /* 基本はupright */
  font-size: 20px;
  letter-spacing: 0.08em; /* uprightの場合は少し広めに */
  line-height: 2;

  /* フォールバック対策 */
  font-feature-settings: "vkrn"; /* 縦組み用カーニング */
  -webkit-font-feature-settings: "vkrn";

  /* 英数字のサイズ微調整 */
  font-variant-numeric: proportional-nums;
}

/* 長い英単語は別途調整 */
.vertical-best-practice .long-word {
  font-size: 0.85em;
  letter-spacing: 0.03em;
}
【不要なパソコンを送るだけ】パソコン無料処分サービス『送壊ゼロ』

縦書き時の句読点(「、」「。」)や記号の位置ズレを修正するCSSテクニック

縦書きでは句読点や括弧などの記号が、想定外の位置に表示されたり、文字間隔が不自然になったりする問題が発生します。これはフォントのメトリクス情報や、ブラウザのレンダリングエンジンの違いが原因です。

問題の発生例:

<style>
  .punctuation-problem {
    writing-mode: vertical-rl;
    font-size: 24px;
    padding: 25px;
    border: 2px solid #e67e22;
    background-color: #fdebd0;
    height: 350px;
  }
</style>

<div class="punctuation-problem">
  吾輩は猫である。名前はまだ無い。<br>
  どこで生れたか、とんと見当がつかぬ。<br>
  「こんにちは」と彼は言った。<br>
  (補足説明)
</div>

基本的な修正方法:

.punctuation-fixed {
  writing-mode: vertical-rl;
  font-size: 24px;
  letter-spacing: 0.05em; /* 文字間隔を微調整 */
  line-height: 2;

  /* 縦書き用のOpenType機能を有効化 */
  font-feature-settings: "vpal", "vkrn";
  -webkit-font-feature-settings: "vpal", "vkrn";
}

実践的な完全サンプルコード:

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    .punctuation-container {
      display: flex;
      gap: 40px;
      padding: 30px;
      background-color: #2c3e50;
    }

    /* 修正前 */
    .punctuation-before {
      writing-mode: vertical-rl;
      font-size: 20px;
      padding: 25px;
      border: 3px solid #e67e22;
      background-color: #fdebd0;
      height: 400px;
      width: 180px;
    }

    /* 修正後 */
    .punctuation-after {
      writing-mode: vertical-rl;
      font-size: 20px;
      letter-spacing: 0.05em; /* 文字間を微調整 */
      line-height: 2.2; /* 行間を広めに */
      padding: 25px;
      border: 3px solid #27ae60;
      background-color: #d5f4e6;
      height: 400px;
      width: 180px;

      /* OpenType機能で縦書き最適化 */
      font-feature-settings: "vpal" 1, "vkrn" 1, "vchw" 1;
      -webkit-font-feature-settings: "vpal" 1, "vkrn" 1, "vchw" 1;
    }

    /* 句読点の個別調整が必要な場合 */
    .punctuation-after .comma,
    .punctuation-after .period {
      margin-right: -0.1em; /* 句読点の後の余白を詰める */
    }

    .punctuation-after .quote-start {
      margin-left: -0.05em; /* 開き括弧の前を詰める */
    }

    .punctuation-after .quote-end {
      margin-right: -0.05em; /* 閉じ括弧の後を詰める */
    }
  </style>
</head>
<body>
  <div class="punctuation-container">
    <div class="punctuation-before">
      吾輩は猫である。名前はまだ無い。<br>
      どこで生れたか、とんと見当がつかぬ。<br>
      「こんにちは」と彼は言った。<br>
      (補足説明があります)
    </div>

    <div class="punctuation-after">
      吾輩は猫である<span class="period">。</span>名前はまだ無い<span class="period">。</span><br>
      どこで生れたか<span class="comma">、</span>とんと見当がつかぬ<span class="period">。</span><br>
      <span class="quote-start">「</span>こんにちは<span class="quote-end">」</span>と彼は言った<span class="period">。</span><br>
      <span class="quote-start">(</span>補足説明があります<span class="quote-end">)</span>
    </div>
  </div>
</body>
</html>

実際の表示

See the Pen css-vertical-text-center-07 by watashi-xyz (@watashi-xyz) on CodePen.

フォント別の調整方法:

/* 游ゴシック・游明朝の場合 */
.punctuation-yu-gothic {
  writing-mode: vertical-rl;
  font-family: "Yu Gothic", "游ゴシック", sans-serif;
  font-feature-settings: "vpal", "vkrn", "vchw";
  letter-spacing: 0.06em;
  line-height: 2.1;
}

/* ヒラギノの場合 */
.punctuation-hiragino {
  writing-mode: vertical-rl;
  font-family: "Hiragino Mincho ProN", "ヒラギノ明朝 ProN", serif;
  font-feature-settings: "vpal", "vkrn";
  letter-spacing: 0.05em;
  line-height: 2;
}

/* Noto Serif JPの場合(最も安定) */
.punctuation-noto {
  writing-mode: vertical-rl;
  font-family: "Noto Serif JP", serif;
  font-feature-settings: "vpal", "vkrn", "vchw";
  letter-spacing: 0.08em;
  line-height: 2.2;
}

特定の記号を個別調整する方法:

<style>
  .vertical-symbols {
    writing-mode: vertical-rl;
    font-size: 22px;
    letter-spacing: 0.08em;
    line-height: 2.2;
    padding: 30px;
  }

  /* 句読点の調整 */
  .adjust-comma { margin: -0.1em 0 -0.05em 0; }
  .adjust-period { margin: -0.1em 0 -0.05em 0; }

  /* 括弧類の調整 */
  .adjust-paren-open { margin: 0 0 -0.08em 0; }
  .adjust-paren-close { margin: -0.08em 0 0 0; }

  /* 中黒・波ダッシュの調整 */
  .adjust-nakaguro {
    margin: 0 -0.1em;
    display: inline-block;
  }

  /* 疑問符・感嘆符の調整 */
  .adjust-exclamation {
    margin-right: -0.15em;
  }
</style>

<div class="vertical-symbols">
  これは文章です<span class="adjust-period">。</span>次の文章です<span class="adjust-period">。</span><br>
  項目A<span class="adjust-comma">、</span>項目B<span class="adjust-comma">、</span>項目C<br>
  <span class="adjust-paren-open">(</span>補足情報<span class="adjust-paren-close">)</span><br>
  驚いた<span class="adjust-exclamation">!</span>本当ですか<span class="adjust-exclamation">?</span>
</div>

CSSカスタムプロパティで管理する方法(推奨):

:root {
  /* 句読点調整用のカスタムプロパティ */
  --vertical-comma-margin: -0.08em;
  --vertical-period-margin: -0.1em;
  --vertical-paren-open-margin: -0.06em;
  --vertical-paren-close-margin: -0.06em;
  --vertical-quote-margin: -0.05em;
}

.vertical-managed {
  writing-mode: vertical-rl;
  font-size: 22px;
  letter-spacing: 0.08em;
  line-height: 2.2;
  font-feature-settings: "vpal", "vkrn";
}

.vertical-managed .comma {
  margin-right: var(--vertical-comma-margin);
}

.vertical-managed .period {
  margin-right: var(--vertical-period-margin);
}

.vertical-managed .paren-open {
  margin-left: var(--vertical-paren-open-margin);
}

.vertical-managed .paren-close {
  margin-right: var(--vertical-paren-close-margin);
}

/* レスポンシブ時の調整値変更 */
@media (max-width: 768px) {
  :root {
    --vertical-comma-margin: -0.05em;
    --vertical-period-margin: -0.08em;
  }
}

OpenType機能の詳細解説:

.vertical-opentype-full {
  writing-mode: vertical-rl;

  /* 縦書き用OpenType機能の完全版 */
  font-feature-settings:
    "vpal" 1,  /* 縦書き用字形(Vertical Proportional Alternate) */
    "vkrn" 1,  /* 縦書き用カーニング(Vertical Kerning) */
    "vchw" 1,  /* 縦書き用字幅調整(Vertical Contextual Half-width) */
    "vert" 1,  /* 縦書き用字形置換(Vertical Writing) */
    "vrt2" 1;  /* 縦書き用回転グリフ(Vertical Rotated) */

  -webkit-font-feature-settings: "vpal", "vkrn", "vchw", "vert", "vrt2";

  letter-spacing: 0.08em;
  line-height: 2.2;
}
国内シェアNo.1のエックスサーバーが提供するVPSサーバー『XServer VPS』

iOS Safariで縦書き中央が崩れる原因とCSSワークアラウンド

iOS Safariは縦書き表示において、独自のレンダリングバグや挙動の違いがあり、特に中央揃えレイアウトで問題が頻発します。このセクションでは、実機検証に基づいた確実な対策を紹介します。

主な問題パターン:

  1. Flexboxやgridでの中央配置がズレる
  2. transformによる位置調整が効かない
  3. フォントサイズが自動調整されて意図しないサイズになる
  4. スクロール時に文字が消える・ちらつく

問題1:Flexbox中央配置のズレ対策

<style>
  /* 問題のあるコード(iOS Safariでズレる) */
  .flex-center-broken {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
  }

  .vertical-text-broken {
    writing-mode: vertical-rl;
    font-size: 24px;
  }

  /* iOS Safari対策版 */
  .flex-center-ios-fixed {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    min-height: -webkit-fill-available; /* iOS Safari用 */

    /* iOS特有のレンダリングバグ対策 */
    -webkit-transform: translateZ(0);
    transform: translateZ(0);
  }

  .vertical-text-ios-fixed {
    writing-mode: vertical-rl;
    -webkit-writing-mode: vertical-rl; /* ベンダープレフィックス */
    font-size: 24px;

    /* iOS Safariの自動フォントサイズ調整を無効化 */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;

    /* ハードウェアアクセラレーションを有効化 */
    -webkit-transform: translateZ(0);
    transform: translateZ(0);
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
  }
</style>

<div class="flex-center-ios-fixed">
  <p class="vertical-text-ios-fixed">
    iOS Safariでも<br>
    正しく中央配置
  </p>
</div>

問題2:Grid中央配置のiOS対策

/* 通常のGrid中央配置 */
.grid-center-standard {
  display: grid;
  place-items: center;
  min-height: 100vh;
}

/* iOS Safari完全対応版 */
.grid-center-ios-safe {
  display: grid;
  place-items: center;

  /* iOS SafariのViewport Height問題対策 */
  min-height: 100vh;
  min-height: -webkit-fill-available;

  /* グリッドアイテムの配置を強制 */
  align-content: center;
  justify-content: center;

  /* レンダリング最適化 */
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
}

.vertical-grid-item-ios {
  writing-mode: vertical-rl;
  -webkit-writing-mode: vertical-rl;

  /* iOS独自の調整 */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

問題3:transform位置調整のiOS対策

<style>
  .position-center-ios-safe {
    position: relative;
    width: 100vw;
    height: 100vh;
    height: -webkit-fill-available; /* iOS対策 */

    /* スクロールバグ対策 */
    overflow: hidden;
  }

  .vertical-absolute-ios {
    position: absolute;
    top: 50%;
    left: 50%;

    /* iOS Safariのtransformバグ対策 */
    -webkit-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);

    /* さらにマージンで微調整(iOS特有のズレ補正) */
    margin-top: -1px;
    margin-left: -1px;

    writing-mode: vertical-rl;
    -webkit-writing-mode: vertical-rl;

    /* テキストレンダリング最適化 */
    -webkit-text-size-adjust: 100%;
    -webkit-font-smoothing: antialiased;

    /* ハードウェアアクセラレーション */
    -webkit-transform: translate(-50%, -50%) translateZ(0);
    transform: translate(-50%, -50%) translateZ(0);
    will-change: transform;
  }
</style>

<div class="position-center-ios-safe">
  <p class="vertical-absolute-ios">
    iOS Safari完全対応の<br>
    position中央配置
  </p>
</div>

実践的な完全サンプル(iOS Safari完全対応版):

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    html {
      /* iOS SafariのViewport問題対策 */
      height: -webkit-fill-available;
    }

    body {
      min-height: 100vh;
      min-height: -webkit-fill-available;
    }

    .ios-safe-container {
      display: flex;
      align-items: center;
      justify-content: center;
      min-height: 100vh;
      min-height: -webkit-fill-available;

      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);

      /* iOS Safari対策の基本セット */
      -webkit-transform: translateZ(0);
      transform: translateZ(0);
      -webkit-backface-visibility: hidden;
      backface-visibility: hidden;

      /* スクロール問題対策 */
      overflow: hidden;
      position: relative;
    }

    .vertical-content-ios {
      writing-mode: vertical-rl;
      -webkit-writing-mode: vertical-rl;
      text-orientation: mixed;

      font-size: 28px;
      letter-spacing: 0.12em;
      line-height: 2.2;
      color: #ffffff;

      padding: 35px;
      background-color: rgba(0, 0, 0, 0.4);
      border-radius: 12px;
      box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);

      /* iOS Safari完全対応 */
      -webkit-text-size-adjust: 100%;
      text-size-adjust: 100%;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;

      /* ハードウェアアクセラレーション */
      -webkit-transform: translateZ(0);
      transform: translateZ(0);
      will-change: transform;

      /* 縦書き最適化 */
      font-feature-settings: "vpal", "vkrn";
      -webkit-font-feature-settings: "vpal", "vkrn";

      /* iOS独自の微調整 */
      max-height: 85vh;
      overflow-y: auto;
      -webkit-overflow-scrolling: touch; /* 慣性スクロール */
    }

    /* iOS 14以降の対策 */
    @supports (-webkit-touch-callout: none) {
      .vertical-content-ios {
        /* より確実な中央配置 */
        margin: auto;
      }
    }

    /* iPhone SE(第1世代)など小画面対策 */
    @media (max-width: 375px) {
      .vertical-content-ios {
        font-size: 22px;
        padding: 25px;
        max-height: 80vh;
      }
    }
  </style>
</head>
<body>
  <div class="ios-safe-container">
    <div class="vertical-content-ios">
      iOS Safariでも<br>
      完全に動作する<br>
      縦書き中央配置<br>
      長文でも大丈夫です
    </div>
  </div>
</body>
</html>

実際の表示

See the Pen css-vertical-text-center-08 by watashi-xyz (@watashi-xyz) on CodePen.

問題別の対策まとめ:

/* 【問題1】100vhが正しく計算されない */
.fix-viewport-height {
  min-height: 100vh;
  min-height: -webkit-fill-available; /* iOS Safari対策 */
}

html {
  height: -webkit-fill-available; /* html要素にも指定 */
}

/* 【問題2】フォントサイズが勝手に変わる */
.fix-font-size {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* 【問題3】transformが効かない・ズレる */
.fix-transform {
  -webkit-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  -webkit-transform: translate(-50%, -50%) translateZ(0);
  transform: translate(-50%, -50%) translateZ(0);
  will-change: transform;
}

/* 【問題4】文字が消える・ちらつく */
.fix-flickering {
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

/* 【問題5】スクロール時の挙動がおかしい */
.fix-scroll {
  -webkit-overflow-scrolling: touch; /* 慣性スクロール */
  overflow-y: auto;
}

包括的なiOS Safari対策クラス(コピペ用):

/* iOS Safari完全対応の縦書き中央配置テンプレート */
.vertical-center-ios-complete {
  /* コンテナ設定 */
  display: flex;
  align-items: center;
  justify-content: center;

  /* Viewport Height対策 */
  min-height: 100vh;
  min-height: -webkit-fill-available;

  /* レンダリング最適化 */
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

.vertical-text-ios-complete {
  /* 縦書き設定 */
  writing-mode: vertical-rl;
  -webkit-writing-mode: vertical-rl;
  text-orientation: mixed;

  /* フォント設定 */
  font-size: 24px;
  letter-spacing: 0.1em;
  line-height: 2;

  /* iOS Safari対策 */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;

  /* ハードウェアアクセラレーション */
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
  will-change: transform;

  /* OpenType機能 */
  font-feature-settings: "vpal", "vkrn";
  -webkit-font-feature-settings: "vpal", "vkrn";

  /* スクロール対策 */
  max-height: 85vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* HTML要素にも設定 */
html {
  height: -webkit-fill-available;
}

body {
  min-height: 100vh;
  min-height: -webkit-fill-available;
}

デバッグ用のiOS Safari検出とフォールバック:

/* iOS Safariを検出して特別な処理を適用 */
@supports (-webkit-touch-callout: none) {
  /* iOS Safari専用スタイル */
  .vertical-ios-only {
    writing-mode: vertical-rl;
    -webkit-writing-mode: vertical-rl;

    /* iOS特有の微調整 */
    padding-top: env(safe-area-inset-top);
    padding-bottom: env(safe-area-inset-bottom);
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
  }
}

/* iOS以外のブラウザ用 */
@supports not (-webkit-touch-callout: none) {
  .vertical-other-browser {
    writing-mode: vertical-rl;
    /* 通常の設定 */
  }
}

レスポンシブ対応とメディアクエリ:

/* iPhone SE(第1世代)375px × 667px */
@media (max-width: 375px) {
  .vertical-responsive-ios {
    font-size: 18px;
    letter-spacing: 0.08em;
    padding: 20px;
  }
}

/* iPhone 12 Pro 390px × 844px */
@media (min-width: 376px) and (max-width: 430px) {
  .vertical-responsive-ios {
    font-size: 22px;
    letter-spacing: 0.1em;
    padding: 25px;
  }
}

/* iPad 768px × 1024px */
@media (min-width: 768px) {
  .vertical-responsive-ios {
    font-size: 28px;
    letter-spacing: 0.12em;
    padding: 35px;
  }
}

/* 横向き対応 */
@media (orientation: landscape) and (max-width: 896px) {
  .vertical-responsive-ios {
    font-size: 20px;
    max-height: 70vh; /* 横向きでは高さを抑える */
  }
}

実務でよくあるトラブルと解決策:

<style>
  /* トラブル1:ホームバー領域に文字が重なる(iPhone X以降) */
  .safe-area-padding {
    padding-bottom: env(safe-area-inset-bottom, 20px);
    padding-left: env(safe-area-inset-left, 0);
    padding-right: env(safe-area-inset-right, 0);
  }

  /* トラブル2:スクロール時に固定ヘッダーがズレる */
  .fixed-header-ios {
    position: fixed;
    top: 0;
    right: 0;
    -webkit-transform: translateZ(0);
    transform: translateZ(0);
    will-change: transform;
  }

  /* トラブル3:Flexboxの子要素がはみ出る */
  .flex-child-fix {
    min-width: 0; /* Flexアイテムの最小幅をリセット */
    min-height: 0;
    flex-shrink: 1; /* 縮小を許可 */
  }

  /* トラブル4:Grid内の要素が中央からズレる */
  .grid-item-center-fix {
    margin: auto; /* iOS Safariでは明示的に必要な場合がある */
    align-self: center;
    justify-self: center;
  }
</style>

パフォーマンス最適化(iOS Safari向け):

.vertical-performance-optimized {
  writing-mode: vertical-rl;
  -webkit-writing-mode: vertical-rl;

  /* GPUアクセラレーションを最適化 */
  -webkit-transform: translate3d(0, 0, 0);
  transform: translate3d(0, 0, 0);

  /* レイヤー化を強制 */
  will-change: transform, opacity;

  /* レンダリング最適化 */
  contain: layout style paint;

  /* フォント描画最適化 */
  -webkit-font-smoothing: subpixel-antialiased;
  text-rendering: optimizeLegibility;
}

/* アニメーション時の最適化 */
.vertical-animated-ios {
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
  will-change: transform;

  /* アニメーションの滑らかさを改善 */
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  -webkit-transition: -webkit-transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

ブラウザ判定とフォールバック戦略:

// JavaScriptでiOS Safariを検出してクラスを追加
const isIOSSafari = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;

if (isIOSSafari) {
  document.documentElement.classList.add('ios-safari');
}
/* iOS Safari専用の調整 */
.ios-safari .vertical-text {
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  -webkit-transform: translateZ(0);
}

/* その他のブラウザ */
body:not(.ios-safari) .vertical-text {
  /* 通常のスタイル */
}

最終チェックリスト(iOS Safari対応):

  • min-height: -webkit-fill-available; を使用している
  • -webkit-text-size-adjust: 100%; でフォントサイズ固定
  • -webkit-transform: translateZ(0); でハードウェアアクセラレーション有効化
  • env(safe-area-inset-*) でセーフエリア対応
  • -webkit-overflow-scrolling: touch; で慣性スクロール対応
  • ベンダープレフィックス(-webkit-)を適切に追加
  • will-change プロパティでレンダリング最適化
  • 実機(iPhone / iPad)で動作確認済み

トラブルシューティングフローチャート:

iOS Safariで縦書きが崩れている
 ↓
【確認1】100vhが正しく機能しているか?
 → NO:min-height: -webkit-fill-available; を追加
 ↓
【確認2】フォントサイズが意図通りか?
 → NO:-webkit-text-size-adjust: 100%; を追加
 ↓
【確認3】transformが効いているか?
 → NO:-webkit-transform を追加、translateZ(0)で強制レイヤー化
 ↓
【確認4】文字が消える・ちらつく?
 → YES:-webkit-backface-visibility: hidden; を追加
 ↓
【確認5】スクロールがカクつく?
 → YES:-webkit-overflow-scrolling: touch; を追加
 ↓
解決!

これらの対策を適用することで、iOS Safariにおける縦書き中央配置の問題はほぼすべて解決できます。特に -webkit-fill-available-webkit-text-size-adjusttranslateZ(0) の3つは必須の対策として覚えておきましょう。

◆◇◆ 【衝撃価格】VPS512MBプラン!1時間1.3円【ConoHa】 ◆◇◆

よくある質問(FAQ)

Flexboxで縦書きを中央配置したら、テキストが画面から切れてしまいます。どう修正すればいいですか?

問題の状況:

/* このコードだとテキストが長い場合に切れる */
.flex-container {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
}

.vertical-text {
  writing-mode: vertical-rl;
  font-size: 24px;
}

原因: Flexboxのalign-items: center;justify-content: center;は、子要素が親要素のサイズを超えた場合、はみ出した部分をスクロールできない領域に配置してしまいます。特に縦書きでは横方向(writing-modeでは縦方向)にテキストが伸びるため、予想以上に長くなりがちです。

解決策:

/* 解決方法1:min-heightを使う */
.flex-container-fixed {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh; /* heightをmin-heightに変更 */
  padding: 20px; /* 余白を確保 */
}

.vertical-text {
  writing-mode: vertical-rl;
  font-size: 24px;
  max-height: 90vh; /* 最大高さを制限 */
  overflow-y: auto; /* 長い場合はスクロール可能に */
}

/* 解決方法2:marginを使う */
.flex-container-margin {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  overflow: auto; /* コンテナ自体をスクロール可能に */
}

.vertical-text-margin {
  writing-mode: vertical-rl;
  font-size: 24px;
  margin: auto; /* 自動的に中央配置 */
  max-height: calc(100vh - 40px); /* 余白を考慮 */
}

/* 解決方法3:safe center(最もモダンな方法) */
.flex-container-safe {
  display: flex;
  align-items: safe center; /* safe キーワードを追加 */
  justify-content: safe center;
  min-height: 100vh;
}

実装例:

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <style>
    .flex-safe-container {
      display: flex;
      align-items: safe center;
      justify-content: safe center;
      min-height: 100vh;
      padding: 20px;
      background-color: #ecf0f1;
    }

    .vertical-long-text {
      writing-mode: vertical-rl;
      font-size: 20px;
      letter-spacing: 0.08em;
      line-height: 2;
      max-height: 90vh;
      overflow-y: auto;
      padding: 30px;
      background-color: #ffffff;
      border: 2px solid #3498db;
      border-radius: 8px;
    }
  </style>
</head>
<body>
  <div class="flex-safe-container">
    <div class="vertical-long-text">
      <!-- 長いテキストでも切れずにスクロール可能 -->
      これは非常に長いテキストです。縦書きで表示される内容が...(省略)
    </div>
  </div>
</body>
</html>

実際の表示

See the Pen css-vertical-text-center-09 by watashi-xyz (@watashi-xyz) on CodePen.

ブラウザ互換性の注意:

  • safe centerはChrome 115+、Firefox 63+、Safari 15.4+でサポート
  • 古いブラウザ対応が必要な場合はmin-heightoverflowを使う方法が確実

縦書きにすると英数字が横向きになるのですが、一部だけ縦向きにする方法はありますか?

問題の状況: 製品番号や価格など、一部の英数字だけを縦向き(正立)にしたいが、全体にtext-orientation: upright;を適用すると日本語の読みやすさが損なわれる。

解決策:

<style>
  .vertical-mixed {
    writing-mode: vertical-rl;
    text-orientation: mixed; /* 基本はmixed */
    font-size: 22px;
    letter-spacing: 0.08em;
    line-height: 2;
  }

  /* 特定の要素だけuprightにする */
  .upright {
    text-orientation: upright;
    font-size: 0.9em; /* やや小さめで視覚的バランスを調整 */
    font-weight: 600; /* 太めにして可読性向上 */
  }

  /* 数値用のクラス */
  .number-upright {
    text-orientation: upright;
    font-family: "Arial", "Helvetica", sans-serif; /* 数字が読みやすいフォント */
    font-size: 0.95em;
    font-variant-numeric: tabular-nums; /* 等幅数字 */
  }
</style>

<div class="vertical-mixed">
  商品コード:<span class="upright">ABC-12345</span><br>
  価格:<span class="number-upright">¥10,000</span><br>
  在庫:<span class="number-upright">50</span>個<br>
  発売日:2025年1月1日
</div>

より実用的な実装例(カスタムプロパティで管理):

:root {
  --upright-size: 0.9em;
  --upright-spacing: 0.05em;
}

.vertical-content {
  writing-mode: vertical-rl;
  text-orientation: mixed;
  font-size: 20px;
}

/* 英数字用クラス */
.alphanumeric {
  text-orientation: upright;
  font-size: var(--upright-size);
  letter-spacing: var(--upright-spacing);
}

/* 略語・頭字語用 */
.acronym {
  text-orientation: upright;
  font-size: 0.85em;
  font-weight: bold;
  letter-spacing: 0.1em;
}

/* URLやメールアドレス用 */
.url {
  text-orientation: upright;
  font-size: 0.8em;
  font-family: monospace;
  word-break: break-all;
}

JavaScriptで自動化する方法:

<script>
// 数字を自動的にspanで囲んで縦向きにする
document.querySelectorAll('.vertical-auto').forEach(element => {
  element.innerHTML = element.innerHTML.replace(
    /(\\d+)/g,
    '<span class="number-upright">$1</span>'
  );
});

// 英大文字の略語を自動検出
document.querySelectorAll('.vertical-auto').forEach(element => {
  element.innerHTML = element.innerHTML.replace(
    /\\b([A-Z]{2,})\\b/g,
    '<span class="acronym">$1</span>'
  );
});
</script>

失敗例と成功例の比較:

/* ❌ NG:全体にuprightを適用 */
.vertical-ng {
  writing-mode: vertical-rl;
  text-orientation: upright; /* 日本語も詰まって読みにくい */
}

/* ✓ OK:部分的にuprightを適用 */
.vertical-ok {
  writing-mode: vertical-rl;
  text-orientation: mixed; /* 基本はmixed */
}
.vertical-ok .number {
  text-orientation: upright; /* 数字だけ縦向き */
}

iOS Safariで縦書きの中央配置がズレます。PC版では正常なのですが…

問題の状況: ChromeやFirefoxでは完璧に中央配置されているのに、iPhoneやiPadのSafariで見ると微妙に(または大きく)ズレている。

主な原因:

  1. 100vhがiOS SafariでアドレスバーやツールバーのUIを含んだ高さになる
  2. webkit-プレフィックスが不足している
  3. iOS独自のフォントサイズ自動調整機能が働いている
  4. ハードウェアアクセラレーションが有効になっていない

包括的な解決策:

/* HTML要素の設定 */
html {
  height: -webkit-fill-available; /* iOS Safari対策 */
}

body {
  min-height: 100vh;
  min-height: -webkit-fill-available;
  margin: 0;
  padding: 0;
}

/* コンテナの設定 */
.vertical-center-ios {
  display: flex;
  align-items: center;
  justify-content: center;

  /* Viewport Height対策 */
  min-height: 100vh;
  min-height: -webkit-fill-available;

  /* レンダリング最適化 */
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

/* 縦書きテキストの設定 */
.vertical-text-ios {
  writing-mode: vertical-rl;
  -webkit-writing-mode: vertical-rl; /* ベンダープレフィックス必須 */

  font-size: 24px;

  /* フォントサイズ自動調整を無効化 */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;

  /* フォントレンダリング最適化 */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;

  /* ハードウェアアクセラレーション */
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
  will-change: transform;

  /* Safe Area対応(iPhone Xシリーズ以降) */
  padding: env(safe-area-inset-top, 20px)
           env(safe-area-inset-right, 20px)
           env(safe-area-inset-bottom, 20px)
           env(safe-area-inset-left, 20px);
}

メタタグの設定も重要:

<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">

position + transformを使う場合の対策:

.position-center-ios {
  position: relative;
  width: 100vw;
  height: 100vh;
  height: -webkit-fill-available;
}

.vertical-absolute-ios {
  position: absolute;
  top: 50%;
  left: 50%;

  /* iOS対応のtransform */
  -webkit-transform: translate(-50%, -50%) translateZ(0);
  transform: translate(-50%, -50%) translateZ(0);

  /* 微調整(iOS特有のズレ補正) */
  margin-top: -1px;
  margin-left: -1px;

  writing-mode: vertical-rl;
  -webkit-writing-mode: vertical-rl;
  -webkit-text-size-adjust: 100%;
}

デバッグ用のチェックリスト:

  • min-height: -webkit-fill-available; を使用
  • -webkit-writing-mode: vertical-rl; を追加
  • -webkit-text-size-adjust: 100%; を設定
  • -webkit-transform: translateZ(0); を追加
  • viewport metaタグに viewport-fit=cover を指定
  • env(safe-area-inset-*) でセーフエリア対応
  • 実機(iPhone/iPad)で動作確認
Webデザインコース

まとめ

CSSで縦書きテキストを中央配置する方法について、基本から実務レベルまで詳しく解説してきました。

縦書きレイアウトはwriting-mode: vertical-rl;で実現できますが、実際のプロジェクトでは英数字の向き、句読点の位置ズレ、iOS Safariでの表示崩れなど、様々な課題に直面します。これらの問題は、適切なCSSプロパティとブラウザ対策を組み合わせることで、確実に解決できます。

中央配置の実装には、Flexbox・Grid・positionの3つの主要な手法があり、それぞれに特徴があります。汎用性と安定性を重視するならFlexbox、コードの簡潔さを求めるならGrid、精密な位置調整が必要ならpositionを選択するのが最適です。

重要ポイント

  • 基本設定writing-modetext-orientationletter-spacingline-heightの4つが縦書きの土台
  • OpenType機能font-feature-settings: "vpal", "vkrn";で句読点の位置ズレを大幅に改善できる
  • iOS Safari対策webkit-fill-availablewebkit-text-size-adjust: 100%translateZ(0)の3つは必須
  • レスポンシブ対応:メディアクエリでwriting-modeを切り替え、スマホでは横書きに変更すると読みやすい
  • テンプレート活用:この記事のコードをベースにすれば、開発時間を大幅に短縮できる

実装時は、この記事で紹介したテンプレートコードをそのままコピペして使っていただけます。ブラウザ互換性やパフォーマンス最適化もすべて組み込み済みなので、すぐに本番環境で活用できます。

最後に、実装後は必ず複数のブラウザ・デバイスで動作確認を行いましょう。特にiPhone・iPadのSafariでの表示チェックは欠かせません。この記事が、皆さんの縦書きレイアウト実装の助けになれば幸いです。

タイトルとURLをコピーしました