【CSS】transformテクニック!要素を円形(時計状)に均等配置するレイアウト術

Webサイトを作っていると、「時計の文字盤」や「円形のメニュー」のように、要素をぐるっと円状に均等配置したい場面がありますよね。 昔はJavaScriptで複雑な三角関数(サイン・コサイン)の計算をしたり、一つ一つ手作業で位置を調整したりと大変でした。

しかし今のCSSなら、HTMLの「CSS変数(カスタムプロパティ)」と「transform」を組み合わせるだけで、簡単に、しかも美しく円形配置ができてしまいます!

今回は「時計の文字盤」を例に、要素数が変わっても応用できるようなCSSテクニックを解説します!

デモ動作

See the Pen CSS変数を活用した円形レイアウト by mikanbako (@mikanbako) on CodePen.

全画面でのデモ動作は以下のリンクからご確認下さい!(別タブで開かれます)

実装コード紹介

【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制作でも活用してみてください!

Prev
Next