npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

qcss-qjs

v1.4.3

Published

QCSS Compiler with Intelligent Suggestions & Source Maps

Readme

QCSS (Quantitative CSS) 🎨

Size Dependencies License

English: Structure First. Zero Runtime (when you can). Specificity Solved.
中文: 结构优先。尽量零运行时。温柔地告别权重地狱。

QCSS 把 CSS 当成 DOM 的“类型系统”:
你不是在写一堆 class,而是在给 DOM 结构下定义。

如果你刚打开这个仓库,不必一下子把所有细节记住。
先从「快速上手」里的几个命令开始用起来就好。


🌟 What is QCSS? / 什么是 QCSS?

[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,也可以完全不引入运行时。


✨ Core Ideas / 核心理念

  • 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,让页面一出生就有样式。


🚀 Quick Start / 快速上手

下面是你真正需要记住的三个场景。如果一开始只用这些就够了。

1. Prepare / 准备

Clone 仓库并安装依赖(目前只有 parse5 等少量依赖):

git clone https://github.com/your-name/qcss.git
cd qcss
npm install

本地直接使用 CLI(源码方式):

npx qcss --help  # 会打印参数用法(目前仍然比较简略)

2. Minimal Example / 最小示例

HTML:

<div data-ref="card">
  <h3 data-ref="title">Hello</h3>
</div>

QCSS:

card {
  background: white;

  title {
    color: #333;
  }
}

编译(开发模式,直接输出可读 CSS):

npx qcss examples/style.qcss examples/style.css

编译结果类似:

[data-ref="card"] {
  background: white;
}
[data-ref="card"] [data-ref="title"] {
  color: #333;
}

3. Development Build / 开发构建

可读选择器 + 自动监听(开发环境建议这样用):

npx qcss --watch --layer examples/style.qcss examples/style.css
  • --watch:监听 QCSS 文件变化自动重新编译
  • --layer:在输出中加上 @layer,方便和其他 CSS 配合使用

4. Production Build / 生产构建(单/多页面)

哈希 + 压缩 + Tree Shaking:

# 单页面
npx qcss --hash --minify --html examples/index.html examples/style.qcss examples/style.css

# 多页面(用逗号分隔)
npx qcss --hash --minify --html "examples/index.html,examples/about.html" examples/style.qcss examples/style.css

不用着急记住所有参数。可以先从「只加 --hash --html」开始体验 Tree Shaking 和哈希,再逐步叠加。


🧩 Writing QCSS / 如何书写 QCSS

Structure-based Styling / 结构化样式

<main data-ref="root">
  <header data-ref="header">
    <h1 data-ref="title">Home</h1>
  </header>
</main>
root {
  header {
    title {
      color: #333;
      font-size: 24px;
    }
  }
}

QCSS 会把它视为一条路径:root header title
这条路径既用于生成 CSS,也会出现在哈希 manifest 里。

Variables / 变量

$primary: #6c5ce7;

root {
  title {
    color: $primary;
  }
}

Mixins / 混合宏

@mixin center {
  display: flex;
  justify-content: center;
  align-items: center;
}

dialog {
  @include center;
}

内部会处理 @mixin 展开,并带有循环检测,避免无意的递归。

Components / 组件(位置无关)

@component btn {
  padding: 10px 20px;
  background: blue;
  &:hover {
    background: darkblue;
  }
}
<button data-comp="btn">Click Me</button>
  • 组件不依赖层级路径,更像是「结构系统里的小积木」
  • 在哈希模式下,会为 @component 分配独立哈希,并通过 q-comp 绑定

Scoped Animations / 动画隔离

root {
  title {
    animation: spin 1s linear infinite;
  }

  @keyframes spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
  }
}

QCSS 会为 @keyframes spin 生成带哈希的内部名称,避免不同模块之间的动画名冲突。


✂️ Tree Shaking & Dynamic Content / 剪枝与动态内容

Basic Tree Shaking / 基本剪枝

只要提供 HTML,QCSS 就会只保留用到的路径:

npx qcss-qjs --hash --html index.html style.qcss style.css

Multi-page Tree Shaking / 多页面剪枝

多页面站点只需要把 HTML 用逗号连接:

npx qcss-qjs --hash --html "index.html,about.html,docs.html" style.qcss style.css

QCSS 会把所有页面的路径合并成一棵逻辑大树,再进行剪枝。

Keep Dynamic Branches / 保留动态分支

如果某些元素是 JS 动态创建的,看不到实际 data-ref,可以用 @keep

dynamic-box {
  @keep;
  color: red;
}

即便在 HTML 中暂时没有使用,带 @keep 的规则也不会被剪掉。

Scan Dynamic Templates / 扫描动态模板

你也可以用 --scan 让 QCSS 去扫描代码目录,寻找字符串里的 data-ref

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 真实结构」是否一致。

Basic Check / 基本检查

