🌪️

実務を意識したTailwind CSSの基本的な使い方

2023/12/27に公開

はじめに

株式会社 var でインターンをしているユウマです。実務に入る前の研修で、現役フロントエンドエンジニアにコードレビューを受け、基本的な Tailwind の使い方を教わりました。研修中に得た知識を共有することで、同じく学習途中の方々に役立つきっかけになればと思います。

この記事の対象者

  • Tailwind に興味を持ち、基本的な書き方を学びたい方
  • ハッカソンなどのチーム開発で Tailwind を効果的に使用したい方
  • なんとなくで Tailwind を使っている方(研修開始前の自分)

この記事のゴール

  • Tailwind の基本設定とカスタマイズ方法を理解する
  • 効率的なクラス名の管理方法を理解する
  • Tailwind を使用した実践的なスタイリングの仕方を理解する

前提

tailwind.config.js で Tailwind をカスタマイズする

tailwind.config.jsではプロジェクト固有のスタイリング設定ができます。この設定ファイルでは、カラーやフォントサイズなどの基本的なデザイン要素を事前に定義できます。開発者はこれらの設定を活用することで、一貫性のあるデザインを簡単に実装し、後からの変更や拡張にも柔軟に対応できます。

実務では、デザイナーが Figma などのツールを使用して色やフォントを指定することが一般的です。そのため、tailwind.config.jsを使い、デザインの指示に沿ったスタイルを効率的に適用しましょう。

以下は、tailwind.config.jsでの基本的なカラー、フォントファミリー、フォントサイズの設定例です。

// tailwind.config.js
import type { Config } from "tailwindcss";
import defaultTheme from "tailwindcss/defaultTheme";

const config: Config = {
  content: ["./src/**/*.{js,ts,jsx,tsx,mdx}"],
  theme: {
    // カラー設定
    colors: {
      // 基本色
      blue: "#1fb6ff",
      purple: "#7e5bef",
      pink: "#ff49db",
      orange: "#ff7849",
      green: "#13ce66",
      yellow: "#ffc82c",
      black: "#000000",
      // グレースケールの詳細設定
      gray: {
        900: "#333333",
        800: "#666666",
        700: "#999999",
        600: "#CCCCCC",
        100: "#EEEEEE",
      },
      white: "#FFFFFF",
    },
    // フォントファミリー設定
    fontFamily: {
      sans: ["Graphik", "sans-serif"],
      serif: ["Merriweather", "serif"],
    },
    // フォントサイズ設定
    fontSize: {
      xs: ["0.75rem", { lineHeight: "1rem", letterSpacing: "0.03em" }],
      sm: ["0.875rem", { lineHeight: "1.25rem", letterSpacing: "0.03em" }],
      base: ["1rem", { lineHeight: "1.5rem", letterSpacing: "0.03em" }],
      lg: ["1.125rem", { lineHeight: "1.75rem", letterSpacing: "0.03em" }],
      xl: ["1.25rem", { lineHeight: "1.75rem", letterSpacing: "0.03em" }],
      "2xl": ["1.5rem", { lineHeight: "2rem", letterSpacing: "0.03em" }],
      "3xl": ["1.875rem", { lineHeight: "2.25rem", letterSpacing: "0.03em" }],
      "4xl": ["2.25rem", { lineHeight: "2.5rem", letterSpacing: "0.03em" }],
      "5xl": ["3rem", { lineHeight: "1", letterSpacing: "0.03em" }],
    },
  },
  plugins: [],
};

この設定を使って、以下のようにクラスを適用することができます。

// コンポーネントの使用例
<div className="bg-blue font-sans text-lg">サンプルテキスト</div>

このようにtailwind.config.jsを活用することで、デザインの一貫性を保ちつつ、開発の効率を高めることができます。

Tailwind の公式ドキュメントを参考に、フォントやカラーの設定を実装することをお勧めします。

※これを設定するとデフォルトの Tailwind のカラーパレットが使用できなくなります。bg-blue-500など。

globals.css でページ共通の CSS を定義する

Tailwind とは関係ないですが、globals.cssプロジェクト全体で共通して使用する基本スタイルを設定することができます。Tailwind の@layerディレクティブを使用すると、これらのスタイルを Tailwind のbaseレイヤーに組み込むことができます。これにより、Tailwind のデフォルトのベーススタイルにカスタムスタイルを上書きまたは追加することが可能になります。

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  body {
    font-size: theme(fontSize.base);
    font-weight: theme(fontWeight.medium);
    font-family: theme(fontFamily.sans);
    color: theme(colors.gray.100);
    background-color: theme(colors.black);
  }
}

上記のコードでは theme 関数を使い、tailwind.config.js のテーマ設定を参照しています。

CSS と@layer の使い方はこちらを参照してください。

効率的なクラス名の管理にcn()関数を活用する

ここでは、clsxtailwind-mergeを組み合わせたカスタムヘルパー関数cn()の導入とその利点について解説します。このcn()関数は、src/libs/utils.tsに定義され、プロジェクト全体で利用可能です。

npm install tailwind-merge clsx
import clsx, { ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

この関数は、複数のクラス名を簡単に結合し、Tailwind CSS のユーティリティクラスの競合を効率的に解決します。では、cn()を使う場合と使わない場合の違いを見てみましょう。

cn()関数を使わない場合

// Button.tsx
const Button = ({ size, children }) => {
  let sizeClass = "";
  if (size === "sm") {
    sizeClass = "text-sm px-3 py-1";
  } else if (size === "md") {
    sizeClass = "text-base px-4 py-2";
  } else if (size === "lg") {
    sizeClass = "text-lg px-5 py-3";
  }

  return <button className={`border rounded ${sizeClass}`}>{children}</button>;
};

このコードでは、sizeプロップに基づいて手動でsizeClassを設定しています。これは直感的ですが、サイズオプションが増えるとコードが長く複雑になります。

cn()関数を使う場合

// Button.tsx
import { cn } from 'src/libs/utils';

const Button = ({ size, children }) => {
  return (
    <button
      className={cn(
        'border rounded',
        {
          size === 'sm' && 'text-sm px-3 py-1',
          size === 'md' && 'text-base px-4 py-2',
          size === 'lg' &&'text-lg px-5 py-3',
        }
      )}
    >
      {children}
    </button>
  );
};

cn()関数を使用すると、クラス名の結合が非常に簡潔になります。第 1 引数に共通の CSS を記述し、第 2 引数にはオブジェクト形式で条件付きのクラス名を指定し、cn()関数が適切なクラスを選択して結合します。これにより、コードの可読性が向上し、拡張性も高くなります。

おすすめの拡張機能やツール

参考

https://tailwindcss.com/docs/configuration
https://youtu.be/cZc4Jn5nK3k?si=EvvfOIZgY8fCh7BY
https://ui.shadcn.com/docs/installation/manual#add-a-cn-helper
https://www.youtube.com/watch?v=re2JFITR7TI

最後に

弊社では、インフラ学習サイト Envader(エンベーダー)と IT スクール(RareTECH)を運営しています。また、企業研修やシステム開発なども行っていますので興味がある方は HP よりご連絡下さい。

https://envader.plus
https://raretech.site
https://var.co.jp

また、弊社では一緒に働く仲間を募集しています。

  • フロントエンドエンジニア
  • Bubble エンジニア
  • IT スクール RareTECH のメンター
  • ウェブマーケター

など様々なポジションで採用活動を強化しております。興味のある方は以下 Wantedly よりご連絡下さい。

https://www.wantedly.com/companies/var/projects

GitHubで編集を提案

Discussion