デモで学ぶ 文字・画像の回転と縦書き
CSS の transform: rotate() による文字・画像の回転と、writing-mode による縦書き表示の実装デモ。見出しラベルや縦組みレイアウトにすぐ使えるHTML・CSSのコードをコピーできます。
HTML・CSS・JSコードプレビューツール にて実装確認ができます。
やりたいことから探す
① transform: rotate() — 文字の回転
現在: transform: rotate(0deg)
<span class="box">Rotate Me!</span>
.box {
display: inline-block;
font-size: 1.1rem;
font-weight: 700;
color: #1a1a2e;
background: #f0f7ff;
border: 2px solid #bfdbfe;
border-radius: 8px;
padding: 12px 24px;
transform: rotate(0deg);
transition: transform 0.4s ease;
}
要素を指定した角度だけ回転させます。単位は deg(度)で、正の値は時計回り、負の値は反時計回りです。transition と組み合わせるとアニメーション付きの回転になります。
transform は inline 要素には適用されません。span・a などをそのまま回転させようとしても何も起こらないため、display: inline-block(または block・flex)を必ず指定してください。「rotate が効かない」という原因のほとんどがこれです。
② transform-origin — 画像の回転と回転の起点
現在: transform-origin: center center
<img class="rotate-img" src="sample.jpg" alt="サンプル画像">
.rotate-img {
width: 140px;
height: 100px;
object-fit: cover;
border-radius: 8px;
transform: rotate(30deg);
transform-origin: center center;
transition: transform 0.4s ease;
}
既定では要素の中心(center center)を軸に回転します。top left を指定すると左上の角、bottom right なら右下の角が軸になり、同じ 30deg でも仕上がりの位置が大きく変わります。値は left / center / right と top / center / bottom の組み合わせのほか、50% 20px のような数値でも指定できます。
transform は見た目だけを変える指定で、レイアウト上の占有スペースは回転前の矩形のまま変わりません。そのため画像を回転させると、周囲に不自然な余白ができたり、逆に隣の要素へ重なって見えたりします。デモのグレーの点線が「元の占有スペース」です。余白を詰めたい場合は親要素側で margin を調整するか、回転後のサイズに合わせて幅・高さを指定し直してください。
当サイトでは画像ファイルを使わない方針のため、デモでは画像の代わりに同じサイズ(140×100px)・同じ角丸のブロックをCSSで描画しています。コピペ用コードの CSS はそのまま <img> に適用でき、挙動は完全に同じです。
③ writing-mode — 縦書きの基本
吾輩は猫である。名前はまだない。どこで生れたかとんと見当がつかぬ。
現在: writing-mode: horizontal-tb
<p class="vertical-text">吾輩は猫である。名前はまだない。</p>
.vertical-text {
writing-mode: horizontal-tb;
}
テキストの書字方向を指定するプロパティです。horizontal-tb(横書き)が既定値で、vertical-rl は右から左へ流れる縦書き(日本語の伝統的な縦組み)、vertical-lr は左から右へ流れる縦書きになります。
横書きでは要素の width が行の折り返し位置を決めますが、縦書きでは軸が90°入れ替わるため、折り返しを決めるのは height になります。height を指定しないと文章が1行のまま下へ伸び続け、親要素からはみ出します。デモでは height: 120px を指定しています。
④ text-orientation — 縦書き時の英数字の向き
Web2.0の時代
現在: text-orientation: mixed
<p class="vertical-text">Web2.0の時代</p>
.vertical-text {
writing-mode: vertical-rl;
text-orientation: mixed;
height: 120px;
}
縦書きテキスト内での各文字の向きを制御します。mixed(既定)は日本語・中国語は直立でラテン文字は90°回転、upright はすべての文字を直立、sideways はすべての文字を横倒しにします。英数字を縦書きで自然に見せたいときは upright が便利です。
text-orientation は writing-mode: vertical-rl / vertical-lr が指定されている要素にしか効きません。横書き(horizontal-tb)の要素に書いても何も起こらないため、必ずセットで指定してください。
⑤ 縦書き応用 — サイドラベル / 縦見出し / 縦ナビ
サイドラベルを使ったレイアウト例。縦書きテキストがセクションのアクセントになります。
縦書きの見出しと横書きのコンテンツを組み合わせたブロックの例です。
現在: サイドラベルスタイル
<div class="section-wrap">
<span class="side-label">SECTION</span>
<div class="section-content">
<p>コンテンツテキスト</p>
</div>
</div>
.section-wrap {
display: flex;
align-items: flex-start;
gap: 16px;
}
.side-label {
writing-mode: vertical-rl;
transform: rotate(180deg);
font-size: 0.75rem;
font-weight: 700;
letter-spacing: 0.15em;
color: #2563eb;
border-left: 2px solid #2563eb;
padding-left: 6px;
flex-shrink: 0;
}
.section-content p {
font-size: 0.9rem;
color: #334155;
line-height: 1.8;
margin: 0;
}
writing-mode: vertical-rl だけでは文字が上から下へ流れます。rotate(180deg) を重ねると文字列全体が反転し、「下から上」へ読ませる欧文誌面のようなサイドラベルになります。letter-spacing を広めに設定すると縦書き特有のリズムが生まれます。
よくある質問
CSSで文字を90度回転させるにはどうしますか?
対象の要素に transform: rotate(90deg) を指定します。ただし span や a などの inline 要素には transform が効かないため、あわせて display: inline-block が必要です。①のデモで 0°・90°・180°・-45° を切り替えながら確認できます。反時計回りにしたい場合は rotate(-90deg) のように負の値を指定します。
画像を回転させたら周りのレイアウトが崩れました。
transform は見た目を変えるだけで、レイアウト上の占有スペースは回転前の矩形のまま残ります。そのため回転した画像の周囲に余白ができたり、隣の要素と重なって見えたりします。②のデモでは元の占有スペースを点線で表示しているので、この挙動が視覚的に確認できます。対処としては、親要素側で margin を調整するか、回転後の見た目のサイズに合わせて幅・高さを指定し直します。
縦書きにしたら英数字だけ横に倒れてしまいます。
これは text-orientation の既定値 mixed の仕様で、日本語は直立・ラテン文字は90°回転して表示されます。英数字も日本語と同じように直立させたい場合は text-orientation: upright を指定してください。逆にすべてを横倒しにするなら sideways です。④のデモで3種類を並べて比較できます。なお text-orientation は writing-mode が縦書きの要素にしか効きません。
writing-mode を指定したのにテキストが折り返しません。
縦書きでは軸が90°入れ替わるため、折り返し位置を決めるのは width ではなく height です。height を指定しないと文章が1行のまま下へ伸び続け、親要素からはみ出します。height: 120px のように高さを与えれば、その位置で次の行へ折り返します。③のデモもこの指定を含んだ構成です。
rotate と writing-mode はどう使い分けますか?
短いラベルやバッジを傾けたいだけなら transform: rotate()、日本語の文章を本格的に縦組みにするなら writing-mode: vertical-rl が適しています。rotate は1文字ずつではなく要素ごと傾けるため、複数行の文章に使うと読みづらくなります。両者は排他ではなく、⑤のサイドラベルのように writing-mode で縦組みにしてから rotate(180deg) で向きを反転させる、という併用が実務では定番です。
当サイトで公開しているWebデザインやUIの実装例は、一覧として以下記事に纏めています。