npx qcss-qjs app.qcss dummy.css --html index.html --check
  • QCSS → HTML
    检查「QCSS 里有,但 HTML 里没有」的路径(僵尸样式)

    [QCSS → HTML] Path defined in QCSS but NOT found in HTML:
      - "root sidebar header"
  • HTML → QCSS(默认信息提示)
    列出「HTML 推导出的路径,但 QCSS 没有对应规则」:

    [HTML → QCSS] Paths found in HTML but NOT defined in QCSS (info only):
      - "root sidebar"

当两侧完全对齐时,你会看到:

✅ All QCSS paths and HTML structure are consistent!

Strict HTML Mode / 严格 HTML 模式

如果你希望「HTML 里所有 data-ref 都必须有对应 QCSS 定义」,可以打开严格模式:

npx qcss-qjs app.qcss dummy.css --html index.html --check --strict-html
  • 此时 HTML → QCSS 缺少的路径也会被视为错误
  • 非零退出码适合在 CI 流水线中使用

Multi-page Check / 多页面检查

npx qcss-qjs app.qcss dummy.css --html "index.html,about.html,docs.html" --check
  • 会把所有页面的路径合并
  • Doctor 报告中的统计也是基于这棵合并后的路径树

data-ref Duplicates / data-ref 重复检测

Doctor 还会帮你温柔地看一眼 data-ref 是否在同一页面被重复使用:

[HTML] Duplicate data-ref values in index.html (info only):
  - "title" appears 2 times
  • 同一 HTML 内多次出现会被标出来
  • 不同 HTML 文件之间可以重复,不会被当作错误
  • --strict-html 下,这些重复也会计入错误数量

CI Integration / CI 集成

当 Doctor 发现任何不一致或错误时,进程会以非零退出码结束:

  • 有问题:打印 ❌ Found X potential path inconsistencies.,退出码非 0
  • 无问题:打印 ✅ 提示,退出码为 0

CI 中可以这样使用:

npx qcss app.qcss dummy.css --html "index.html,about.html" --check --strict-html

只要结构不匹配,就会自动阻断构建或合并。


💉 HTML Injection / HTML 注入

为了解决 FOUC(Flash of Unstyled Content),可以在构建阶段直接把哈希注入 HTML:

Single Page / 单页面

npx qcss --inject --hash --html index.html style.qcss style.css
  • 读取 index.html
  • 根据编译得到的 manifest,将 q-id / q-inline / q-comp 写回 DOM
  • 覆盖写回原 HTML 文件

Multi-page / 多页面

npx qcss --inject --hash --html "index.html,about.html" style.qcss style.css

此时会逐个读取并覆盖每个源 HTML 文件。

Merge Output / 合并输出(可选)

如果你希望把多个 HTML 合成一个输出(例如做 SSR 的中间产物):

npx qcss --inject --hash --html "index.html,about.html" --output-html dist.html style.qcss style.css

此时所有 HTML 会被合并后写入 dist.html


📦 Manifest & Runtime / Manifest 与运行时

Global Manifest / 全局 Manifest

在哈希模式下,编译结果是一个对象:

npx qcss --hash --html index.html style.qcss style.css

默认会生成:

  • style.css:哈希后的 CSS
  • style.css.json:全局 manifest,形如:
{
  "root header titleRef": "q-xxxxxx",
  "@comp:btn": "q-yyyyyy"
}

Per-page Manifest / 按页面 Manifest

如果是多页面应用,可以为每个页面生成单独的 manifest:

npx qcss --hash --per-page-manifest --html "page1.html,page2.html" style.qcss dist.css

额外生成:

  • page1.qcss-manifest.json
  • page2.qcss-manifest.json

每个文件只包含该页面真正用到的路径 → 哈希映射,便于按页面懒加载或拆分。

QJS Runtime (Experimental) / QJS 运行时(实验性)

仓库中还包含一个 QJS 原型(qjs/),目标是:

  • 用 manifest 驱动 q-id 的绑定和更新
  • 提供轻量的响应式与列表操作能力
  • 为信息流、动画、游戏等场景提供基础设施

目前 QJS 还在打磨中,更适合作为「未来方向」参考,而不是强制依赖。


🧾 CLI Reference / 命令行速查

Basic Usage / 基本用法

npx qcss [flags] <input.qcss> [output.css]
  • input.qcss:必填,QCSS 源文件
  • output.css:可选,不填则输出到 stdout

Flags / 参数

| Flag | Type | Description | | --- | --- | --- | | --watch | boolean | 监听输入文件变化,自动重新编译 | | --layer | boolean | 在输出中包一层 @layer,方便与其他 CSS 整合 | | --minify | boolean | 压缩输出 CSS | | --hash | boolean | 启用哈希模式,输出 q-id 选择器和 manifest | | --html <files> | string | 逗号分隔的 HTML 列表,用于 Tree Shaking / Doctor / 注入 | | --inject | boolean | 根据 manifest 把哈希注入 HTML(配合 --hash 使用) | | --output-html <file> | string | 将注入后的 HTML 写入指定文件;不指定则覆盖原 HTML(多页面时逐个覆盖) | | --scan <path> | 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 快乐编码吧!