【CSS】transformテクニック!要素を円形(時計状)に均等配置するレイアウト術
Webサイトを作っていると、「時計の文字盤」や「円形のメニュー」のように、要素をぐるっと円状に均等配置したい場面がありますよね。 昔はJavaScriptで複雑な三角関数(サイン・コサイン)の計算をしたり、一つ一つ手作業で位置を調整したりと大変でした。
しかし今のCSSなら、HTMLの「CSS変数(カスタムプロパティ)」と「transform」を組み合わせるだけで、簡単に、しかも美しく円形配置ができてしまいます!
今回は「時計の文字盤」を例に、要素数が変わっても応用できるようなCSSテクニックを解説します!
デモ動作
See the Pen CSS変数を活用した円形レイアウト by mikanbako (@mikanbako) on CodePen.
demo: CSS変数を活用した円形レイアウト
実装コード紹介
【HTML】
<div class="l-wrap">
<h2>CSS 円形配置(サークルレイアウト)デモ</h2>
<div class="p-demo-box">
<!-- 時計の枠 -->
<div class="c-clock">
<!--
💡 インラインスタイルで CSS変数(--i) に順番をセット!
時計なので1〜12まで用意します。
-->
<span class="c-clock__num" style="--i:1;">1</span>
<span class="c-clock__num" style="--i:2;">2</span>
<span class="c-clock__num" style="--i:3;">3</span>
<span class="c-clock__num" style="--i:4;">4</span>
<span class="c-clock__num" style="--i:5;">5</span>
<span class="c-clock__num" style="--i:6;">6</span>
<span class="c-clock__num" style="--i:7;">7</span>
<span class="c-clock__num" style="--i:8;">8</span>
<span class="c-clock__num" style="--i:9;">9</span>
<span class="c-clock__num" style="--i:10;">10</span>
<span class="c-clock__num" style="--i:11;">11</span>
<span class="c-clock__num" style="--i:12;">12</span>
</div>
</div>
</div>
【CSS】
/* ベース装飾 */
.l-wrap {
padding: 40px 20px;
max-width: 600px;
margin: 0 auto;
text-align: center;
color: #3e3e3e;
}
h2 {
margin-bottom: 30px;
font-size: 16px;
color: #1bb4d4;
}
.p-demo-box {
display: flex;
justify-content: center;
padding: 40px;
background: #fff;
border-radius: 12px;
box-shadow: 0 4px 15px rgb(0 0 0 / 5%);
}
/* =========================================
💡 時計のベース(親要素)
========================================= */
.c-clock {
position: relative;
width: 220px;
height: 220px;
background: #e0f7fa;
border: 4px solid #1bb4d4;
border-radius: 50%;
}
/* =========================================
💡 配置する数字(子要素)
========================================= */
.c-clock__num {
position: absolute;
top: 50%;
left: 50%;
font-size: 20px;
font-weight: bold;
color: #333;
/*
ここが円形配置のテクニック!
360度 ÷ 12個 = 30度 を基準に計算しています。
*/
transform:
translate(-50%, -50%)
rotate(calc(30deg * var(--i)))
translateY(-90px)
rotate(calc(-30deg * var(--i)));
}
コードの解説・仕組み
transform:
translate(-50%, -50%)
rotate(calc(30deg * var(--i)))
translateY(-90px)
rotate(calc(-30deg * var(--i)));
transform の中で指定している4つの動きを分解して解説します!
translate(-50%, -50%)
まずはすべての数字を、親要素(時計)の「真ん中」に移動させます。
rotate(calc(30deg * var(–i)))
それぞれの数字に割り振った変数(--i)を使って回転させます。12個の要素を配置するので「360度 ÷ 12 = 30度」。つまり、1は30度、2は60度…というように放射状の角度を向けます。
translateY(-90px)
向いている角度のまま、Y軸(上方向)に向かって半径分(今回は90px)だけ外側に押し出します。
※正確には、半径(110px) - 文字サイズ(20px) = 90pxという算出方法です。
なのでtranslateY(calc(-110px + 100%))という記述でもOKです!
rotate(calc(-30deg * var(–i)))
このままだと数字が傾いて倒れたままなので、ステップ2で回転させた分と「逆方向(マイナス)」に回転させることで、文字を真っ直ぐに立たせます。
まとめ
今回はCSSの transform とカスタムプロパティ(CSS変数)を活用して、要素を円形に配置するテクニックをご紹介しました。
昔はJavaScriptで三角関数を用いた複雑な計算が必要だったサークルレイアウトも、現代のCSSなら translate と rotate を組み合わせるだけで、こんなにスマートに実装できてしまいます。HTML側で変数(順番)を渡す仕組みにしておけば、要素の数が増減してもCSSの計算式を少し変更するだけで柔軟に対応可能です。
時計の文字盤だけでなく、円形のナビゲーションメニューや装飾など、デザインの幅を大きく広げてくれるテクニックなので、ぜひ皆さんのWeb制作でも活用してみてください!