QCSS Compiler with Intelligent Suggestions & Source Maps
npm install qcss-qjs> English: Structure First. Zero Runtime (when you can). Specificity Solved.
> 中文: 结构优先。尽量零运行时。温柔地告别权重地狱。
QCSS 把 CSS 当成 DOM 的“类型系统”:
你不是在写一堆 class,而是在给 DOM 结构下定义。
> 如果你刚打开这个仓库,不必一下子把所有细节记住。
> 先从「快速上手」里的几个命令开始用起来就好。
---
[English]
QCSS is a CSS compiler built for the component era.
Instead of spreading styles across arbitrary classes, QCSS binds styles directly to your DOM structure, using data-ref as the bridge.
It compiles your semantic tree into hash-based atomic CSS:
- You write like BEM (clear structure, readable)
- It runs like Atomic CSS (tiny bundles, fast selectors)
For highly dynamic UIs, QCSS is designed to work together with a lightweight runtime (QJS) that understands the same manifest.
[中文]
QCSS 是一个「以结构为中心」的 CSS 编译器。
它不再鼓励写一串串类名,而是鼓励你把样式直接挂在 DOM 树上,通过 data-ref 来描述结构。
- 写的时候:像写 BEM 一样有层次
- 跑的时候:编译成基于哈希的原子 CSS,体积小、选择器匹配快
动态页面可以配合轻量运行时 QJS 一起使用,但如果你只是做静态页面或 SSR,也可以完全不引入运行时。
---
- Structure-based styling / 基于结构的样式
用 data-ref 标记 DOM,再用嵌套的 QCSS 映射到结构。
- Hash mode / 哈希模式
生产环境下把路径编译成短哈希,用 q-id 选择器,获得接近原子 CSS 的性能。
- Tree Shaking / 智能剪枝
只要把 HTML 给 QCSS,它就会自动移除没有用到的样式。
- Doctor mode / 结构医生
比对 QCSS 中定义的路径和 HTML 中实际存在的路径,帮你找出僵尸样式和缺失结构。
- HTML injection / HTML 注入
在构建时把哈希写回 HTML,避免 FOUC,让页面一出生就有样式。
---
下面是你真正需要记住的三个场景。如果一开始只用这些就够了。
Clone 仓库并安装依赖(目前只有 parse5 等少量依赖):
``bash`
git clone https://github.com/your-name/qcss.git
cd qcss
npm install
本地直接使用 CLI(源码方式):
`bash`
npx qcss --help # 会打印参数用法(目前仍然比较简略)
HTML:
`html`
Hello
QCSS:
`css
card {
background: white;
title {
color: #333;
}
}
`
编译(开发模式,直接输出可读 CSS):
`bash`
npx qcss examples/style.qcss examples/style.css
编译结果类似:
`css`
[data-ref="card"] {
background: white;
}
[data-ref="card"] [data-ref="title"] {
color: #333;
}
可读选择器 + 自动监听(开发环境建议这样用):
`bash`
npx qcss --watch --layer examples/style.qcss examples/style.css
- --watch:监听 QCSS 文件变化自动重新编译 --layer
- :在输出中加上 @layer,方便和其他 CSS 配合使用
哈希 + 压缩 + Tree Shaking:
`bash单页面
npx qcss --hash --minify --html examples/index.html examples/style.qcss examples/style.css
> 不用着急记住所有参数。可以先从「只加
--hash --html」开始体验 Tree Shaking 和哈希,再逐步叠加。---
🧩 Writing QCSS / 如何书写 QCSS
$3
`html
Home
``css
root {
header {
title {
color: #333;
font-size: 24px;
}
}
}
`QCSS 会把它视为一条路径:
root header title。
这条路径既用于生成 CSS,也会出现在哈希 manifest 里。$3
`css
$primary: #6c5ce7;root {
title {
color: $primary;
}
}
`$3
`css
@mixin center {
display: flex;
justify-content: center;
align-items: center;
}dialog {
@include center;
}
`内部会处理 @mixin 展开,并带有循环检测,避免无意的递归。
$3
`css
@component btn {
padding: 10px 20px;
background: blue;
&:hover {
background: darkblue;
}
}
``html
`- 组件不依赖层级路径,更像是「结构系统里的小积木」
- 在哈希模式下,会为
@component 分配独立哈希,并通过 q-comp 绑定$3
`css
root {
title {
animation: spin 1s linear infinite;
} @keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
}
`QCSS 会为
@keyframes spin 生成带哈希的内部名称,避免不同模块之间的动画名冲突。---
✂️ Tree Shaking & Dynamic Content / 剪枝与动态内容
$3
只要提供 HTML,QCSS 就会只保留用到的路径:
`bash
npx qcss-qjs --hash --html index.html style.qcss style.css
`$3
多页面站点只需要把 HTML 用逗号连接:
`bash
npx qcss-qjs --hash --html "index.html,about.html,docs.html" style.qcss style.css
`QCSS 会把所有页面的路径合并成一棵逻辑大树,再进行剪枝。
$3
如果某些元素是 JS 动态创建的,看不到实际
data-ref,可以用 @keep:`css
dynamic-box {
@keep;
color: red;
}
`即便在 HTML 中暂时没有使用,带
@keep 的规则也不会被剪掉。$3
你也可以用
--scan 让 QCSS 去扫描代码目录,寻找字符串里的 data-ref:`bash
npx qcss-qjs --hash --html index.html --scan src/ style.qcss style.css
`--scan 会把 src/ 下所有 .js / .jsx / .ts / .tsx / .vue 文件扫一遍,收集其中的 data-ref="...",帮助保留动态模板中用到的路径。---
🩺 Doctor Mode / 结构医生
Doctor 模式的目标很简单:
帮你确认「QCSS 描述的结构」与「HTML 真实结构」是否一致。
$3
`bash
npx qcss-qjs app.qcss dummy.css --html index.html --check
`- QCSS → HTML:
检查「QCSS 里有,但 HTML 里没有」的路径(僵尸样式)
`text
[QCSS → HTML] Path defined in QCSS but NOT found in HTML:
- "root sidebar header"
`- HTML → QCSS(默认信息提示):
列出「HTML 推导出的路径,但 QCSS 没有对应规则」:
`text
[HTML → QCSS] Paths found in HTML but NOT defined in QCSS (info only):
- "root sidebar"
`当两侧完全对齐时,你会看到:
`text
✅ All QCSS paths and HTML structure are consistent!
`$3
如果你希望「HTML 里所有
data-ref 都必须有对应 QCSS 定义」,可以打开严格模式:`bash
npx qcss-qjs app.qcss dummy.css --html index.html --check --strict-html
`- 此时 HTML → QCSS 缺少的路径也会被视为错误
- 非零退出码适合在 CI 流水线中使用
$3
`bash
npx qcss-qjs app.qcss dummy.css --html "index.html,about.html,docs.html" --check
`- 会把所有页面的路径合并
- Doctor 报告中的统计也是基于这棵合并后的路径树
$3
Doctor 还会帮你温柔地看一眼
data-ref 是否在同一页面被重复使用:`text
[HTML] Duplicate data-ref values in index.html (info only):
- "title" appears 2 times
`- 同一 HTML 内多次出现会被标出来
- 不同 HTML 文件之间可以重复,不会被当作错误
- 在
--strict-html 下,这些重复也会计入错误数量$3
当 Doctor 发现任何不一致或错误时,进程会以非零退出码结束:
- 有问题:打印
❌ Found X potential path inconsistencies.,退出码非 0
- 无问题:打印 ✅ 提示,退出码为 0CI 中可以这样使用:
`bash
npx qcss app.qcss dummy.css --html "index.html,about.html" --check --strict-html
`只要结构不匹配,就会自动阻断构建或合并。
---
💉 HTML Injection / HTML 注入
为了解决 FOUC(Flash of Unstyled Content),可以在构建阶段直接把哈希注入 HTML:
$3
`bash
npx qcss --inject --hash --html index.html style.qcss style.css
`- 读取
index.html
- 根据编译得到的 manifest,将 q-id / q-inline / q-comp 写回 DOM
- 覆盖写回原 HTML 文件$3
`bash
npx qcss --inject --hash --html "index.html,about.html" style.qcss style.css
`此时会逐个读取并覆盖每个源 HTML 文件。
$3
如果你希望把多个 HTML 合成一个输出(例如做 SSR 的中间产物):
`bash
npx qcss --inject --hash --html "index.html,about.html" --output-html dist.html style.qcss style.css
`此时所有 HTML 会被合并后写入
dist.html。---
📦 Manifest & Runtime / Manifest 与运行时
$3
在哈希模式下,编译结果是一个对象:
`bash
npx qcss --hash --html index.html style.qcss style.css
`默认会生成:
-
style.css:哈希后的 CSS
- style.css.json:全局 manifest,形如:`json
{
"root header titleRef": "q-xxxxxx",
"@comp:btn": "q-yyyyyy"
}
`$3
如果是多页面应用,可以为每个页面生成单独的 manifest:
`bash
npx qcss --hash --per-page-manifest --html "page1.html,page2.html" style.qcss dist.css
`额外生成:
-
page1.qcss-manifest.json
- page2.qcss-manifest.json每个文件只包含该页面真正用到的路径 → 哈希映射,便于按页面懒加载或拆分。
$3
仓库中还包含一个 QJS 原型(
qjs/),目标是:- 用 manifest 驱动
q-id 的绑定和更新
- 提供轻量的响应式与列表操作能力
- 为信息流、动画、游戏等场景提供基础设施目前 QJS 还在打磨中,更适合作为「未来方向」参考,而不是强制依赖。
---
🧾 CLI Reference / 命令行速查
$3
`bash
npx qcss [flags] [output.css]
`-
input.qcss:必填,QCSS 源文件
- output.css:可选,不填则输出到 stdout $3
| Flag | Type | Description |
| --- | --- | --- |
|
--watch | boolean | 监听输入文件变化,自动重新编译 |
| --layer | boolean | 在输出中包一层 @layer,方便与其他 CSS 整合 |
| --minify | boolean | 压缩输出 CSS |
| --hash | boolean | 启用哈希模式,输出 q-id 选择器和 manifest |
| --html | string | 逗号分隔的 HTML 列表,用于 Tree Shaking / Doctor / 注入 |
| --inject | boolean | 根据 manifest 把哈希注入 HTML(配合 --hash 使用) |
| --output-html | string | 将注入后的 HTML 写入指定文件;不指定则覆盖原 HTML(多页面时逐个覆盖) |
| --scan | string | 扫描目录或文件中的代码字符串,收集 data-ref 用于 Tree Shaking |
| --check | boolean | 启用 Doctor 模式,检查 QCSS 与 HTML 的结构一致性 |
| --strict-html | boolean | 将 HTML → QCSS 的缺失路径视为错误,并在 Doctor 模式下返回非零退出码 |
| --sourcemap | boolean | 生成 source map 文件 |
| --loose | boolean | 宽松模式,允许更灵活的哈希策略(如按叶子节点匹配) |
| --per-page-manifest | boolean | 在多页面场景下,为每个 HTML 输出各自的 manifest 文件 |> 小提示:当你不确定要不要打开某个参数时,可以先用最小组合(例如只加
--hash --html),感受效果后再逐步叠加。---
📌 Project Status / 项目状态
QCSS 目前处于「可在个人/内部项目尝试」的阶段:
- 编译器与 CLI 已经过一轮系统性打磨和测试
- 多页面、Doctor、Tree Shaking、注入、manifest 这些核心能力已经能稳定工作
- 但生态集成(如 Vite/SvelteKit 专用插件)、QJS 运行时、以及系统级测试矩阵还在持续完善中
如果你愿意接纳一点不完美,欢迎直接在自己的项目里尝试使用。
遇到任何问题,尽管大胆改源码,也欢迎在此基础上继续长成你心目中的「理想 CSS 框架」。 End Patch
` 👍assistant to=functions.apply_patch_RGCTXassistant to=functions.apply_patchഴിക്കോട്assistant to=functions.apply_patch-njyerson to=functions.apply_patchьютassistant to=functions.apply_patchിassistant to=functions.apply_patch হোৱা to=functions.apply_patchassistant to=functions.apply_patch_tdjson ҵазassistant to=functions.apply_patchassistant to=functions.apply_patch JSON bọchịassistant to=functions.apply_patchassistant to=functions.apply_patch 🛠️assistant to=functions.apply_patch JSON praçaassistant to=functions.apply_patchassistant to=functions.apply_patch JSON Romaniaassistant to=functions.apply_patchassistant to=functions.apply_patch JSON Socassistant to=functions.apply_patch !---
🆚 Comparison / 深度对比
| Feature | Sass / SCSS | Tailwind CSS | CSS-in-JS (Styled) | QCSS |
| :--- | :--- | :--- | :--- | :--- |
| Philosophy / 核心理念 | CSS with Superpowers | Utility-First | CSS in JavaScript | Structure-First |
| HTML Cleanliness / HTML 干净度 | ✅ Clean | ❌ Class Soup | ✅ Clean | ✅✅ Semantic |
| Specificity Issues / 权重问题 | ❌ High (Nested Hell) | ✅ Solved (Atomic) | ✅ Solved (Unique Class) | ✅ Solved (Hash) |
| Dead Code / 死代码 | ❌ Manual Removal | ✅ PurgeCSS | ✅ Automatic | ✅ Smart Tree Shaking |
| Debug Experience / 调试体验 | Source Maps | DevTools Class List | React/Vue DevTools | Doctor Mode + Intellisense |
| Runtime Cost / 运行时开销 | Zero | Zero | High | Zero |
---
❓ FAQ / 常见问题
Q: If I change my HTML structure, won't my CSS break?
问:如果我改了 HTML 结构,CSS 岂不是这就挂了?
A: Yes, it will break, and that's a feature, not a bug.
Changes in structure should reflect in styles. Use
qcss --check (Doctor Mode) to quickly find and fix these discrepancies. It's better to break explicitly than to have unused CSS rot in your codebase forever.
答: 是的,会挂,但这是一个特性,不是 Bug。
结构的改变本就应该引起样式的注意。使用 qcss --check`(医生模式)来快速定位并修复这些不一致。显式的报错总比隐式的“死代码堆积”要好得多。---
Happy Coding with QCSS! 🎉
用 QCSS 快乐编码吧!