Tailwindcssでshimmer button(シマーボタン)の作成方法

## はじめに
皆さんこんにちは、[株式会社KANGEN Holdings][link-1]に所属するフルスタックエンジニアのA.K.です。

2023年頃から、ボーダーに沿って光がきらりと回転するボタンのUIを採用するサイトが増えていることに気づきました。特にLanding pageでその割合が高いようです。このようなボタンは英語で「shimmer button」と呼ばれます（以降も「shimmer button」と呼ばせていただきます）。

今回は、Tailwind CSSを使用してshimmer buttonを作る方法について紹介させていただきます。

## 1.shimmer buttonの特徴
https://www.raycast.com/
![スクリーンショット 2025-01-14 14.55.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3952033/1617cecb-4249-7250-5165-6277e9760190.png)

https://bewater.xyz/
![スクリーンショット 2025-01-14 14.54.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3952033/93029133-6540-3825-4690-3f368c5c0645.png)

上記は例で視覚的な魅力を感じていますか？

**特徴**
- ボタンの境界線や背景を輝く光が動きながら、キラキラとしたエフェクトを与えることで、視覚的にインパクトを与えます
- このエフェクトは、ユーザーの注意を引きやすく、特に重要なアクションボタンに適しています
- ユーザーエクスペリエンスを向上させるため、Shimmerエフェクトは過度にならず、洗練された印象を与えるよう設計されています

**使用ケース**
このパターンのボタンデザインは、モダンで未来的な見た目を持ち、ハイテク製品や先進的なサービスを提供するウェブサイトでよく使用されます。

## 2.技術スタック
本文では、React (Vite) + Tailwind CSSを使用しています。

[Tailwind CSS公式サイト][link-2]を参考にすると、フレームワークを使用するかしないかは自由です。

## 3.CSS関数 conic-gradient() で円錐状のグラデーションを描画
ここでは、JavaScriptを使わずに光の回転を実現するために、CSSの関数 conic-gradient() を使用します。

まず、conic-gradient() を使用してどのような表示ができるのか、以下のコードを使って確認してみます。
```
//index.cssファイル
@tailwind base;
@tailwind components;
@tailwind utilities;

body {
  background: theme('colors.slate.950');
  color: theme('colors.slate.50');
}

main {
  background: conic-gradient(white, black, white);
  width: 100vw;
  height: 100vh;
}

//App.tsxファイル
import './App.css';

function App() {
  return (
    <main>
    </main>
  )
}

export default App;
```
結果はこんな感じです。まだピンとこないかもしれないですが、次にボタンを作っていきます。

![スクリーンショット 2025-01-14 16.46.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3952033/264a28ea-e7c8-8d5e-dc32-1a008ab780c3.png)

## 4.ボタンUIの作成と conic-gradient 効果の追加
Tailwind CSSを使用して、conic-gradient をボタンの背景として追加してみます。

```App.tsx
import './App.css';

function App() {

  return (
    <main className="min-h-screen flex justify-center items-center w-full">
      <button
        type="button"
        className="px-24 py-8 text-3xl font-bold bg-[conic-gradient(from_0deg,theme(colors.slate.950)_0%,theme(colors.slate.500)_10%,theme(colors.slate.950)_20%)]"
        aria-label="shimmer"
      >
        SHIMMER
      </button>
    </main>
  )
}

export default App;
```
このグラデーションの光を動的に回転させると、どのようなイメージになるか見てみましょう。

![スクリーンショット 2025-01-14 16.29.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3952033/4c42049c-efdc-66bc-c731-34606209c6c3.png)

## 5.CSSカスタムプロパティとアニメーションの設定
再利用性と保守性を向上させるため、カスタムプロパティを積極的に活用します。--shimmer-angle は、光の角度を制御するためのカスタムプロパティで、keyframes で0度から360度まで回転するアニメーションを追加します。


```index.css
@property --shimmer-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

@keyframes shimmer {
  0% {
    --shimmer-angle: 0deg;
  }

  100% {
    --shimmer-angle: 360deg;
  }
}
```
```App.tsx
import './App.css';

function App() {

  return (
    <main className="min-h-screen flex justify-center items-center w-full">
      <button
        type="button"
        className="px-24 py-8 text-3xl font-bold
          bg-[conic-gradient(from_var(--shimmer-angle),theme(colors.slate.950)_0%,theme(colors.slate.500)_10%,theme(colors.slate.950)_20%)]
        animate-[shimmer_2.5s_linear_infinite]"
        aria-label="shimmer"
      >
        SHIMMER
      </button>
    </main>
  )
}

export default App;
```
このように光が回転するアニメーションを追加されました。

![画面収録-2025-01-14-17.24.37.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3952033/6a2e0ed7-fd19-d841-2363-4f9cd0cb4cb3.gif)

## 6.Tailwind CSSでの最終仕上げ
最後に、ボタンの見た目をさらに改善していきます。
```App.tsx
import './App.css';

function App() {

  return (
    <main className="min-h-screen flex justify-center items-center w-full">
      <button
        type="button"
        className="relative px-24 py-8 text-3xl font-bold
          bg-[conic-gradient(from_var(--shimmer-angle),theme(colors.slate.950)_0%,theme(colors.slate.500)_10%,theme(colors.slate.950)_20%)] animate-[shimmer_2.5s_linear_infinite] rounded-[24px]
          after:flex after:absolute after:bg-slate-950 after:inset-[2px] after:rounded-[22px] after:content-[attr(aria-label)]
          after:items-center after:justify-center"
        aria-label="shimmer"
      >
        SHIMMER
      </button>
    </main>
  )
}

export default App;

```
最終的な完成品はこちらです。

![画面収録-2025-01-15-11.15.01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3952033/46ba9db9-fb8c-b1c6-2855-9b18c12b3c1a.gif)

## 7.今回の記事のため用意したソースコード
https://github.com/ppppppsmash/shimmer-button

今回のShimmer Buttonの作成を通して、CSSだけで動的なアニメーションを実現できるモダンな技術について学ぶことができました。conic-gradient() やカスタムプロパティの活用によって、視覚的に印象的なUIを簡単に作成できることが分かりました。

特に、JavaScriptを使わずに純粋なCSSでアニメーションをコントロールすることで、パフォーマンスの向上や保守性の向上が期待できます。Tailwind CSSと組み合わせることで、効率的にスタイルを適用し、素早くデザインを変更できる柔軟性も感じました。

これからも、こうしたモダンなCSS技術を活用して、より魅力的でインタラクティブなUIを作成していきたいと思います。皆さんもぜひ試してみて、CSSの可能性を広げてみてください。



[link-1]: https://kangen-holdings.co.jp/
[link-2]: https://tailwindcss.com/docs/installation/framework-guides