CSS3のtransitionプロパティを使うと、プロパティの値をアニメーションで切替えることができます。tobypitman.com「Dynamic CSS3 Animated Accordian Menu」を参考に、アコーディオンメニューをつくりました。コードの行数はわかりやすいように減らし、手直ししたサンプルで仕組みをご説明します(サンプル001)。JavaScriptコードは書きません。
サンプル001■CSS3: Accordion menu
01 開いたメニューのデザイン
メニューはつぎのようにリストで組立てます。body要素に加えるコードは以下のとおりです。メインメニューのa要素には、id属性が与えてあります。
- JavaScript
- JavaScriptリファレンス
- CreateJS Docs (英語)
- jQueryリファレンス
- Web標準
- CSSリファレンス
- HTML 5.1 Nightly (英語)
- Close
<div id="wrap">
<ul class="menu">
<li class="title"><a id="menu01" href="#menu01"><span>JavaScript</span></a>
<ul>
<li><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference" target="_blank">JavaScriptリファレンス</a></li>
<li><a href="http://www.createjs.com/#!/Docs" target="_blank">CreateJS Docs (英語)</a></li>
<li><a href="http://semooh.jp/jquery/" target="_blank">jQueryリファレンス</a></li>
</ul>
</li>
<li class="title"><a id="menu02" href="#menu02"><span>Web標準</span></a>
<ul>
<li><a href="https://developer.mozilla.org/ja/docs/Web/CSS/Reference?redirectlocale=ja&redirectslug=Web%2FCSS%2FCSS_Reference" target="_blank">CSSリファレンス</a></li>
<li><a href="http://www.w3.org/html/wg/drafts/html/master/" target="_blank">HTML 5.1 Nightly (英語)</a></li>
</ul>
</li>
<li class="title"><a id="bottom" href="#"><span>Close</span></a>
</li>
</ul>
</div>
|
まずは、開いたメニューをデザインするため、後に掲げるコード001のCSSを定めます。サブメニューのa要素に:hover擬似クラスを定めましたので、マウスポインタを重ねるとその項目がハイライトします(図001)。
- .title ul li a:hover {
- background: lightsteelblue;
- }
|
図001■開いたメニューの項目がロールオーバーでハイライトする
メニュー(クラスmenu)に定めたスタイルについて、以下に抜書きして補います。border-radiusプロパティはボーダーの角を丸めます(第19行目)。また、box-shadowプロパティは、つぎのような構文で影を加えます(第23行目)。
box-shadow: 水平のずれ 垂直のずれ ぼかしの大きさ 影色
そして、backgroundプロパティに与えたlinear-gradient()関数が、色の線形グラデーションを定めます(第22行目)[*1]。メニューが閉じた状態で見るとわかりやすいでしょう(図002)。メインメニュー項目の上から下に向けて、背景色にグラデーションがかかります。
linear-gradient(to 終点, 開始色, 終了色)
図002■メインメニューの項目にまたがって背景色にグラデーションがかかる
- .menu {
- border-radius: 20px;
- background: linear-gradient(to bottom, whitesmoke, silver);
- box-shadow: 0px 4px 10px darkgray;
- }
|
ここまでの開いたメニューのstyle要素をまとめたのが、以下のコード001です。ロールオーバーのハイライトも、クリックしたときのリンクもすでに定められています。
コード001■開いたメニューとロールオーバーのデザインを定める
- *{
- margin: 0;
- padding: 0;
- }
- body {
- text-align: center;
- font: 14px sans-serif;
- }
- #wrap {
- margin: 50px auto 0 auto;
- width: 200px;
- text-align: left;
- }
- a {
- text-decoration: none;
- }
- .menu {
- width: 200px;
- border-radius: 20px;
- list-style: none;
- border: 1px solid darkgray;
- background: linear-gradient(to bottom, whitesmoke, silver);
- box-shadow: 0px 4px 10px darkgray;
- }
- .title {
- overflow: hidden;
- border-top: 1px solid white;
- }
- .menu li.title:first-child {
- border-top: none;
- }
- .title a span {
- display:block;
- padding:10px 10px 10px 20px;
- color: black;
- }
- .title ul li a {
- display: block;
- padding-left: 20px;
- line-height: 30px;
- text-decoration: none;
- font-size: 14px;
- background: white;
- color: darkslategray;
- }
- .title ul li a:hover {
- background: lightsteelblue;
- color: black;
- }
- .title ul li a {
- display: block;
- }
- #bottom span {
- font-size: 10px;
- padding: 10px 10px 10px 20px;
- }
|
02 開けるサブメニューをターゲット要素から捉える
つぎに、メインメニューのクリックでサブメニューを開きます。このとき、ターゲット要素を使うので、a要素にそれぞれid属性を与え、対応したターゲットをhref属性に定めました。
<ul class="menu">
<li class="title"><a id="menu01" href="#menu01"><span>JavaScript</span></a>
<li class="title"><a id="menu02" href="#menu02"><span>Web標準</span></a>
</ul>
|
予めサブメニューは閉じておくので、以下のようにサブメニューのa要素はheightを0にしておきます(第50〜51行目)。そのうえで、メインメニューをクリックしたときに、そのサブメニューを開くようにします。
メインメニューをクリックすると、そのa要素のhref属性に定めたターゲットがURL(URI)に識別子として加わります。このとき、識別子が示す要素は、:target擬似クラスで表せるのです。そして、隣接セレクタ+により、その後のul要素つまりサブメニューのa要素のheightプロパティが拡げられます(第54〜56行目)。
- .title ul li a {
- height: 0px;
- }
- :target + ul li a {
- height: 30px;
- }
|
こうして、クリックした項目のサブメニューが開きます(図004)。ここまでのstyle要素をまとめたのが、以下のコード002です。もっとも、サブメニューはいきなり開くので、まだアコーディオンの動きにはなっていません。
図003■クリックした項目のサブメニューが開く
コード002■クリックしたターゲット要素のつぎのリストのサブメニューを開く
- *{
- margin: 0;
- padding: 0;
- }
- body {
- text-align: center;
- font: 14px sans-serif;
- }
- #wrap {
- margin: 50px auto 0 auto;
- width: 200px;
- text-align: left;
- }
- a {
- text-decoration: none;
- }
- .menu {
- width: 200px;
- border-radius: 20px;
- list-style: none;
- border: 1px solid darkgray;
- background: linear-gradient(to bottom, whitesmoke, silver);
- box-shadow: 0px 4px 10px darkgray;
- }
- .title {
- overflow: hidden;
- border-top: 1px solid white;
- }
- .menu li.title:first-child {
- border-top: none;
- }
- .title a span {
- display:block;
- padding:10px 10px 10px 20px;
- color: black;
- }
- .title ul li a {
- display: block;
- padding-left: 20px;
- line-height: 30px;
- text-decoration: none;
- font-size: 14px;
- background: white;
- color: darkslategray;
- }
- .title ul li a:hover {
- background: lightsteelblue;
- color: black;
- }
- .title ul li a {
- height: 0px;
- display: block;
- }
- :target + ul li a {
- height: 30px;
- }
- #bottom span {
- font-size: 10px;
- padding: 10px 10px 10px 20px;
- }
|
03 transitionプロパティでメニューの開け閉めをアニメーションさせる
では、img要素に画像のsrc属性をつぎのように加えます。ボタンのリストについては、前掲のコードのまま変えていません。
transitionプロパティを使えば、アニメーションでopacityプロパティの値が変えられます。transitionに定めるもっとも基本的な値は、つぎのようにアニメーションの時間、および変化のタイミング関数のふたつです(「CSS transition の使用」参照)。タイミング関数は値の変わり方を決め、キーワードから選べます(図004)。
transition: 時間 タイミング関数
図004■タイミング関数のキーワードと値の変化
linear
|
|
|
ease
(デフォルト)
|
|
ease-in
|
|
|
ease-in-out
|
|
ease-out
|
|
|
step-start
|
|
step-end
|
|
|
|
|
サブメニューのa要素には、つぎのようにtransitionプロパティの定めを加えました(第53行目)。タイミング関数のease-in-outは、デフォルトのeaseより初めと終わりのカーブがなだらかです(前掲図004)。
- .title ul li a {
- height: 0px;
- transition: 0.5s ease-in-out;
- }
- :target + ul li a {
- height: 30px;
- }
|
これでアコーディオンメニューの動きができました。メインメニューをクリックすると、アコーディオンのようにサブメニューが広がります。書上げたstyle要素は、つぎにまとめたコード003のとおりです。このコードを前掲サンプル001に定めました。
コード003■クリックしたターゲット要素のつぎのリストをアニメーションで開く
- *{
- margin: 0;
- padding: 0;
- }
- body {
- text-align: center;
- font: 14px sans-serif;
- }
- #wrap {
- margin: 50px auto 0 auto;
- width: 200px;
- text-align: left;
- }
- a {
- text-decoration: none;
- }
- .menu {
- width: 200px;
- border-radius: 20px;
- list-style: none;
- border: 1px solid darkgray;
- background: linear-gradient(to bottom, whitesmoke, silver);
- box-shadow: 0px 4px 10px darkgray;
- }
- .title {
- overflow: hidden;
- border-top: 1px solid white;
- }
- .menu li.title:first-child {
- border-top: none;
- }
- .title a span {
- display:block;
- padding:10px 10px 10px 20px;
- color: black;
- }
- .title ul li a {
- display: block;
- padding-left: 20px;
- line-height: 30px;
- text-decoration: none;
- font-size: 14px;
- background: white;
- color: darkslategray;
- }
- .title ul li a:hover {
- background: lightsteelblue;
- color: black;
- }
- .title ul li a {
- height: 0px;
- display: block;
- transition: 0.5s ease-in-out;
- }
- :target + ul li a {
- height: 30px;
- }
- #bottom span {
- font-size: 10px;
- padding: 10px 10px 10px 20px;
- }
|
作成者: 野中文雄
作成日: 2015年1月28日