この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:4
ページ更新者:guest
更新日時:2026-06-11 07:10:02

タイトル: CSSの組み込み方法
SEOタイトル: HTML に CSS を組み込む 4 つの方法(External / Internal / Inline / @import)

この記事の要点
  • 4 つの組み込み方法: External (<link>) / Internal (<style>) / Inline (style) / @import
  • 推奨は External (<link rel="stylesheet" href="style.css">) — キャッシュ、保守性、性能すべて最良
  • @import は遅い(ブロッキング読込)→ ビルドツール側で結合して <link> 1 本にする
  • Inline style は動的指定が必須の場面のみ。CSP / 保守性で減点
  • 現代の運用: CSS Modules / Sass / PostCSS でビルド → 1 本の min.css に。Critical CSS を inline で先頭に

4 つの基本的な組み込み方法

方法記法用途推奨度
External<link rel="stylesheet">全ページ共通の CSS★★★ 推奨
Internal<style>...</style>そのページ専用 / Critical CSS★★ 限定
Inlinestyle="..."動的値・メール HTML★ 例外時のみ
@importCSS 内で別 CSS を読む古い CMS / 一部用途非推奨

1. External (外部 CSS) — 最推奨

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>サイト</title>

  <!-- 通常の組み込み -->
  <link rel="stylesheet" href="/css/main.css">

  <!-- 複数読み込み (順序で上書き) -->
  <link rel="stylesheet" href="/css/base.css">
  <link rel="stylesheet" href="/css/components.css">

  <!-- メディアクエリで分岐 -->
  <link rel="stylesheet" href="/css/print.css" media="print">

  <!-- 遅延読込(非同期) -->
  <link rel="preload" href="/css/heavy.css" as="style"
        onload="this.onload=null;this.rel='stylesheet'">

  <!-- CDN -->
  <link rel="stylesheet" href="https://cdn.example.com/lib.css"
        crossorigin="anonymous"
        integrity="sha384-...">
</head>
<body>...</body>
</html>

External のメリット:

  • ブラウザキャッシュが効く(複数ページで同じ CSS を再 DL しない)
  • HTML と CSS の分離で保守性 ★
  • HTTP/2 / HTTP/3 では複数ファイル同時 DL がほぼコスト無し
  • min化 / hash付与(main.abc123.css)で長期キャッシュ可能

2. Internal (style タグ)

