⛑️

自動補完も完備👀!Custom Utilitiy Classで送る幸せなTailwind CSSライフ

2024/06/30に公開

結論

設定方法

  • customUtilities.ts(名前は何でも良い)を作成する。
    • 中身を参考にしていただきながらcssをCamelCaseで設定(TSなので)
  • tailwind.config.tsでimportしpluginsの配列に渡す。

利点

  • VScode内で拡張機能であるTailwind CSS IntelliSenseでの補完で参照可能
  • hover時に当たっているプロパティの参照も可能
  • Tailwindで導入されてないプロパティも使える(CSSなので)
customUtilities.ts
import { Properties } from 'csstype'; //CamelCaseの補完が出る用
import { PluginAPI, CSSRuleObject } from 'tailwindcss/types/config';

type CSSRulesType = CSSRuleObject & Properties;

export const customUtilities = (plugin: PluginAPI) => {
  const { addUtilities, theme } = plugin;

// 以下の様な形でthemeでwrapした上で設定した内容を参照するという様に少し工夫が必要になります。

  const accentColor = theme('colors.accent.DEFAULT') as string | undefined;
  const fontFamilyPrimary = theme('fontFamily.primary');

// 型指定に対応する為の処理
  const fontFamilyPrimaryString = Array.isArray(fontFamilyPrimary)
    ? fontFamilyPrimary.join(', ')
    : typeof fontFamilyPrimary === 'string'
    ? fontFamilyPrimary
    : 'sans-serif';

  const utilities: { [key: string]: CSSRulesType } = {
    '.primary-btn': {
      backgroundColor: accentColor || '#f19687',
      minWidth: '178px',
      borderTopLeftRadius: '30px',
      borderBottomLeftRadius: '30px',
      borderTopRightRadius: '4px',
      borderBottomRightRadius: '24px',
      fontFamily: fontFamilyPrimaryString,
      textTransform: 'uppercase',
      letterSpacing: '1px',
      height: '58px',
      paddingLeft: '2rem',
      paddingRight: '1.5rem',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      color: '#fff',
    },
  };
  addUtilities(utilities);
};

tailwind.config.ts
import { customUtilities } from './lib/customUtilities';

const config = {
~~
  fontFamily: {
    primary: 'var(--font-marcellus)',
    secondary: 'var(--font-montserrat)',
    sans: ['var(--font-noto-sans-jp)'],
  },
  extend: {
    colors: {
      primary: {
        DEFAULT: '#473936',
      },
    },
  },
  plugins: [customUtilities],
}
sample.tsx
const Sample = () => {
  return (
    <div>
      <button className="primary-btn">Button</button>
    </div>
  );
};
eslintrc.json
"tailwindcss/no-custom-classname": [
  2,// 1はwarningで2がerrorです。好みで設定を
  {
    "allowedCustomClasses": ["primary-btn"] //追加した分のcustom classを配列に追加
  }
],

を足して置く

※これによりcustom classとして存在しない
誤ったclassを記述した場合はエラーになります。入れておくのがおすすめです。

自動補完

マウスhoverでプロパティの設定内容を確認可能

class名に誤りがある場合、errorになる

Tailwindには存在しないCSSプロパティに準拠できる
※この場合はanimation-timeline

はじめに

Tailwind CSSについては、これまでは様々な有識者の方々の比較検討記事での意見やclass名が連続で並ぶ為、見た目的にも美しくないなぁと苦手意識を持っていたので避けていましたが、プロダクトで実際に採用するかどうかの比較の為にもTailiwind CSSに入門し、大体1ヶ月ぐらい経ち「割と良いな」という感情を今は持っています。

まだまだ、完全に理解した状態であり、チョットデキルとは言い難いものの少し慣れてきたので扱えるようにはなってきました。
※エンジニアの皆様はご存知かと思いますが意味は逆です

とはいえ独自にclassを作りたい問題

component側にユーティリティclassを並べ、その粒度を絞っていけば最小単位のみのレイアウトだけになるように作れますし、それを使うレイアウト側のユーティリティクラスのだけに注力するようにすれば1つcomponentやページにものすごいclassが並んでしまい「これは、なんのことやら...oh」という事態はcomponentの設計戦略次第では避けることはできると思います。

とはいえ独自のclassを作り、それを当てるだけでスタイリングが担保される
場面も開発を進めていくとあると思うので、やっぱり少しぐらいは独自のclassを作りたいという問題になるかなと感じております。

@applyを使うか??

@applyは以下の例の様にclassを作成し、そのclassを要素に当てるTailwindの機能です。

@applyの参考
.btn {
  @apply bg-accent min-w-[178px] rounded-tl-[30px] rounded-bl-[30px] rounded-tr-[4px] rounded-br-[24px] font-primary uppercase tracking-[1px] h-[58px] pl-8 pr-6 flex items-center justify-center text-white;
}

<button className="btn" />

便利な機能ではありますが個人的には以下の理由からあまり使うべきではないという判断です

@applyを使いたくない理由

その1

@apply機能を使い一つのクラスにまとめるということで便利ではありますが
設定できるのはそもそもTailwindに設定されているユーティリティclassだけであり、まだTaliwindが対応していないCSSプロパティ(e.g.animation-timeline)は設定できないようです。

その2

VScodeでの補完が効かない。(個人的にはこれが大きいです)
いちいち、@applyで宣言されているclassが書いてあるファイルにどういうプロパティが当たっているのか見に行くのも面倒だし、class名からだけではプロパティや形・色まで想定し辛いことなどあるので

その3

作者が辞めようって言ってる(じゃあ、辞めよう😟)

作者の Adam 氏は @apply を使うことは辞めるように強く提言している。
ドキュメントにもまた、「見た目を整理するためだけに使わないように」という章があったりする。

詳しくは以下ににまとめてくださっています。(学び)
https://www.ushironoko.me/posts/tailwind-apply-dame

まとめ

custom classを設定することで開発が楽になり(補完効くプロパティの内容わかる)ますが、Tailwindの設計思想では個別のclassをたくさん作ることが意図では無いはずなので、どうしても使いたいときに作るclassとしての役割程度で基本的にはcomponent側の粒度設計を上手くやった方が良さそうなのかなとは思います。

そもそもclassをたくさん作って書く必要があるなら他のスタイリング法の方が利点も大きい筈かなとも思います。

引用

https://note.com/teched/n/n555f4f5f9344

https://www.ushironoko.me/posts/tailwind-apply-dame

引用させていただきました。ありがとうございました🙇

余談

この記事を書こうと思った経緯と失敗

経緯🔥

https://www.lundevweb.com/2024/06/create-scroll-animation-using-css-only.html

を見てすげぇっと思い、あれ?でもanimationTimelineってTailwindじゃ使えないなってなったのがはじまりです(同じようなことを実現させるにはframer-motion使うとかいっぱい別の方法ありますが)

YoutubeでCSSテクニックを公開されていますが強強マン過ぎて勉強になる(凄すぎてならないことも多々あるw)のでおすすめです!!

https://www.youtube.com/channel/UCpWAHyvsw6-Hd3FMcKIHGCA

失敗😷

この記事を書いてる途中で全く別の問題でTailwind CSS IntelliSenseの補完が完全に死んだり(ほんとに何もでなくなった)eslintが動かなくなって画像のキャプチャー撮るためにVSCode初期化したり、cache消したりと...
記事を書くよりも時間がかかったのでかなり疲れました💭

Discussion