Edited at

[簡単]コピペするだけ!ナビゲーションホバーエフェクト

More than 1 year has passed since last update.

自分のメモも含めて、最近よく見かけるナビゲーションのホバーエフェクトをまとめてみました。

css:DEMO

scss:DEMO

cssのみで記述されたシンプルなものになります。

scssでも実装してみましたが、今回は初心者の方向けにCSSで記述したもので解説していきます!


共通HTML・CSS


HTML

<nav class="type1">

<ul class="type1-menu">
<li><a href="#">HOME</a></li>
<li><a href="#">ABOUT</a></li>
<li><a href="#">WORKS</a></li>
<li><a href="#">CONTACT</a></li>
</ul>
</nav>

通常のナビゲーションをマークアップします。


CSSをいじる前に…

リセットCSSを設置!

Chrome・IEなどのブラウザによってデフォルトでCSSを持っているので、全てフラットになるようReset CSSを設定します。

公式ページからコピペするか、headタグ内に下記(cdn)を追加してください。

https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css

別のリセットcssを使用してる場合はお手数ですが、調整をお願いします。


CSS

nav ul {

display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: wrap;
}
nav ul li {
margin-right: 1rem;
}
nav ul li a {
display: block;
padding: 10px;
color: #000000;
text-decoration: none;
}

横並びしたいリストの親要素にdisplay: flex;を付与します。


type1 - 下からにゅっと出てくるエフェクト

type1.gif


CSS

