SpiraCSS HTML to SCSS
HTML / テンプレートから SpiraCSS のルールに沿った SCSS ファイルを自動生成する VSCode 拡張 & CLI です。
<!-- 選択した HTML -->
<section class="hero-section">
<h1 class="title">Welcome</h1>
<p class="lede">Introduction text...</p>
<div class="feature-card">
<h2 class="heading">Feature</h2>
</div>
<div class="cta-box">
<a class="link" href="#">Learn more</a>
</div>
</section>
↓ SpiraCSS 形式の SCSS を自動生成
hero-section.scss ← ルート Block
scss/
feature-card.scss ← 子 Block
cta-box.scss ← 子 Block
index.scss ← @use で子 Block を集約
hero-section.scss(ルート Block):
@use "global" as *;
@use "sass:meta";
// @assets/css/index.scss
.hero-section {
@include meta.load-css("scss");
// block base styles
> .title {
// element base styles
}
> .lede {
// element base styles
}
> .feature-card {
// @rel/scss/feature-card.scss
// child component layout
}
> .cta-box {
// @rel/scss/cta-box.scss
// child component layout
}
// --shared ----------------------------------------
// --interaction -----------------------------------
// @at-root & {
// }
}
scss/feature-card.scss(子 Block):
@use "global" as *;
// @rel/../hero-section.scss
.feature-card {
// block base styles
> .heading {
// element base styles
}
// --shared ----------------------------------------
// --interaction -----------------------------------
// @at-root & {
// }
}
scss/index.scss(子 Block 集約):
@use "feature-card";
@use "cta-box";
生成される SCSS の特徴:
- Block/Element 判定: class 属性の先頭トークン(base class)を
blockCase / elementCase / customPatterns で判定
- 子セレクタ強制:
> .element / > .child-block の形式で構造を明確化
- ファイル分離 + index.scss: 子 Block は
childScssDir 配下に別ファイルとして生成し、index.scss で @use を統合
- shared/interaction セクション: SpiraCSS のセクション構成に沿ったコメントを挿入
- meta.load-css(): ルート Block のみ
@include meta.load-css("scss")(childScssDir に応じて)で子 Block を読み込み
- ページエントリコメント:
// @assets/css/index.scss は pageEntryAlias / pageEntrySubdir のヒント
- @rel コメント: 親子 Block 間の参照を自動挿入(SpiraCSS Comment Links で Cmd/Ctrl+Click ジャンプ可能)
- グローバル @use:
stylesEntry(または globalScssModule)のモジュールパスを先頭に挿入
VSCode 拡張のインストール
- Marketplace で "SpiraCSS HTML to SCSS" を検索(拡張 ID:
spiracss.spiracss-html-to-scss)
- ローカルで使う場合は
build/*.vsix を「VSIX からインストール」(未生成なら yarn package で作成)
CLI インストール
yarn add -D spiracss-html-to-scss
使い方(VSCode)
| コマンド |
ショートカット |
説明 |
| Generate SCSS from Root |
Cmd+Alt+R |
ルート要素から SCSS ファイル群を一括生成 |
| Generate SCSS from Selection |
Cmd+Alt+S |
選択要素から SCSS ファイル群を個別生成 |
| Insert SpiraCSS placeholders |
Cmd+Alt+E |
HTML にプレースホルダクラスを付与(SCSS 生成なし) |
Root モード
- ルート Block 要素を含む範囲を選択
Cmd+Alt+R または右クリックメニューから実行
- 編集中ファイルと同じフォルダに SCSS が生成される
補足: Root モードは選択範囲内の最初の要素をルートとして扱います。先頭クラスが Block 判定に一致しない場合は生成されません。
your-component/
├─ hero-section.scss ← ルート Block
├─ scss/
│ ├─ feature-card.scss ← 子 Block
│ └─ index.scss ← @use 自動マージ
└─ your-template.html
Selection モード
- 個別に SCSS 化したい Block 要素を選択
Cmd+Alt+S または右クリックメニューから実行
scss/ フォルダに各 Block の SCSS が生成される
補足: 選択範囲内に複数の Block がある場合はそれぞれ生成されます。
プレースホルダ付与
SCSS を生成せず、HTML に SpiraCSS 用の目印クラスだけを付与します。
クラス名が未定の段階で構造を先に整えたい場合に便利です。
- ルートにしたい要素を含む範囲を選択
Cmd+Alt+E または右クリックメニューから実行
- 全ての子孫要素を再帰的に走査し、SpiraCSS 構造に整形
- 子要素を持つ要素 → Block プレースホルダを付与
- 子要素を持たない要素(葉ノード) → Element プレースホルダを付与
- 既に Block 名があればスキップ
- Element 名で子を持てば Block 形式に変換(例:
title → title-box)
プレースホルダ名は blockCase / elementCase 設定に応じて変わります(両者は独立して設定可能):
Block プレースホルダ(blockCase に依存):
blockCase |
プレースホルダ |
kebab(既定) |
block-box |
camel |
blockBox |
pascal |
BlockBox |
snake |
block_box |
Element プレースホルダ(elementCase に依存):
elementCase |
プレースホルダ |
kebab(既定) |
element |
camel |
element |
pascal |
Element |
snake |
element |
CLI
3 つのコマンドを提供します。すべて spiracss.config.js の設定を参照します。
詳細なオプションやエラーコードは docs/cli.md を参照してください。
spiracss-html-to-scss
SCSS 自動生成(VSCode 拡張と同じロジック)
# Root モード
npx spiracss-html-to-scss --root path/to/file.html
# Selection モード
npx spiracss-html-to-scss --selection path/to/file.html
# 標準入力から
cat file.html | npx spiracss-html-to-scss --selection --stdin --base-dir src/components/sample
オプション: --dry-run(ファイル書き込みなし)、--json(JSON 出力)、--ignore-structure-errors(構造 lint を無視して生成)
補足: デフォルトでは構造 lint を実行し、エラーがある場合は終了します。
出力先のルール:
- 入力ファイル指定: 入力ファイルと同じディレクトリ(
--base-dir 指定時は上書き)
--stdin: --base-dir(省略時はカレントディレクトリ)
- 子 Block は
childScssDir(既定 scss)
spiracss-html-lint
HTML 構造が SpiraCSS ルールに従っているかを検証
npx spiracss-html-lint --root path/to/file.html
npx spiracss-html-lint --root path/to/file.html --json
プレースホルダクラス(blockCase / elementCase に応じたもの)を付与
npx spiracss-html-format path/to/file.html -o formatted.html
設定
プロジェクトルートの spiracss.config.js で動作をカスタマイズできます。
// spiracss.config.js
module.exports = {
stylelint: {
classStructure: {
naming: {
// Block の命名規則: kebab / camel / pascal / snake
blockCase: 'kebab',
// Element の命名規則: kebab / camel / pascal / snake
elementCase: 'kebab',
}
}
},
generator: {
// SCSS 先頭の @use で参照するモジュールパス
stylesEntry: 'global',
// ページエントリコメントのヒント
pageEntryAlias: 'assets',
pageEntrySubdir: 'css',
// 子 Block SCSS のディレクトリ名
childScssDir: 'scss',
}
}
stylesEntry は @use 文そのものではなく、モジュールパスのみを指定します(例: global, @styles/partials/global)。旧キー globalScssModule でも同様に設定できます。
設定の全体像は docs/spiracss-config.md を参照してください。
対象と制限
対応テンプレート
HTML、Astro、EJS、Nunjucks、React/JSX、Vue/Nuxt、Svelte など。
テンプレート構文(<%...%>、{{...}}、{...} など)は正規表現で除去し、class / className 属性の静的クラス名を抽出します。
Block 判定
class 属性の先頭トークンを base class として判定します。先頭トークンが blockCase(または customPatterns.block)に一致する場合のみ Block として扱います。Block/Element として扱いたいクラスは先頭に置いてください。
blockCase |
Block の例 |
elementCase |
Element の例 |
kebab(既定) |
hero-section, feature-card |
kebab(既定) |
title, lede |
camel |
heroSection, featureCard |
camel |
title, body |
pascal |
HeroSection, FeatureCard |
pascal |
Title, Body |
snake |
hero_section, feature_card |
snake |
title, lede |
注意: elementCase が pascal の場合のみ、Element は大文字始まり 1 語(例: Title)になります。それ以外は小文字 1 語です。customPatterns を指定した場合は該当パターンが優先されます。-、_、u- で始まるクラスは Modifier/Utility 扱いで base class にはなりません。
制限事項
- Vue/Svelte の
:class バインド内の静的クラスは抽出しない(class="..." 側に書くことを推奨)
- 動的に出現するクラス名は追跡しない
- プレースホルダ付与コマンド(
Insert SpiraCSS placeholders)はテンプレート構文(EJS <% %>, Nunjucks {{ }} {% %}, Astro frontmatter 等)を含む HTML には適用されません。これらの構文は HTML パース時に破壊される恐れがあるため、静的な HTML 断片に対してのみ使用してください
- JSX/React の
className は 文字列 / テンプレートリテラル なら処理対象です。className={styles.foo} のような動的バインディングはスキップされます
技術詳細(サニタイズ処理、Block 判定、Modifier 抽出など)は docs/internals.md を参照してください。
関連ツール
SpiraCSS 関連ツールの他のパッケージ:
Release Notes
0.1.1
- 関連ツールのリンクを VSCode Marketplace URL に更新
0.1.0