今回のお題は、ボタンが立体的に並んだナビゲーションバーだ(サンプル1 ) 。マウスポインタを重ねると、ボタンが飛び出す。「 Navigation Bar by Jan Kaděra 」のデザインとアニメーションをもとに、わかりやすく組み立て直した。3次元の動きで、ボタンの数も多い。少しやっかいそうに感じたかもしれない。ところが、思いのほかコードはたやすい。
サンプル1 CSS3: 3D style navigation bar
平面的なナビゲーションバー
まずは<head>
要素にいくつか仕込みをしておこう。ボタンのアイコンにはFont Awesomeを使うので、つぎのようにCDNを読み込む(第15回の「アイコンWebフォントを使う 」参照) 。おなじみの-prefix-freeも加える。そして、今回はリセットCSSを用いた。ブラウザによって異なるデフォルトをリセットすることで、表現が揃えられる。広く使われているのは、Eric Meyer氏のCSS だ(「 2016年で最もダウンロードされたリセットCSSランキングトップ5 」 ) 。CDNはcdnjsのmeyer-reset から読み込んだ。
<head>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
</head>
HTMLのコードはつぎに示す簡素なつくりだ。<ul>
要素(class
属性"nav-bar")の中にボタンを、要素<li>
と<a>
(class
属性"list-item")の入れ子で加えた。そこにFont Awesomeのアイコンが入っている。
<body>要素
<ul class="nav-bar">
<li>
<a class="list-item" href="#">
<i class="fa fa-bars"></i>
</a>
</li>
<li>
<a class="list-item" href="#">
<i class="fa fa-th-large"></i>
</a>
</li>
<li>
<a class="list-item" href="#">
<i class="fa fa-bar-chart"></i>
</a>
</li>
<li>
<a class="list-item" href="#">
<i class="fa fa-tasks"></i>
</a>
</li>
<li>
<a class="list-item" href="#">
<i class="fa fa-bell"></i>
</a>
</li>
<li>
<a class="list-item" href="#">
<i class="fa fa-archive"></i>
</a>
</li>
<li>
<a class="list-item" href="#">
<i class="fa fa-comment"></i>
</a>
</li>
<li>
<a class="list-item" href="#">
<i class="fa fa-sitemap"></i>
</a>
</li>
<li>
<a class="list-item" href="#">
<i class="fa fa-thumbs-up"></i>
</a>
</li>
<li>
<a class="list-item" href="#">
<i class="fa fa-tumblr"></i>
</a>
</li>
</ul>
これにつぎのCSSを割り当てると、2次元で影をつけた平坦なナビゲーションバーができ上がる(図1 ) 。擬似要素と変形を加えて立体的にしていく。
* {
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
background: #f2f2f2;
}
li {
list-style: none;
}
.list-item {
background: #000;
color: #575757;
text-align: center;
height: 2.5em;
width: 4em;
line-height: 2.5em;
border-bottom: 1px solid #060606;
position: relative;
display: block;
box-shadow : -2em 1.5em 0 #e1e1e1;
}
図1 擬似要素と変形を加える前のナビゲーションバー
ナビゲーションバーを3次元風に見せる
今回のお題のミソは、3次元の変形を使わないということだ。前掲サンプル1 をよくよく眺めれば、パース(遠近法)がかかっていない。擬似要素::before
と::after
で、ナビゲーションバーの側面に見える部分を、つぎのCSSのとおりtransform
プロパティで2次元に変形して加える(図2 ) 。傾斜は関数skewX()
とskewY()
で、それぞれの軸方向に傾ける角度を渡す。
.list-item::before,
.list-item::after {
content: "";
position: absolute;
width: 0.5em;
}
.list-item::after {
height: 4em;
background: #181818;
bottom: -2.25em;
left: 1.5em;
transform : rotate (90deg) skewY 45deg);
}
.list-item::before {
height: 2.5em;
background: #121212;
top: .25em;
left: -0.5em;
transform : skewY (-45deg);
}
図2 擬似要素でナビゲーションバーの側面を加えた
そのうえで、ナビゲーションバー全体の要素(class
属性"nav-bar")をつぎのように斜めに傾けて、立体的に見せる(図3 ) 。なお、関数skew()
を用いると、xとyのふたつの引数が渡せる。だが、最近の仕様からは除かれた。ブラウザによっては実装が残っているものの、使わない方がよい。動きを加える前の、立体風に見えるナビゲーションバーのCSSの定めは、以下のコード1 にまとめた。
.nav-bar {
transform : rotate (-35deg) skewX (20deg) skewY (5deg);
}
図3 立体風になったナビゲーションバー
コード1 立体風のナビゲーションバー
* {
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
background: #f2f2f2;
}
.nav-bar {
transform : rotate (-35deg) skewX (20deg) skewY (5deg);
}
li {
list-style: none;
}
.list-item {
background: #000;
color: #575757;
text-align: center;
height: 2.5em;
width: 4em;
line-height: 2.5em;
border-bottom: 1px solid #060606;
position: relative;
display: block;
box-shadow : -2em 1.5em 0 #e1e1e1;
}
.list-item::before,
.list-item::after {
content: "";
position: absolute;
width: 0.5em;
}
.list-item::after {
height: 4em;
background: #181818;
bottom: -2.25em;
left: 1.5em;
transform : rotate (90deg) skewY (45deg);
}
.list-item::before {
height: 2.5em;
background: #121212;
top: .25em;
left: -0.5em;
transform : skewY (-45deg);
}
マウスポインタが重なったときのアニメーションを加える
それぞれのボタンの
要素(class
属性"list-item")にマウスポインタを重ねたら(:hover
擬似クラス) 、つぎのように位置や大きさを変えることにより、飛び出したように見せる(図4 ) 。影もそれに合わせて動かした。
.list-item:hover {
background: #ff6e42;
color: #fffcfb;
transform : translate (0.9em, -0.9em);
box-shadow : -2em 2em 0 #e1e1e1;
}
.list-item:hover::before {
background: #b65234;
width: 1em;
top: 0.5em;
left: -1em;
}
.list-item:hover::after {
background: #b65234;
width: 1em;
bottom: -2.5em;
left: 1em;
height: 4em;
}
図4 マウスポインタを重ねると飛び出して見える
あとは、つぎのようにtransition
プロパティで滑らかなアニメーションにすればよい。機械的な動きにするため、タイミング関数はlinear
を用いた。書き上がったCSSの定めは、以下のコード2 にまとめた。
.list-item {
transition : 0.25s linear;
}
.list-item::before,
.list-item::after {
transition : 0.25s linear;
}
コード2 マウスポインタを重ねるとボタンが飛び出す3D風のナビゲーションバー
* {
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
background: #f2f2f2;
}
.nav-bar {
transform : rotate (-35deg) skewX (20deg) skewY (5deg);
}
li {
list-style: none;
}
.list-item {
background: #000;
color: #575757;
text-align: center;
height: 2.5em;
width: 4em;
line-height: 2.5em;
border-bottom: 1px solid #060606;
position: relative;
display: block;
box-shadow : -2em 1.5em 0 #e1e1e1;
transition : 0.25s linear;
}
.list-item:hover {
background: #ff6e42;
color: #fffcfb;
transform : translate (0.9em, -0.9em);
box-shadow : -2em 2em 0 #e1e1e1;
}
.list-item:hover::before {
background: #b65234;
width: 1em;
top: 0.5em;
left: -1em;
}
.list-item:hover::after {
background: #b65234;
width: 1em;
bottom: -2.5em;
left: 1em;
height: 4em;
}
.list-item::before,
.list-item::after {
content: "";
position: absolute;
width: 0.5em;
transition : 0.25s linear;
}
.list-item::after {
height: 4em;
background: #181818;
bottom: -2.25em;
left: 1.5em;
transform : rotate (90deg) skewY (45deg);
}
.list-item::before {
height: 2.5em;
background: #121212;
top: .25em;
left: -0.5em;
transform : skewY (-45deg);
}