.type1 .type1-menu a {

position: relative;
}
.type1 .type1-menu a::after {
position: absolute;
left: 0;
bottom: 0;
display: block;
content: "";
width: 0%;
height: 2px;
background: #000;
transition: all 0.2s cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
.type1 .type1-menu a:hover::after {
width: 100%;
}

hoverしたときに現れるラインは疑似要素のafterでスタイリングします。:hoverとごちゃごちゃにならないようコロンは2つで記述してます。(コロン1つでもOKです!)

hover前はラインのwidthを0%、hover後はwidthを100%に変更するだけですね!


type2 - ラインが左から右に駆け抜けるエフェクト

type2.gif


CSS

.type2 .type2-menu a {

position: relative;
border-bottom: 2px solid #b2b2b2;
}
.type2 .type2-menu a::after {
position: absolute;
bottom: -2px;
left: 0;
display: block;
content: "";
width: 100%;
height: 2px;
background: #000000;
transform: scaleX(0);
transform-origin: right top;
transition: transform 0.3s;
}
.type2 .type2-menu a:hover::after {
transform: scaleX(1);
transform-origin: left top;
}

通常時の下のラインはaタグにborder-bottomを付与します。

こちらもtype1と同じよう、hoverしたとき疑似要素::afterにスタイリングします。

ポイントとなるのはtransform: scaleX(数値);transform-origin;です。

transform: scaleX(数値);でラインを拡大縮小で表示させるのですが、これだけだとラインのセンターからの拡大縮小になります。↓↓

sample.gif

そこで、transform-originで要素の原点を決めてあげます!

hoverしたとき左からラインが流れてほしいので「.type2 .type2-menu a:hover::after」にtransform-origin: left top;、

hoverを外した時にラインが右に流れてほしいので「.type2 .type2-menu a::after」にtransform-origin: right top;を指定します。

また、CSSアニメーションのtransitionにはtransformだけ指定します。

transition: all 0.3s;と記述すると動きがおかしくなります。(実際に私ははしょらせておかしくなりました...泣)


type3 - 取り消し線エフェクト

type3.gif


CSS

.type3 .type3-menu a {

position: relative;
}
.type3 .type3-menu a::after {
position: absolute;
left: 0;
top: 50%;
bottom: 50%;
transform: translate(0, -50%);
display: block;
content: "";
width: 0%;
height: 2px;
background: #000000;
transition: all 0.2s cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
.type3 .type3-menu a:hover::after {
width: 100%;
}

type1のラインの位置を変えただけです!

上下中央になるよう疑似要素::afterに下記のプロパティを追加しました。

top: 50%;

bottom: 50%;

transform: translate(0, -50%);


type4 - ホバー時に日本語表記になるエフェクト

type4.gif


HTML

共通HTMLに少々変更が入ります。

<nav class="type4">

<h2>type4</h2>
<ul class="type4-menu">
<li>
<a href="#">
<span class="en">HOME</span>
<span class="ja">ホーム</span>
</a>
</li>
<li>
<a href="#">
<span class="en">ABOUT</span>
<span class="ja">ページについて</span>
</a>
</li>
<li>
<a href="#">
<span class="en">WORKS</span>
<span class="ja">作品</span>
</a>
</li>
<li>
<a href="#">
<span class="en">CONTACT</span>
<span class="ja">お問合わせ</span>
</a>
</li>
</ul>
</nav>

英語と日本語を表示させたいので、aタグの中にそれぞれspanタグを設置します。


CSS

.type4 .type4-menu a {

position: relative;
text-align: center;
overflow: hidden;
padding: 10px 22px; //メニューに入るテキスト量によってpaddingは変更してください
}
.type4 .type4-menu a::after {
position: absolute;
bottom: 0;
left: 0;
display: block;
content: "";
width: 0%;
height: 2px;
background: #F05152;
transition: all 0.2s cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
.type4 .type4-menu a span {
display: block;
width: 100%;
margin: 0 auto;
transition: all 0.2s cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
.type4 .type4-menu a span.ja {
position: absolute;
top: 100%;
left: 0%;
font-size: 14px;
font-weight: bold;
white-space: nowrap;
color: #F05152;
}
.type4 .type4-menu a:hover::after {
width: 100%;
}
.type4 .type4-menu a:hover span.en {
transform: translate(0%, -150%);
}
.type4 .type4-menu a:hover span.ja {
top: 25%;
}

下からラインが現れるのはtype1の流用ですね!色だけ変更してます。

「span.ja」は通常時見えないようtop: 100%;で下にずらします。

親要素である「.type4 .type4-menu a」にoverflow: hidden;を付与してるのでその領域外からはみ出た「span.ja」は見えなくなってると思います。

hoverさせたとき、英語表記の「span.en」はtransform: translate(0% -150%);で上にずらし、日本語表記の「span.ja」はtopの値を変更します。


type5 - ラインで四方を囲うエフェクト

type5.gif


CSS

.type5 .type5-menu li {

position: relative;
overflow: hidden;
}
.type5 .type5-menu li::before,
.type5 .type5-menu li::after {
position: absolute;
display: block;
content: "";
width: 100%;
height: 1px;
background: #000000;
transition: all 0.2s cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
.type5 .type5-menu li::before {
top: 0;
left: -100%;
}
.type5 .type5-menu li::after {
bottom: 0;
right: -100%;
}
.type5 .type5-menu li a::before,
.type5 .type5-menu li a::after {
position: absolute;
display: block;
content: "";
width: 1px;
height: 100%;
background: #000000;
transition: all 0.2s cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
.type5 .type5-menu li a::before {
top: 100%;
left: 0;
}
.type5 .type5-menu li a::after {
top: -100%;
right: 0;
}
.type5 .type5-menu li:hover::before {
left: 0;
}
.type5 .type5-menu li:hover::after {
right: 0;
}
.type5 .type5-menu li a:hover::before {
top: 0;
}
.type5 .type5-menu li a:hover::after {
top: 0;
}

ラインそれぞれにスタイルをつけるので記述がやや長くなります。

liとaに疑似要素::beforeと::afterをつけてます。

.type5 .type5-menu li::before  → 上線

.type5 .type5-menu li::after  → 下線

.type5 .type5-menu li a::before → 左線

.type5 .type5-menu li a::after  → 右線

こちらもpositionでそれぞれのラインの位置をずらしておきます。

type4と同じよう親要素の「.type5 .type5-menu li」にoverflow: hidden;を付与して、はみ出た部分は見えないようにします。

hoverしたときはラインが見える位置にtopやrightの数値をいじって戻す感じですね!


type6 - ラインでなぞるようなエフェクト

type6.gif


CSS

.type6 .type6-menu li {

position: relative;
overflow: hidden;
}
.type6 .type6-menu li::before,
.type6 .type6-menu li::after {
position: absolute;
display: block;
content: "";
width: 100%;
height: 1px;
background: #000000;
transition: all 0.2s cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
.type6 .type6-menu li::before {
top: 0;
left: -100%;
}
.type6 .type6-menu li::after {
bottom: 0;
right: -100%
}
.type6 .type6-menu li a::before,
.type6 .type6-menu li a::after {
position: absolute;
display: block;
content: "";
width: 1px;
height: 100%;
background: #000000;
transition: all 0.2s cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
.type6 .type6-menu li a::before {
top: 100%;
left: 0;
}
.type6 .type6-menu li a::after {
top: -100%;
right: 0;
}
.type6 .type6-menu li:hover::before {
animation: topline 0.1s linear forwards;
}
@keyframes topline {
0% {
left: -100%;
}
100% {
left: 0;
}
}
.type6 .type6-menu li:hover::after {
animation: btmline 0.1s linear forwards 0.2s;
}
@keyframes btmline {
0% {
right: -100%
}
100% {
right: 0;
}
}
.type6 .type6-menu li:hover a::before {
animation: leftline 0.1s linear forwards 0.3s;
}
@keyframes leftline {
0% {
top: 100%;
}
100% {
top: 0;
}
}
.type6 .type6-menu li:hover a::after {
animation: rightline 0.1s linear forwards 0.1s;
}
@keyframes rightline {
0% {
top: -100%;
}
100% {
top: 0;
}
}

ほぼtype5と同じです。アニメーションの手法が違うだけです。

リンクをなぞるようにラインを動かすのですがkeyframesを使い、順番に表示させます。

下記は右線の「.type6 .type6-menu li:hover a::after」をhoverしたときの記述です。

562572cba4ded3567703bac920e2f564.png

ポイントはdelayになります。

それぞれのラインを0.1sごとに表示させたいのでdelay値は以下になります。

.type6 .type6-menu li::before(上線) → delayさせる必要がないので指定なし

.type6 .type6-menu li::after(下線)  → 0.2s

.type6 .type6-menu li a::before(左線) → 0.3s

.type6 .type6-menu li a::after(右線)  → 0.1s


まとめ

デザインの制作はできたけど、hoverしたときの挙動をどうしよう。。となったときに参考にしてみてください。

ものによってはボタンにも適応できます👌

最後まで読んでいただきありがとうございました!

css:DEMO

scss:DEMO