2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Last updated at Posted at 2023-08-14

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

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

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

一方デメリットとしては、すべてのスタイルが静的解析によって生成されるため、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 Menu() {
  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側で処理させてあげるようにすると良さそうです。

2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?