📛

CSS Modules の命名に迷ったら

2022/10/04に公開

先日、こちらの記事「Tailwind 考」を発端に、Tailwind CSS を愛用されている方達の間では「命名を考えなくてもよい」という点を、高く評価されているように感じました。実際、stylede-components はコンポーネント毎に命名するのが一般的ですし、CSS Modules も書き方によっては、セレクター名称をたくさん考えなければいけません。

職場で働く同僚の間でも、要素に直接スタイルをあてない書き方だと「命名規則で迷いそう、ガイドラインが必要そう」という声を聞きます。普段 CSS Modules を利用している筆者ですが、コーディング時命名に迷うことはかなり稀です。「迷わないために何を基準にすべきか?」について、わたしが普段ヒントにしている点を紹介します。

UI コンポーネントを細分化する

まずはじめに検討するのは、UI コンポーネントの細分化です。UI コンポーネントは責務・可読性にもとづき細分化をすることもありますが、何より再レンダリングの最適化を図るならば、自然と細分化されるはずです。

冒頭の記事でも述べられていますが、そもそも UI コンポーネントが細分化されているので、この時点で考えなければいけない名称はわずかです。一つの UI コンポーネントに必要になるセレクター名称はせいぜい片手で数えられる程度で、両手で数えるぐらいの量になってきた時はコンポーネントの粒度を見直します。これが大抵、よいリファクタに繋がったりします。

暗黙のロールを className にする

では、片手で数えるだけの命名をどこから捻出するのでしょうか?例えば以下の UI コンポーネントにを例に考えてみましょう。

const PostList = ({ title, items }: { title: string; items: Item[] }) => {
  return (
    <section className={styles.module}>
      <h2 className={styles.heading}>{title}</h2>
      <ul className={styles.list}>
        {items.map((item) => (
          <li key={item.id} className={styles.listitem} {...item} />
        ))}
      </ul>
    </section>
  );
};

ここには 4 つの className が存在します。styles.moduleは、コンポーネントのルートノードとして、個人的なお決まりとしてよく使う名称です。ここは少し悩みどころなので、チームでガイドラインを決めると良いかもしれません。

.heading / .list / .listitemですが、これの出どころは 「暗黙のロール」 です。アクセシビリティツリーを見ながらコーディングする機会が増えてきているので、割とこれを拝借するだけで十分なことが多いです。アクセシビリティツリーの見方はこちらの記事で紹介しています。

型定義をそのまま使う

React プロジェクトでは、TypeScript を使う機会が多いと思います。そのため、型定義を参照して、そのまま className にしてしまうことが多いです。先ほどと同じコンポーネントで表現するならば、以下の様になるでしょう。

const PostList = ({ title, items }: { title: string; items: Item[] }) => {
  return (
    <section className={styles.module}>
      <h2 className={styles.title}>{title}</h2>
      <ul className={styles.items}>
        {items.map((item) => (
          <li key={item.id} className={styles.item} {...item} />
        ))}
      </ul>
    </section>
  );
};

まとめ

  • UI コンポーネントを細分化する
  • 暗黙のロールを className にする
  • 型定義をそのまま使う

この順番に普段命名しているので、いずれにも該当しないケースがほとんどありません。装飾のためだけの要素(命名になやむ要素)は、かなり少ないのではないでしょうか。

Discussion