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

css-typed-om-polyfill

v1.0.0

Published

A JavaScript polyfill for the CSS Typed Object Model (Level 1)

Downloads

31

Readme

Moonlight CSS Typed OM Polyfill

Moonlight 是一个高性能、高精度的 CSS Typed Object Model (OM) Level 1 规范 JavaScript polyfill。

不同于普通的垫片库,Moonlight 旨在通过 微架构优化 (Velocity Engine)代数逻辑引擎 (Algebraic Soul),在不支持原生 API 的环境中提供接近甚至在某些特定场景下超越原生的性能体验。

它不仅是一个工具,更是逻辑与速度的共生体。

目录

简介

CSS Typed Object Model 允许开发者以对象的形式操作 CSS 值,而不是脆弱的字符串拼接。Moonlight 将这种能力带到了所有现代浏览器中。

它专注于:

  1. 类型安全:严格区分 numberlengthangle 等类型,拒绝非法计算。
  2. 数学化简:自动应用分配律、常量折叠,将复杂的 calc() 树化简为最优形式。
  3. 零分配解析:使用优化的词法分析器,最小化垃圾回收 (GC) 压力。

核心进化

  • Velocity Engine (极速引擎): 采用类数组结构处理变换列表;针对 2 参数 calc() 运算提供极速“热路径 (Hot Path)”。
  • Algebraic Soul (代数灵魂): 实现了数学分配律 ((A + B) * k = Ak + Bk) 和智能倒数折叠。
  • Strict Typing (严苛类型): 严格遵循规范,禁止 number + length (如 calc(0 + 10px)),并提供精准的错误提示。
  • Full Transforms: 完整支持 CSS Transform Module Level 2,包括 skew, perspectivetoMatrix() 计算。

支持的接口

Moonlight 实现了规范中的核心数学和变换接口:

基础值:

  • CSSStyleValue (解析入口)
  • CSSNumericValue (所有数值基类)
  • CSSUnitValue (例如: 10px, 50%)
  • CSSKeywordValue (例如: auto)
  • CSSUnparsedValue (兜底类型)

数学表达式:

  • CSSMathSum, CSSMathProduct
  • CSSMathNegate, CSSMathInvert
  • CSSMathMin, CSSMathMax, CSSMathClamp

变换与矩阵:

  • CSSTransformValue (类数组对象,支持迭代)
  • CSSTranslate, CSSRotate, CSSScale
  • CSSSkew, CSSSkewX, CSSSkewY
  • CSSPerspective
  • 支持 .toMatrix() 返回 DOMMatrix

DOM 扩展:

  • HTMLElement.prototype.attributeStyleMap

安装

直接在项目中引入 polyfill 脚本。它会自动检测原生支持,仅在必要时激活。

<script src="cssom.js"></script>
<script>
  const el = document.querySelector('#box');
  // 如果浏览器不支持原生 Typed OM,Moonlight 将接管 attributeStyleMap
  el.attributeStyleMap.set('opacity', 0.5);
</script>

基本用法

操作 attributeStyleMap

const el = document.getElementById('hero');

// 设置样式 (自动装箱)
el.attributeStyleMap.set('font-size', CSS.rem(1.5));
el.attributeStyleMap.set('width', CSS.px(100));
el.attributeStyleMap.set('opacity', CSS.number(0.8));

// 获取样式
const width = el.attributeStyleMap.get('width');
console.log(width.value); // 100
console.log(width.unit);  // "px"
console.log(width.toString()); // "100px"

// 类型检查
console.log(width instanceof CSSUnitValue); // true

使用工厂函数

// 创建不同单位的值
const angle = CSS.deg(45);
const time = CSS.s(1.5);
const percent = CSS.percent(100);

// 链式计算
const result = CSS.px(10).add(CSS.px(20)).mul(2);
console.log(result.toString()); // "60px" (自动化简)

高级用法

代数运算与优化

Moonlight 不仅仅是存储表达式,它会像编译器一样优化它们。

// 1. 常量折叠 (Constant Folding)
const a = CSS.px(10).mul(2);
console.log(a.toString()); // "20px" (而不是 calc(10px * 2))

// 2. 分配律应用 (Distributive Law)
// (100% - 20px) / 2  =>  50% - 10px
const b = CSS.percent(100).sub(CSS.px(20)).div(2);
console.log(b.toString()); // "calc(50% + -10px)" 
// 这种优化对于避免深层嵌套的 calc() 树至关重要

变换与矩阵 (Transforms)

支持完整的变换对象模型和矩阵计算。

// 解析变换字符串
const transform = CSSStyleValue.parse('transform', 'translate(10px, 50%) rotate(45deg)');

// 像数组一样访问
console.log(transform[0] instanceof CSSTranslate); // true
console.log(transform[1] instanceof CSSRotate);    // true

// 迭代
for (const component of transform) {
    console.log(component.toString());
}

// 计算矩阵 (需要 DOMMatrix 支持)
const matrix = transform.toMatrix();
console.log(matrix.m11, matrix.m12, ...); 

性能哲学

Moonlight 的设计遵循 "Velocity" (极速) 哲学:

  1. Hot Path Optimization: 针对 CSS中最常见的二元运算(如 width: calc(100% - 20px))编写了专门的快速路径,绕过通用的数组分配。
  2. Singleton Cache: 对常用的 0px, 1, 0 等值使用单例或快速创建模式,减少 GC 压力。

在微基准测试中,Moonlight 在纯代数计算场景下性能可与原生实现媲美。

局限性

尽管 Moonlight 非常强大,但由于缺乏浏览器的布局引擎上下文,仍存在物理局限:

  • 相对单位解析: 无法将 em, rem, vw, % 解析为绝对像素 (px),因为这依赖于 DOM 树和布局计算。
  • 上下文无关: CSSStyleValue.parse 不知道它被用于哪个元素,因此无法处理 inherit 或基于当前字体的计算。
  • 颜色与图像: 目前主要关注数值、数学和变换。复杂的 color()image-set() 可能会回退为 CSSUnparsedValue

许可证

MIT - 献给所有追求极致的开发者。