<!DOCTYPE html>
<html>
<head>
  <style>
    body { font-family: sans-serif; }
    .alert { background: #fee; border: 1px solid #c00; }

    @media (max-width: 768px) {
      body { font-size: 14px; }
    }
  </style>
</head>
<body>
  <div class="alert">注意</div>
</body>
</html>

Internal の使いどころ:

  • そのページにしか使わない CSS(メール購読確認ページ等)
  • Critical CSS(ファーストビューに必要な最小 CSS)を inline → レンダリング高速化
  • 1 ページ完結の LP(ランディングページ)
  • キャッシュは効かない(HTML 毎回再 DL)

3. Inline (style 属性)

<!-- 各要素に直接 -->
<div style="color: red; font-weight: bold;">エラー</div>

<!-- 動的値(JS 生成、テンプレート変数) -->
<div style="background: {{ user.theme_color }}">
  {{ user.name }}
</div>

<!-- HTMLメール(CSS 外部読込が効かないクライアント対策) -->
<table style="width:100%;border-collapse:collapse">
  <tr><td style="padding:10px;background:#f5f5f5">本文</td></tr>
</table>

Inline の問題点:

  • 詳細度が高すぎる: !important 以外で上書き不可能
  • キャッシュ不可
  • CSP(Content Security Policy)と相性悪い: style-src 'unsafe-inline' が必要
  • 保守性最悪: グローバル変更ができない

例外的に使ってよいケース:

  • HTML メール(受信側 CSS 解釈の制限)
  • JS で実行時に算出した値(座標、サイズ)
  • テスト用の 1 回限り検証

4. @import

/* main.css */
@import url("base.css");
@import url("components.css");

/* メディア条件付き */
@import url("print.css") print;

/* CSS の最先頭でなければ無効 */
body { background: white; }
@import url("late.css");   /* これは無効 */

@import の弱点: パーサが @import を読んでから次の CSS を取りに行くブロッキング読込になり、レンダリングが遅れます。今は使わないのが正解。代わりに Sass/PostCSS の @import@use でビルド時に結合してください。

5. CSS-in-JS

// styled-components (React)
import styled from 'styled-components';

const Button = styled.button`
  background: #4caf50;
  color: white;
  padding: 0.5em 1em;

  &:hover {
    background: #45a049;
  }
`;

// Emotion
import { css } from '@emotion/react';
const style = css`color: red;`;
<div css={style}>...</div>

React / Vue で使われる。SSR 時にスタイルを <style> として出力する形式が主流。

6. CSS Modules

/* Button.module.css */
.primary {
  background: #4caf50;
  color: white;
}
.large {
  padding: 1em 2em;
}
// Button.jsx
import styles from './Button.module.css';

export default function Button({ children }) {
  return (
    <button className={`${styles.primary} ${styles.large}`}>
      {children}
    </button>
  );
}

// クラス名は build 時に Button_primary__a3f9 のようにユニーク化される
// → クラス名衝突が起きない

7. ビルドツール: Sass / PostCSS

// app.scss
@use "base";
@use "components/button";
@use "components/card";

$primary: #4caf50;

.btn {
  background: $primary;

  &--large { padding: 1em 2em; }   /* BEM 記法 */
  &:hover  { background: darken($primary, 10%); }
}

// → ビルドで 1 本の app.css に結合 → <link> 1 行で読込

Critical CSS(パフォーマンス最強)

ファーストビューに必要な CSS をHTML head 内に inlineし、残りは非同期読込:

<head>
  <!-- 最小 critical CSS を head に inline (約 14KB 以内) -->
  <style>
    body { font-family: sans-serif; margin: 0; }
    .hero { background: #1a73e8; color: white; padding: 4em 2em; }
    /* ... ファーストビューだけ ... */
  </style>

  <!-- 残りは非同期 (FOUC 防止に preload + onload) -->
  <link rel="preload" href="/css/main.css" as="style"
        onload="this.onload=null;this.rel='stylesheet'">
  <noscript><link rel="stylesheet" href="/css/main.css"></noscript>
</head>

これで First Contentful Paint (FCP) が劇的に改善します。

HTTP/2 Push(過去の手法)

サーバから CSS を先回り送信する手法ですが、HTTP/2 Push は Chrome で廃止(2022 年)。代わりに <link rel="preload"> + 103 Early Hints が使われます:

HTTP/2 103 Early Hints
Link: </css/main.css>; rel=preload; as=style

HTTP/2 200 OK
Content-Type: text/html
...

性能と保守性の比較

方式初回描画キャッシュ保守性備考
External (link)★★★★★★標準
External + preload★★★★★★★★HTTP 階層下げで最強
Internal (style)★★×1 ページ限定 / Critical
Inline (属性)××動的のみ
@import×(遅延)非推奨

現代の推奨構成

  1. ソース: Sass / PostCSS / Tailwind 等で書く
  2. ビルド: Vite / Webpack で 1 本の app.[hash].css
  3. 配信: CDN で長期キャッシュ(hash 付きなので安全)
  4. 読込: <link rel="stylesheet"> + Critical CSS を inline
  5. CSP: style-src 'self' で inline を禁止(Critical 部分は nonce で許可)

FAQ

Q: link と style、どちらを使うべき?
A: 基本は <link> (External)。キャッシュが効くため。<style> は Critical CSS や 1 ページ完結 LP のみ。

Q: @import はなぜダメ?
A: 読込がシリアル化されレンダリングをブロックします。Sass / PostCSS の @import はビルド時に解決されるので OK ですが、ブラウザに到達する CSS で @import を残すのは禁物。

Q: Inline style は完全に禁止すべき?
A: いいえ。動的計算した位置・サイズ、HTML メール、JS 制御の表示状態などは Inline が正解の場合もあります。保守性が下がることを理解した上で例外的に。