CSSのバンドル

ここではレイアウトに共通のCSSを追加します。CSSはページやレイアウト、コンポーネントからimportできます。pluginSsg()が参照されたCSSを出力するため、CSS用のministaプラグインを追加する必要はありません。

Table of Contents

サイト共通のCSS

サイト全体に適用するCSSをsrc/layouts/globals.cssに置き、隣のレイアウトからimportします。レイアウトと共通CSSを同じディレクトリで管理できます。

src/layouts/index.tsx
import type { Metadata, LayoutProps } from "minista/types"
import Header from "../components/header"
import "./globals.css"

export const metadata: Metadata = { title: "My Site" }

export default function Layout({ title, children }: LayoutProps) {
  return (
    <html lang="ja">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width" />
        <title>{title}</title>
      </head>
      <body>
        <Header siteName="My Site" />
        <main className="site-main">{children}</main>
        <footer>My Site</footer>
      </body>
    </html>
  )
}
src/layouts/globals.css
:root {
  font-family: sans-serif;
  color: #222;
  background: #fff;
}

body {
  margin: 0;
}

.site-main {
  max-width: 72rem;
  margin-inline: auto;
  padding: 2rem 1rem;
}

通常のCSSのセレクターはグローバルに作用します。コンポーネント内からimportしても、自動的にそのコンポーネント専用になるわけではありません。

CSSが増えたら、同じディレクトリのstyle.cssなどへ分割してimportできます。配置場所やファイル名は自由に決められます。

構成と出力を確認する

プロジェクト構成
src/
├── layouts/
│   ├── globals.css
│   └── index.tsx
└── pages/
    ├── index.tsx
    └── about.md
ビルド結果の例
dist/
├── index.html
├── about.html
└── assets/
    └── bundle-[hash].css

ページやレイアウトがimportしたCSSは、既定ではbundleを基にしたCSSへまとめられます。出力名には設定に応じてハッシュが付き、生成HTMLにstylesheetの参照が追加されます。

この方法では、コンポーネントからimportしたCSSもグローバルな出力に含まれます。ページ固有の読み込みを明示したい場合は、CSS・JS・TSのエントリーを使います。

CSS Modulesによるクラス管理

クラス名の衝突を避けたい場合は、.module.cssを使います。

src/components/card.module.css
.card {
  padding: 1.5rem;
  border: 1px solid #ddd;
  border-radius: 0.5rem;
}
src/components/card.tsx
import type { ReactNode } from "react"
import styles from "./card.module.css"

type Props = { children: ReactNode }

export default function Card({ children }: Props) {
  return <article className={styles.card}>{children}</article>
}

ページからCardを使うと、CSSも読み込まれます。

src/pages/index.tsx
import Card from "../components/card"

export default function Page() {
  return (
    <>
      <h1>My Site</h1>
      <Card>制作スタジオのお知らせです。</Card>
    </>
  )
}

生成したクラス名はHTMLとCSSへ反映されます。CSS Modulesを使うだけでブラウザへReactの実行コードが追加されることはありません。

HTMLの構造としてstylesheetを指定することもできます。

import { Head } from "minista/head"

export default function Page() {
  return (
    <>
      <Head>
        <link rel="stylesheet" href="/src/layouts/globals.css" />
        <link rel="stylesheet" href="/css/legacy.css" />
      </Head>
      <h1>スタイルの例</h1>
    </>
  )
}

src/layouts/globals.cssはViteで処理され、ビルド後のURLに書き換わります。このようにlink要素で参照するCSSは、ビルドの入口となるCSSエントリーとして扱われます。詳しくはCSS・JS・TSのエントリーを参照してください。

public/css/legacy.cssはそのままコピーされます。importとlinkで同じCSSを二重に登録せず、用途に合わせて読み込み方を選びます。

Sassを使う

Sassを使う場合はプリプロセッサーを追加します。

npm install --save-dev sass-embedded

その後は.scssや.module.scssをCSSと同様にimportできます。

import "./globals.scss"

インラインスタイル

Reactのstyle属性も利用できます。

<p style={{ color: "tomato", marginBlock: "1rem" }}>お知らせ</p>

これは静的なstyle属性として出力されます。状態に応じてブラウザで値を変えたい場合は、通常のscriptやIslandを使います。

CSSの圧縮や出力先は設定リファレンスを参照してください。

次はCSS・JS・TSのエントリーで、HTMLから読み込むコードを指定します。