2025 07 . 04 FRI

CSSマスクとhover効果でインタラクティブなテキストアニメーションを実装する

2025.06.26

このサイトはアフィリエイト広告を利用しています。

はじめに

Webサイトでユーザーの注意を引くインタラクティブな要素として、hover時にテキストが切り替わるアニメーションは非常に効果的です。CSSのmaskプロパティを使用することで、複雑なJavaScriptを書くことなく、エレガントなテキスト切り替え効果を実現できます。

本記事では、hover時に表示中のテキストをマスクで隠し(mask-out)、別のテキストをマスクで表示する(mask-in)テクニックを、実際に操作できるデモとともに解説します。

実際のデモ

以下のコンポーネントで実際にhover効果を試すことができます:

CSSマスクのhover効果デモ

基本パターン(maskなし)

ホバーしてください 素晴らしい!

スライド効果(左→右でmask移動)

Learn More 詳細を見る →

対角線効果(対角線でmask移動)

Contact お問い合わせ

波紋効果(中心から外側へmask拡大)

Portfolio 作品集

複雑なマスク効果(ストライプ)

Advanced 上級者向け

CSSマスクの基本概念

maskプロパティとは

CSSのmaskプロパティは、要素の特定の部分を表示または非表示にするための機能です。マスクは以下の特徴を持ちます:

  • 透明度による制御: 黒い部分は表示、透明な部分は非表示
  • 複数レイヤー対応: 複数のマスクを重ね合わせて複雑な効果を作成
  • アニメーション対応: transitionと組み合わせてスムーズな動きを実現

mask-compositeプロパティ

mask-compositeは複数のマスクレイヤーの合成方法を制御します:

効果
addマスクを加算合成
subtractマスクを減算合成
excludeマスクを排他合成
intersectマスクを積算合成

実装パターン別解説

基本的なテキスト切り替え

最もシンプルな実装では、opacityとtransformを組み合わせます:

.hover-text-basic .default-text {
color: #333;
transition: opacity 0.3s ease;
}
.hover-text-basic .mask-text {
color: #fff;
background: #333;
opacity: 0;
transform: scale(0.8);
transition: all 0.3s ease;
}
.hover-text-basic:hover .mask-text {
opacity: 1;
transform: scale(1);
}

スライド効果による切り替え

マスクを使用した水平スライド効果の実装です。default-textmask-textで同じlinear-gradientマスクを共有し、mask-positionをずらして配置します。ホバー時に両方のマスクを同時に動かすことで、滑らかな入れ替えが実現されます。

/* スライド効果 - 共通マスク設定 */
.hover-text-slide .default-text,
.hover-text-slide .mask-text {
-webkit-mask: linear-gradient(90deg, black 50%, transparent 50%);
mask: linear-gradient(90deg, black 50%, transparent 50%);
-webkit-mask-size: 200% 100%;
mask-size: 200% 100%;
transition: -webkit-mask-position 0.6s ease, mask-position 0.6s ease;
}
/* 初期位置 */
.hover-text-slide .default-text {
-webkit-mask-position: 0% 0%;
mask-position: 0% 0%;
}
.hover-text-slide .mask-text {
-webkit-mask-position: 100% 0%;
mask-position: 100% 0%;
}
/* ホバー時の移動先 */
.hover-text-slide:hover .default-text {
-webkit-mask-position: -100% 0%;
mask-position: -100% 0%;
}
.hover-text-slide:hover .mask-text {
-webkit-mask-position: 0% 0%;
mask-position: 0% 0%;
}

💪 実装のポイント

default-textmask-textに同じマスクを適用し、mask-positionを逆方向に設定するのが重要です。ホバーでdefault-textが画面外に出ると同時に、mask-textが画面内に入ってくるように調整します。

対角線マスク効果

より動的な対角線での切り替え効果です。スライド効果と同様のロジックで、グラデーションの角度を135degに変更しています。

/* 対角線効果 - 共通マスク設定 */
.hover-text-diagonal .default-text,
.hover-text-diagonal .mask-text {
-webkit-mask: linear-gradient(135deg, black 50%, transparent 50%);
mask: linear-gradient(135deg, black 50%, transparent 50%);
-webkit-mask-size: 200% 200%;
mask-size: 200% 200%;
transition: -webkit-mask-position 0.7s ease, mask-position 0.7s ease;
}
/* 初期位置 */
.hover-text-diagonal .default-text {
-webkit-mask-position: 0% 0%;
mask-position: 0% 0%;
}
.hover-text-diagonal .mask-text {
-webkit-mask-position: 100% 100%;
mask-position: 100% 100%;
}
/* ホバー時の移動先 */
.hover-text-diagonal:hover .default-text {
-webkit-mask-position: -100% -100%;
mask-position: -100% -100%;
}
.hover-text-diagonal:hover .mask-text {
-webkit-mask-position: 0% 0%;
mask-position: 0% 0%;
}

