Help us understand the problem. What is going on with this article?

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

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

s_nitta
株式会社インプレッシブ/webデザイナー/ コーディング技術はまだまだ駆け出し
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした