postcss の使い方

Tool for transforming styles with JS plugins

v8.5.8207.3M/週MITスタイリング
AI生成コンテンツ

この記事はAIによって生成されました。内容の正確性は保証されません。最新の情報は公式ドキュメントをご確認ください。

PostCSS の使い方完全ガイド — JSプラグインでCSSを自在に変換するツール

一言でいうと

PostCSS は、JavaScript プラグインを通じて CSS を解析・変換するためのツールです。CSS をAST(抽象構文木)にパースし、プラグインが自由に操作できる基盤を提供することで、Autoprefixer によるベンダープレフィックス付与、Stylelint によるリント、将来の CSS 構文のトランスパイルなど、多彩な CSS 処理を実現します。

どんな時に使う?

  1. ベンダープレフィックスの自動付与 — Autoprefixer プラグインと組み合わせて、display: flex などに必要なプレフィックスを自動で追加したい場合
  2. CSS のリント・品質チェック — Stylelint と連携して、コーディング規約の遵守やバグの検出を行いたい場合
  3. 次世代 CSS 構文のトランスパイルpostcss-preset-env を使い、ネスティングやカスタムメディアクエリなど、まだブラウザサポートが不十分な CSS 機能を現在のブラウザで動くコードに変換したい場合
  4. CSS Modules やスコープ付き CSS の実現postcss-modules などを使い、クラス名の衝突を防ぐ仕組みを導入したい場合
  5. 独自の CSS 変換処理の構築 — 自作プラグインを書いて、プロジェクト固有の CSS 変換ロジックを実装したい場合

インストール

# npm
npm install postcss

# yarn
yarn add postcss

# pnpm
pnpm add postcss

多くの場合、PostCSS 単体ではなくプラグインと一緒にインストールします。

# よくある組み合わせ例
npm install postcss autoprefixer postcss-preset-env

CLI で使いたい場合は postcss-cli も追加します。

npm install postcss postcss-cli

基本的な使い方

PostCSS の最も基本的な使い方は、CSS 文字列を読み込み → プラグインで変換 → 結果を出力 という流れです。

import postcss from 'postcss';
import autoprefixer from 'autoprefixer';

const inputCss = `
  .container {
    display: flex;
    user-select: none;
    transition: transform 0.3s;
  }
`;

async function processCss(): Promise<void> {
  const result = await postcss([autoprefixer]).process(inputCss, {
    from: undefined, // 入力ファイルパス(文字列直接の場合は undefined)
    to: undefined,   // 出力ファイルパス
  });

  console.log(result.css);
  // ベンダープレフィックスが付与された CSS が出力される

  // 警告があれば表示
  for (const warning of result.warnings()) {
    console.warn(warning.toString());
  }
}

processCss();

ファイルを読み書きする実践的なパターン

import postcss from 'postcss';
import autoprefixer from 'autoprefixer';
import postcssPresetEnv from 'postcss-preset-env';
import { readFile, writeFile } from 'node:fs/promises';

async function buildCss(): Promise<void> {
  const inputCss = await readFile('src/styles/main.css', 'utf-8');

  const result = await postcss([
    postcssPresetEnv({ stage: 2 }),
    autoprefixer,
  ]).process(inputCss, {
    from: 'src/styles/main.css',
    to: 'dist/styles/main.css',
    map: { inline: false }, // 外部ソースマップを生成
  });

  await writeFile('dist/styles/main.css', result.css);

  if (result.map) {
    await writeFile('dist/styles/main.css.map', result.map.toString());
  }
}

buildCss();

postcss.config.js を使った設定

多くのビルドツール(webpack、Vite、Next.js など)は postcss.config.js を自動で読み込みます。

// postcss.config.js
module.exports = {
  plugins: [
    require('postcss-preset-env')({ stage: 2 }),
    require('autoprefixer'),
  ],
};

よく使う API

1. postcss(plugins).process() — CSS の変換処理

最も頻繁に使うエントリーポイントです。

import postcss, { type Result } from 'postcss';
import autoprefixer from 'autoprefixer';

const result: Result = await postcss([autoprefixer]).process(
  'a { color: red }',
  { from: 'input.css', to: 'output.css' }
);

console.log(result.css);  // 変換後の CSS 文字列
console.log(result.map);  // ソースマップ(設定時)
console.log(result.warnings()); // 警告の配列

2. postcss.parse() — CSS を AST にパース

CSS 文字列を直接 AST(Root ノード)に変換します。プラグインを通さず AST を操作したい場合に使います。

import postcss, { type Root } from 'postcss';

const root: Root = postcss.parse(`
  .header {
    color: blue;
    font-size: 16px;
  }
  .footer {
    color: gray;
  }
`);

// すべてのルールを走査
root.walkRules((rule) => {
  console.log(`セレクタ: ${rule.selector}`);
});

// すべての宣言(プロパティ)を走査
root.walkDecls((decl) => {
  console.log(`${decl.prop}: ${decl.value}`);
});

3. root.walk*() 系メソッド — AST の走査

AST を効率的に走査するためのメソッド群です。

import postcss from 'postcss';

const root = postcss.parse(`
  @media (max-width: 768px) {
    .container {
      color: red;
      background: url('image.png');
    }
  }
  /* コメント */
`);

// すべてのノードを走査
root.walk((node) => {
  console.log(node.type); // 'atrule' | 'rule' | 'decl' | 'comment'
});

// @ルールのみ走査
root.walkAtRules('media', (atRule) => {
  console.log(atRule.params); // '(max-width: 768px)'
});

// 特定プロパティの宣言のみ走査
root.walkDecls('color', (decl) => {
  decl.value = 'blue'; // color の値をすべて blue に変更
});

// コメントのみ走査
root.walkComments((comment) => {
  comment.remove(); // コメントをすべて削除
});

4. カスタムプラグインの作成

PostCSS プラグインは決まった形式の関数です。

import postcss, { type PluginCreator } from 'postcss';

interface RemoveCommentsOptions {
  preserveImportant?: boolean;
}

const removeComments: PluginCreator<RemoveCommentsOptions> = (
  opts = {}
) => {
  const { preserveImportant = true } = opts;

  return {
    postcssPlugin: 'postcss-remove-comments',

    Comment(comment) {
      if (preserveImportant && comment.text.startsWith('!')) {
        return; // 「!」で始まるコメントは残す
      }
      comment.remove();
    },
  };
};

removeComments.postcss = true;

// 使用例
async function run(): Promise<void> {
  const input = `
    /* 通常のコメント */
    /*! 重要なコメント */
    .foo { color: red; }
  `;

  const result = await postcss([
    removeComments({ preserveImportant: true }),
  ]).process(input, { from: undefined });

  console.log(result.css);
  // /*! 重要なコメント */
  // .foo { color: red; }
}

run();

5. AST ノードの生成・操作

プログラム的に CSS を組み立てたり変更したりできます。

import postcss from 'postcss';

// 新しい Root を作成
const root = postcss.parse('');

// ルールを追加
const rule = postcss.rule({ selector: '.button' });
rule.append(postcss.decl({ prop: 'display', value: 'inline-flex' }));
rule.append(postcss.decl({ prop: 'padding', value: '8px 16px' }));
rule.append(postcss.decl({ prop: 'border-radius', value: '4px' }));

root.append(rule);

// @media ルールを追加
const media = postcss.atRule({
  name: 'media',
  params: '(max-width: 768px)',
});
const mobileRule = postcss.rule({ selector: '.button' });
mobileRule.append(postcss.decl({ prop: 'width', value: '100%' }));
media.append(mobileRule);

root.append(media);

console.log(root.toString());
// .button {
//     display: inline-flex;
//     padding: 8px 16px;
//     border-radius: 4px
// }
// @media (max-width: 768px) {
//     .button {
//         width: 100%
//     }
// }

類似パッケージとの比較

特徴PostCSSSass (dart-sass)LessLightning CSS
アプローチプラグインベースの CSS 変換基盤独自構文のプリプロセッサ独自構文のプリプロセッサRust 製の高速 CSS パーサー/変換
拡張性◎ プラグインで自由に拡張△ 関数・ミックスインで拡張△ 関数・ミックスインで拡張△ 組み込み機能のみ
速度○ JS ベース○ Dart VM○ JS ベース◎ Rust ネイティブで非常に高速
エコシステム◎ 数百のプラグイン◎ 長い歴史と豊富な資産○ 成熟しているが縮小傾向△ 新しく成長中
標準 CSS との互換性◎ 標準 CSS をそのまま扱える△ 独自構文△ 独自構文◎ 標準 CSS ベース
ソースマップ
主な用途Autoprefixer、リント、将来構文変換変数・ネスト・ミックスイン変数・ネスト・ミックスインミニファイ、プレフィックス、バンドル

補足: PostCSS と Sass/Less は競合ではなく併用されることが多いです。Sass でプリプロセスした後に PostCSS で Autoprefixer を適用する、というのは非常に一般的なワークフローです。Lightning CSS は PostCSS の一部ユースケース(Autoprefixer、ミニファイなど)を高速に代替できますが、プラグインエコシステムの柔軟性では PostCSS に及びません。

注意点・Tips

1. from オプションは必ず指定する

from を省略するとソースマップが正しく生成されず、警告が出ます。文字列を直接処理する場合は明示的に from: undefined を渡しましょう。

// ❌ 警告が出る
await postcss([plugin]).process(css);

// ✅ 明示的に undefined を指定
await postcss([plugin]).process(css, { from: undefined });

// ✅ ファイルパスがあるなら指定
await postcss([plugin]).process(css, { from: 'src/style.css' });

2. 同期 API と非同期 API

PostCSS v8 では .process()LazyResult を返します。非同期プラグインを使う場合は必ず await してください。

// 非同期(推奨)
const result = await postcss([plugin]).process(css, { from: undefined });

// 同期的にアクセスしたい場合(非同期プラグインがないことが前提)
const lazyResult = postcss([plugin]).process(css, { from: undefined });
const syncCss = lazyResult.css; // 同期プラグインのみなら動作する

3. プラグインの順序は重要

プラグインは配列の先頭から順に実行されます。順序を間違えると意図しない結果になります。

// ✅ 推奨順序: 構文変換 → プレフィックス → ミニファイ
postcss([
  postcssPresetEnv({ stage: 2 }),  // 1. 将来構文を変換
  autoprefixer,                     // 2. ベンダープレフィックスを付与
  cssnano,                          // 3. 最後にミニファイ
]);

4. PostCSS v8 のプラグイン互換性

PostCSS v8 ではプラグイン API が変更されました。古いプラグイン(v7 以前向け)を使うと互換性の警告が出ることがあります。プラグインの peerDependencies を確認し、PostCSS v8 対応版を使いましょう。

5