ここ最近主にナビゲーションなどでホバー時にアンダーラインをアニメーションさせるエフェクトの実装要望が多いので、パッと使えるようによく利用するものをひと通りまとめたのでシェアします。また、大体この手のアニメーションを利用する際はサイト全体で動きを統一させることが多いのですが、たまに場所によって少し違いをつけたいということもあるので、そういったときにすぐ対応できるようにSassのmixinを用いて実装する方法も併せて紹介します。
以下で紹介しているサンプルで使用しているHTMLは、すべて<a href="#">Lorem ipsum</a>
のようなシンプルなa
要素を使用した想定になっています。
CSS:ホバー時のアンダーラインアニメーションの実装サンプルとmixinを用いた実装方法 目次
1. Fade Top
ホバーするとテキスト下でアンダーラインが上からフェードインしてくるタイプのアニメーションで、実装にはCSSを下記をのように記述します。
CSS
a {
position: relative;
display: inline-block;
text-decoration: none;
}
a::after {
position: absolute;
bottom: 2px;
left: 0;
content: '';
width: 100%;
height: 2px;
background: #333;
opacity: 0;
visibility: hidden;
transition: .3s;
}
a:hover::after {
bottom: -4px;
opacity: 1;
visibility: visible;
}
2. Fade Bottom
先ほどとは逆に、ホバーするとテキスト下でアンダーラインが下からフェードインしてくるタイプのアニメーションで、実装にはCSSを下記をのように記述します。
CSS
a {
position: relative;
display: inline-block;
text-decoration: none;
}
a::after {
position: absolute;
bottom: -8px;
left: 0;
content: '';
width: 100%;
height: 2px;
background: #333;
opacity: 0;
visibility: hidden;
transition: .3s;
}
a:hover::after {
bottom: -4px;
opacity: 1;
visibility: visible;
}
3. Left to Right
ホバーするとアンダーラインが左から右に引かれる形で表示され、ホバーが外れるとまた左に戻っていくタイプのアニメーションで、実装にはCSSを下記をのように記述します。
CSS
a {
position: relative;
display: inline-block;
text-decoration: none;
}
a::after {
position: absolute;
bottom: -4px;
left: 0;
content: '';
width: 100%;
height: 2px;
background: #333;
transform: scale(0, 1);
transform-origin: left top;
transition: transform .3s;
}
a:hover::after {
transform: scale(1, 1);
}
4. Right to Left
こちらは先ほどとは逆に、ホバーするとアンダーラインが右から左に引かれる形で表示され、ホバーが外れるとまた右に戻っていくタイプのアニメーションで、実装にはCSSを下記をのように記述します。
CSS
a {
position: relative;
display: inline-block;
text-decoration: none;
}
a::after {
position: absolute;
bottom: -4px;
left: 0;
content: '';
width: 100%;
height: 2px;
background: #333;
transform: scale(0, 1);
transform-origin: right top;
transition: transform .3s;
}
a:hover::after {
transform: scale(1, 1);
}
5. Left in Right
ホバーすると左から右にラインが引かれる形で表示されますが、こちらはホバーが外れた場合に左に戻らず右に向かって非表示になるというタイプのアニメーションです。
実装にはCSSを下記をのように記述します。
CSS
a {
position: relative;
display: inline-block;
text-decoration: none;
}
a::after {
position: absolute;
bottom: -4px;
left: 0;
content: '';
width: 100%;
height: 2px;
background: #333;
transform: scale(0, 1);
transform-origin: right top;
transition: transform .3s;
}
a:hover::after {
transform-origin: left top;
transform: scale(1, 1);
}
6. Right in Left
こちらは先ほどとは逆で、ホバーすると右から左にラインが引かれる形で表示され、ホバーが外れた場合に右に戻らず左に向かって非表示になるというタイプのエアニメーションです。
実装にはCSSを下記をのように記述します。
CSS
a {
position: relative;
display: inline-block;
text-decoration: none;
}
a::after {
position: absolute;
bottom: -4px;
left: 0;
content: '';
width: 100%;
height: 2px;
background: #333;
transform: scale(0, 1);
transform-origin: left top;
transition: transform .3s;
}
a:hover::after {
transform-origin: right top;
transform: scale(1, 1);
}
7. Center
ホバーすると中央から左右に向かってラインが引かれるタイプのアニメーションで、実装にはCSSを下記をのように記述します。
CSS
a {
position: relative;
display: inline-block;
text-decoration: none;
}
a::after {
position: absolute;
bottom: -4px;
left: 0;
content: '';
width: 100%;
height: 2px;
background: #333;
transform: scale(0, 1);
transform-origin: center top;
transition: transform .3s;
}
a:hover::after {
transform: scale(1, 1);
}
8. mixin
上で全7種類のアンダーラインアニメーションを紹介してきましたが、以下はこれらを必要に応じて簡単に使用できるようにしたmixinになります。
こういったアニメーションなどは大体サイト内で揃えることが多いですが、たまに場所によって少し動きを変えたいときがあるので、そういったときに便利かと思います。
mixin
SCSS
@mixin hover-underline($type: fade, $dir: null, $weight: 2px, $color: #000) {
@if $dir == null {
@if $type == fade {
$dir: 'top';
} @else if $type == slide {
$dir: 'center';
}
}
position: relative;
display: inline-block;
text-decoration: none;
&::after {
position: absolute;
left: 0;
content: '';
width: 100%;
height: $weight;
background: $color;
@if $type == fade {
transition: .3s;
opacity: 0;
visibility: hidden;
@if $dir == bottom {
bottom: $weight * -4;
} @else {
bottom: $weight;
}
} @else if $type == slide {
bottom: $weight * -2;
transform: scale(0, 1);
transition: transform .3s;
@if $dir == left-right or $dir == right-in-left {
transform-origin: left top;
} @else if $dir == right-left or $dir == left-in-right {
transform-origin: right top;
} @else {
transform-origin: center top;
}
}
}
&:hover::after {
@if $type == fade {
bottom: $weight * -2;
opacity: 1;
visibility: visible;
} @else if $type == slide {
@if $dir == left-in-right {
transform-origin: left top;
} @else if $dir == right-in-left {
transform-origin: right top;
}
transform: scale(1, 1);
}
}
}
全体的に条件分岐多めで冗長な感じになってますが、上で紹介した7種類のアンダーラインアニメーションを上記mixinで簡単に利用できるようになり、アニメーション指定に利用するものとして下記4つの引数があります。
それぞれに特定の値を指定することで使用したいアニメーションを呼び出すことができ、主に$type
と$dir
で指定された値と条件分岐を使って出力内容が変わるようになっています。
$type
(タイプ)$dir
(方向)$weight
(ラインウェイト)$color
(ラインカラー)
それぞれの引数について説明すると、ひとつ目の$type
はアニメーションのタイプを指定するもので、上で紹介した「Fade Top」と「Fade Bottom」がfade
、それ以外の「Left to Right」~「Center」までがslide
という形で大きく分類しており、初期値はfade
を指定しています。
ふたつ目の$dir
ではアニメーションの方向を指定し、ここは$type
で指定した値によって指定できるものが異なります。$type
でfade
を指定した場合はtop
かbottom
を、$type
でslide
を指定した場合はleft-right
, left-in-right
, right-left
, right-in-left
, center
のいずれかを指定します。$dir
の初期値はnull
を設定しており、もし指定されなかった場合はデフォルトの動きとして$type
をfade
にしていれば「Fade Top」が、$type
をslide
にしていれば「Center」が適用されるような形にしてあります。
また、間違った指定(例えばfade
でleft-right
を指定するなど)をした場合でも、何も指定されなかったときと同じようにデフォルトの動きが適用されます。
みっつ目の$weight
はラインウェイトを指定(初期値は2px
)するもので、ここで指定した値は単純にラインの太さのために使用するだけでなく表示位置の調整などにも利用しています。
最後の$color
については、そのままラインカラーを指定(初期値は#000
)するものになります。
実際にmixinを使用する場合は、それぞれ下記のように記述していきます。
下記はすべて$weight
と$color
の指定は省略したものになりますので、必要であれば例えば@include hover-underline('fade', 'top', 4px, #aaa);
のような形で追記してください。
usage
SCSS
// Fade Top
.example01 a {
@include hover-underline('fade', 'top');
}
// Fade Bottom
.example02 a {
@include hover-underline('fade', 'bottom');
}
// Left to Right
.example03 a {
@include hover-underline('slide', 'left-right');
}
// Right to Left
.example04 a {
@include hover-underline('slide', 'right-left');
}
// Left in Right
.example05 a {
@include hover-underline('slide', 'left-in-right');
}
// Right in Left
.example06 a {
@include hover-underline('slide', 'right-in-left');
}
// Center
.example07 a {
@include hover-underline('slide', 'center');
}
※「Fade Top」は@include hover-underline;
、「Center」は@include hover-underline('slide');
でも呼び出せます。
以下はこのmixinを用いて指定しているデモで、CodePenなので実際の表示確認するだけでなくちょっとコードを変更して試すこともできます。
以上、ホバー時のアンダーラインアニメーションの実装サンプルとそれらを簡単に呼び出すためのmixinの紹介でした。
mixinに関しては条件分岐多めだったりでもっとスマートに書けそうな感じがすごいので、もっと良い感じに書ける方法をご存知の方は是非教えてください。
ちなみに、ここで紹介してきたものはすべてアンダーラインのみという形でしたが、疑似要素を増やすことで上下にラインを表示させたり、それぞれ違う方向からラインを引くといったことも可能になります。
以前にもこのようなエフェクトの実装方法を紹介しており、ここで紹介しているものとはtransform
の使い方などが若干異なりますが、それらの実装方法については以下を参考にしてみてください。