
トグルボタンによるラジアルメニュー表示をCSSで実装する方法
CSSのtransformとjavascriptを使ってインタラクティブなラジアルトグルメニューを作ります。
scale(0)とscale(3)を行き来して円形メニューを拡大・縮小し、rotate(45deg)とrotate(0)を行き来してプラスマークを回転させます。
メニューとなるアイコンや画像はscale(3)の時に原寸になる様、元設定では3分の1でサイズ設定をしましょう。
トグルボタンで円形メニューが開くギミック
今回はトグルボタンを押す事で円形に並ぶメニュー(ラジアルメニュー)を表示させます。
JavaScriptとCSS3のtransformやtransitionを駆使して、インタラクティブなラジアルトグルメニューを構築します。
特にスマホ版のTOPページで画像アイコンの円形メニュ―として実装すれば、よりデザイン性が高まるでしょう。
実装サンプル
まずは実際に実装した事例サンプルをご紹介します。
ボタンを押した時に滑らかにメニューが出し入れできるのが特徴です。
各構成ソース
HTMLソース
<div class="wrap"> <div class="radialtoggle" id="toggle" onclick="expand()"> <i class="fa fa-plus" id="plus"></i> </div> <div class="radialmenu" id="menu"> <a href="#"><i class="fa fa-microphone"></i></a> <a href="#"><i class="fa fa-user"></i></a> <a href="#"><i class="fa fa-video-camera"></i></a> <a href="#"><i class="fa fa-envelope"></i></a> <a href="#"><i class="fa fa-camera"></i></a> <a href="#"><i class="fa fa-bell"></i></a> </div> </div>
まず全体をwrapで囲みます。
中にradialtoggleクラスを構成し、大き目のプラスマークのボタンを中央に絶対配置させるようにします。
このプラスマークをクリックした時に、メニューがいわゆる放射状に展開する訳です。
次に各円形メニューを表示するradialmenuクラスを用意します。
それぞれのメニュー項目は、aタグとawesomeアイコンで構成しているだけです。
CSS
ヘッダーで下記のcssを読み込みます。
<link rel="stylesheet" type="text/css" href="css/radialmenu.css">
詳細は「radialmenu.css」ファイル内を参照ください。
Javascript
下記コードを対象のHTMLタグより下で読み込みます。
<script src="js/radialmenu.js"></script>
上記のjsファイルに書かれている内容が以下になります。非常にシンプルですね。
javascript内コード
var i=0; function expand(){ if(i==0){ document.getElementById("menu").style.transform="scale(3)"; document.getElementById("plus").style.transform="rotate(45deg)"; i=1; } else{ document.getElementById("menu").style.transform="scale(0)"; document.getElementById("plus").style.transform="rotate(0deg)"; i=0; } }
javascriptコード進行
コード進行を大まかに説明します。まずは変数iを用意し、初期値として「0」を入れます。
変数が「0」でプラスボタンがクリックされた場合(if)
ID属性menuのついたクラスのスタイル「transform: scale」を0から3へ変更
ID属性plusのついたクラスのスタイル「transform: rotate」を0から45degへ変更
最後に変数iに「1」を代入します。
変数が「1」でプラスボタンがクリックされた場合(else)
ID属性menuのついたクラスのスタイル「transform: scale」を3から0へ変更
ID属性plusのついたクラスのスタイル「transform: rotate」を45degから0へ変更
変数iに「0」を代入します。
プラスボタンが押されるたびに変数に0と1とが交互に代入され、対応する動作を繰り返しているだけです。
ボタンとメニューの重なり順
まずはtoggleボタンと円形メニューの重なる順番を見てみましょう。
土台となるwrapクラスの上に、radialtoggle(ボタン部分)とradialmenu(メニュー部分)が絶対配置で乗っています。
それぞれの重なり順
radialtoggle(ボタン部分)は、z-indexを2に設定
radialmenu(メニュー部分)は、z-indexを1に設定
拡大・縮小するradialmenu部分に対し、常にradialtoggleボタンは「上」にある必要があります。
でないと、縮小した時にボタンの下に隠れる事ができません。
ですのでradialmenuはz-indexを1として、重なり順は常にtoggleボタンの方が上になる様にしています。
各メニューの配置
サンプルでは6つのメニューが表示されていますが、これらは全て「タグの記述順」ごとに絶対配置で位置を指定しています。
.radialmenu a:nth-child(1){ top: 3px; left: 42px; } .radialmenu a:nth-child(2){ top: 21px; left: 72px; } .radialmenu a:nth-child(3){ top: 52px; left: 72px; } .radialmenu a:nth-child(4){ top: 72px; left: 40px; } .radialmenu a:nth-child(5){ top: 52px; left: 7px; } .radialmenu a:nth-child(6){ top: 21px; left: 9px; }
1番最初の<a href="#"><i class="fa fa-microphone"></i></a>はa:nth-child(1)
…
1番最後の<a href="#"><i class="fa fa-bell"></i></a>はa:nth-child(6)
それぞれtopとleftで数値を入れていますので、ここは自由に変更してOKです。
プラスボタンが回転するギミック
radialtoggle内のプラスボタンには、ID属性plusが付いていますね。
<div class="radialtoggle" id="toggle" onclick="expand()"> <i class="fa fa-plus" id="plus"></i> </div>
.fa-plus{ font-size: 60px; color: white; display: block; margin-top: 20px; transition: 0.7s; }
ボタンを押したタイミングで、ID属性plusの付いたfa-plusクラスに対しtransform: rotate(45deg);のスタイルが追加されます。
javascript:変数iが0の時
document.getElementById("plus").style.transform="rotate(45deg)";
この時、fa-plusクラスに設定されたtransition: 0.7s;により回転が滑らかになっています。
もう一度クリックされると元の角度(0deg)に戻ります。
javascript:変数iが1の時
document.getElementById("plus").style.transform="rotate(0deg)";
円形メニューが開くギミック
円形メニューを実現している箇所が「radialmenu」の部分で、このタグにはID属性menuが付いています。
<div class="radialmenu" id="menu"> <a href="#"><i class="fa fa-microphone"></i></a> <a href="#"><i class="fa fa-user"></i></a> <a href="#"><i class="fa fa-video-camera"></i></a> <a href="#"><i class="fa fa-envelope"></i></a> <a href="#"><i class="fa fa-camera"></i></a> <a href="#"><i class="fa fa-bell"></i></a> </div>
格納時は幅と高さが100pxずつの円形になっており、同じサイズであるtoggleボタンの真下に隠れている様な状態です。
.radialmenu { background-color: white; height: 100px; width: 100px; transform: scale(0); border-radius: 50%; border-style: double; border-color: #7f8bc8; position: absolute; margin: auto; top: 0px; bottom: 0px; left: 0px; right: 0px; z-index: 1; transition: 0.7s; }
toggleボタンを押した時にこの円形メニューが広がるのですが、これは円形のサイズを「3倍」にする事で実現しています。
そのため、CSSの初期値では赤字の様にtransform: scale(0)に設定しています。
toggleボタンを押した際に、ID属性menuのscale(0)のスタイルをjavascriptで「scale(3)」に変更するのですね。
javascript:変数iが0の時
document.getElementById("menu").style.transform="scale(3)";
これによりradialmenuの円全体が3倍に大きくなります。
さらにtransition:0.7s;によるアニメーション効果により、円が3倍に広がる動きを滑らかにしています。
円形メニューが閉じるギミック
もう一度toggleボタンをクリックするとscale(3)に変更されたスタイルが、再度scale(0)に変更されます。
javascript:変数iが1の時
document.getElementById("menu").style.transform="scale(0)";
これによりプラスボタンと同じサイズになるので、真下に隠れるようになる訳です。
最初から円形メニューが展開されている様にするには
今回のサンプルでは円形メニューは初期状態だと格納されていますが、場合によっては最初から表示されていて欲しい時もあるでしょう。
その場合は以下の箇所を変更します。
radialmenuクラス部分のCSSを、transform: scale(3);「0」から「3」に変更
変数var i=には最初から「1」を入れる
最初から円形メニューをscale(3)で大きくしておき、javascriptの変数iを「1」からスタートするだけです。
プラスマークを45度から始めるには
プラスマークを最初から45度で始めるには、CSSのfa-plusクラスにtransform: rotate(45deg);を入れておくだけです。
.fa-plus{ font-size: 60px; color: white; display: block; transform: rotate(45deg); margin-top: 20px; transition: 0.7s; }
これで最初から45度傾いています。
つまり初期スタイルを「開いた状態のスタイル」にして、変数iに「1」を入れるだけですね。
結果2パターンの繰り返しになるので、「0→1」始まりが「1→0」始まりになるだけです。
微調整
ちょっとプラスマークが右に寄ってしまっているのが気になる様であれば、下記コードを追加してみるのもよいでしょう。
ifに追加(marginの調整)
document.getElementById("plus").style.margin="20px 0 0 -5px";
elseに追加(marginの調整)
document.getElementById("plus").style.margin="20px 0 0 0px";
これによりプラスマークの位置が少し移動するため、中央に配置されます。
画像を使った円形メニューサンプル
上のサンプルでは円形メニューを「アイコン」で表示していましたが、「画像」で構成するとより魅力的なメニューになります。
画像アイコンのHTMLソース
<div class="wrap"> <div class="radialtoggle" id="toggle2" onclick="expand2()"> <i class="fa fa-plus" id="plus2"></i> </div> <div class="radialmenu" id="menu2"> <a href="#"><img src="../images/css_radialmenu_img2.png" width="15" height="15" alt="menu"></a> <a href="#"><img src="../images/css_radialmenu_img3.png" width="15" height="15" alt="menu"></a> <a href="#"><img src="../images/css_radialmenu_img4.png" width="15" height="15" alt="menu"></a> <a href="#"><img src="../images/css_radialmenu_img5.png" width="15" height="15" alt="menu"></a> <a href="#"><img src="../images/css_radialmenu_img6.png" width="15" height="15" alt="menu"></a> <a href="#"><img src="../images/css_radialmenu_img7.png" width="15" height="15" alt="menu"></a> </div> </div>
サイズの設定に注意
画像をメニューアイコンにする場合、円形メニューが「展開された時」のサイズで画像を用意する事が必要です。
つまりtransformがscale(3)で拡大された時に、適切なサイズにならなければなりません。
上記の例ではそれぞれの画像アイコンはもともと、幅45px高さ45pxで作っています。
ボタンを押す前はscale(0)ですから、タグに設置する場合は3分の1サイズの「幅15px高さ15」で設定する必要がある訳です。
・scale(3)の時、幅45px高さ45px(原寸)
・scale(0)の時、幅15px高さ15px(3分の1)
CSSで指定する時も同様です。
格納時は3分の1サイズに加工する事
一番上のサンプルでも、6つのアイコンの元サイズはcssでは15pxに設定されています。
.radialmenu a { display: inline-block; position: absolute; font-size: 15px; //拡大時は45pxになる color: #BBBBBB; }
それがscale(3)に変更され3倍サイズ(45px)となり、あのサイズに見えている訳ですね。
プラスボタンの下に隠れている時は見えない訳ですから、あくまで「広がった時のサイズ」を基準に作成します。
その上でHTMLやCSSに記述する時は、それらが全て3分の1になる様に設定しましょう。
ラジアルメニューの使い方
この円形メニューを表示する場合、スマホ版のTOPページで使うのが効果的です。
通常のレスポンシブルメニューは出したまま、TOPページ上部にだけこのラジアルメニューを表示する訳です。
そうすればインパクトを出す事ができると思います。
スマホ版での実装の仕方(一例)
実装する場合は、上で説明した様に「最初からラジアルメニューが表示された状態」で始まる方が良いでしょう。
基本は一番外側のwrapクラスに対し、例えばdisplay: none;などで非表示に設定します。
次にメディアクエリ(max-width: 767px)の中で、display: block;として表示させましょう。
そうすればスマホ版でのみ表示がされます。
まとめ
以上、CSSとjavascriptを使ってトグルボタンでラジアルメニューを展開するギミックを実装する方法を紹介しました。
仕組み自体は非常に簡単ですのですぐに導入することができます。
特にスマホ版のTOPなどに使えば、インパクトを与える事ができると思いますので是非活用してみて下さい。