波紋(Ripple)効果

radial-gradientを使い、中央から円形に広がるマスク効果を実装します。この例では、default-textmask-textで異なるマスクロジックを採用しています。default-textはマスクサイズを0%にして消し、mask-text200%に拡大して表示します。

/* default-text: ホバーでマスクサイズを0にする */
.hover-text-ripple .default-text {
-webkit-mask: radial-gradient(circle at center, black 50%, transparent 50%);
mask: radial-gradient(circle at center, black 50%, transparent 50%);
-webkit-mask-size: 200% 200%;
mask-size: 200% 200%;
transition: -webkit-mask-size 0.5s ease, mask-size 0.5s ease;
}
.hover-text-ripple:hover .default-text {
-webkit-mask-size: 0% 0%;
mask-size: 0% 0%;
}
/* mask-text: ホバーでマスクサイズを拡大する */
.hover-text-ripple .mask-text {
-webkit-mask: radial-gradient(circle at center, black 50%, transparent 50%);
mask: radial-gradient(circle at center, black 50%, transparent 50%);
-webkit-mask-size: 0% 0%;
mask-size: 0% 0%;
transition: -webkit-mask-size 0.5s ease, mask-size 0.5s ease;
}
.hover-text-ripple:hover .mask-text {
-webkit-mask-size: 200% 200%;
mask-size: 200% 200%;
}

高度な実装テクニック

複数レイヤーマスクの活用

より複雑な効果を実現するために、複数のマスクレイヤーを組み合わせることができます:

.advanced-mask {
mask:
linear-gradient(#000 0 0),
radial-gradient(circle at center, #000 0%, transparent 70%),
linear-gradient(45deg, #000 30%, transparent 70%);
mask-composite: exclude, add;
mask-size: 100% 100%, 150% 150%, 200% 200%;
mask-position: 0% 0%, 50% 50%, 0% 0%;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

パフォーマンス最適化

📢 パフォーマンス考慮事項

複雑なマスクアニメーションは計算コストが高いため、以下の点に注意してください:

  • will-change: maskプロパティでGPUアクセラレーションを有効化
  • 不要なアニメーション要素はprefers-reduced-motionで制御
  • 大量の要素に適用する場合は慎重にテスト
.optimized-mask {
will-change: mask;
transform: translateZ(0); /* GPUレイヤー作成を強制 */
}
@media (prefers-reduced-motion: reduce) {
.optimized-mask {
transition: none;
}
}

ブラウザ対応とフォールバック

サポート状況

現代のブラウザではmaskプロパティは広くサポートされていますが、古いブラウザ向けのフォールバックも考慮する必要があります。@supports not (mask: none)クエリを使い、マスク非対応ブラウザではopacityによるシンプルな切り替えを適用します。

/* フォールバック対応 */
@supports not (mask: none) and not (-webkit-mask: none) {
/* マスクが使えない場合はopacityで切り替え */
[class^="hover-text-"] .default-text {
opacity: 1;
transition: opacity 0.3s ease;
}
[class^="hover-text-"] .mask-text {
opacity: 0;
transition: opacity 0.3s ease;
}
[class^="hover-text-"]:hover .default-text {
opacity: 0;
}
[class^="hover-text-"]:hover .mask-text {
opacity: 1;
}
}

実用的な活用例

ナビゲーションメニュー

.nav-item {
mask: linear-gradient(90deg, black 0%, black 100%);
transition: mask-position 0.3s ease;
}
.nav-item:hover {
mask: linear-gradient(90deg, transparent 0%, black 100%);
}

CTA(Call To Action)ボタン

.cta-button {
mask: radial-gradient(circle at 0% 50%, black 0%, black 100%);
transition: mask 0.4s ease;
}
.cta-button:hover {
mask: radial-gradient(circle at 100% 50%, black 0%, black 100%);
}

まとめ

CSSマスクを活用したhover時のテキスト切り替えアニメーションは、ユーザーエクスペリエンスを大幅に向上させる効果的な手法です。本記事で紹介した実装パターンを組み合わせることで、以下のメリットを得ることができます:

  • 軽量な実装: JavaScriptを使わずにCSSのみで動的効果を実現
  • 柔軟なカスタマイズ: マスクの形状やアニメーション方向を自由に調整
  • パフォーマンス: GPUアクセラレーションを活用した滑らかなアニメーション

出典リスト

公式リソース(Official Resources)

参考サイト(Reference Sites)