20
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-03-16

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

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

20
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?