LoginSignup
2

【Next.js + Panda CSS】メニューバーで現在のページだけ色を変える

Posted at

Panda CSSはスタイルを動的に変更できない

先日リリースされたPanda CSS、Tailwind CSSの対抗馬として注目を集めています。

書き味はEmotionとほぼ変わりませんが、ゼロランタイムCSS in JSというジャンルに分類され、すべてのCSSをビルド時に生成することでランタイムCSS in JSが抱えていたパフォーマンスの問題を解決しています。

一方デメリットとしては、すべてのスタイルが静的解析によって生成されるため、Emotionでは当たり前のように出来ていたJavaScriptを使った動的な変更ができないことが挙げられると思います。

本記事では、そんなPanda CSSでURLのパス(location)に応じてメニューバー中の現在のページの部分だけスタイルを変える一例を紹介します。

aria-current とは

aria-currentは現在のページを表す属性で、主にスクリーンリーダーに該当の要素の意味を補強するために、アクセシビリティの観点から記述が推奨されている属性です。いくつかの値を取りますが、aria-current="page"とすることで、現在のページを表すことができます。

CSSでaria-current="page"が設定された要素を選択するには、[aria-current="page"]というセレクタを利用しますが、Panda CSSでは_currentPageというConditional Styleが用意されています。

実装

以下はNext.js v13のApp routerを利用した場合の実装方法です。usePathnameの部分を変えればReactやNext.js Pages routerでも同様に実装できると思います。

スタイルを適用したメニューバー

components/Menu.tsx
"use client";

import Link from "next/link";
import { usePathname } from "next/navigation";

import { css } from "@panda/css";

export default function Menus() {
  const pathname = usePathname();

  const links = [
    { href: "/", label: "ホーム" },
    {href: "events", label: "滞在状況"},
    { href: "/history", label: "履歴" },
    { href: "/settings", label: "設定" },
  ];

  return (
    <>
      {links.map(({ href, label }) => (
        <Link
          aria-current={pathname === href ? "page" : undefined}
          className={css({
            color: "inherit",
            textDecoration: "none",
            px: 4,
            py: 2,
            borderRadius: 8,
            transition: "all 0.2s",
            _hover: {
              bgColor: "gray.200",
              _osDark: {
                bgColor: "gray.600",
              },
            },
            _currentPage: {
              color: "green.500",
            },
          })}
          href={href}
          key={href}
        >
          {label}
        </Link>
      ))}
    </>
  );
}

おわり

Emotionを使っていると何かとJS側でスタイルの条件分岐をしてしまいがちですが、パフォーマンス的にはあまりよろしくないので、このようにできるだけCSS側で処理させてあげるようにすると良さそうです。

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
What you can do with signing up
2