CSS.escape
A lightweight, spec-compliant polyfill for the CSS.escape() method defined in CSSOM, for safely escaping CSS identifiers.
Repository Health
Technical Analysis
css.escape is a minimal, dependency-free polyfill implementing the CSS.escape() static method exactly as specified in the CSSOM draft. It takes an arbitrary string — typically an element ID, class name, or other CSS identifier — and returns a version safely escaped for use in CSS selectors and stylesheets, handling null bytes, control characters, leading digits, and non-ASCII characters according to the specification’s exact escaping rules.
Written by Mathias Bynens, the library ships as a single UMD-wrapped file that works as a browser global, a CommonJS module in Node.js, or an AMD module, and automatically defers to a native CSS.escape implementation when the runtime already provides one.
What You Get
- Spec-accurate escaping - Implements every rule from the CSSOM “serialize an identifier” algorithm, including null-byte replacement, control-character escaping, and leading-digit/hyphen handling.
- Zero runtime dependencies - A single small file with no external packages required at runtime.
- Universal module support - UMD wrapper works as a browser global, CommonJS module, or AMD module without configuration.
- Automatic native passthrough - Detects an existing
CSS.escapeon the global object and defers to it instead of double-polyfilling.
Common Use Cases
- Building dynamic CSS selectors - Safely escape user-generated element IDs or class names before using them in
querySelectoror stylesheet rules. - Polyfilling older browsers - Add
CSS.escapesupport to environments that predate the CSSOM specification’s adoption. - Library internals - Used internally by DOM utility libraries and frameworks that need to construct safe CSS selectors from arbitrary strings.
- Server-side rendering - Escape identifiers in Node.js code that generates CSS or HTML with embedded selectors.
Under The Hood
Architecture css.escape has no internal layering — it is a single UMD-wrapped file (css.escape.js) exposing one function, cssEscape, assigned to a global CSS.escape when the environment lacks a native implementation. The module wrapper at the top of the file handles CommonJS (module.exports), AMD (define), and plain browser-global registration in a single conditional block, and the escaping logic itself is a straightforward character-by-character loop over the input string’s code units with early-return branches for edge cases (a lone leading hyphen, or a hyphen followed by a digit). There is no dependency injection and no data flow beyond the function’s own input/output — changing the core algorithm would only ever affect this one function, since nothing else in the codebase depends on its internals.
Tech Stack
The library has zero runtime dependencies and targets plain ES5 JavaScript for maximum compatibility with old browsers and Node.js. Its only devDependencies (declared in package.json) are istanbul for code coverage and coveralls for reporting it to Coveralls; tests run via node tests/tests.js against Node’s built-in assert module, with no external test framework such as Mocha or Jest. CI is configured through a legacy .travis.yml running the npm test script. There is no build step, bundler, or transpiler — the single css.escape.js file is published to npm as-is and consumed directly via require() or a script tag.
Code Quality Test coverage in tests/tests.js is thorough for the surface area involved, exercising null bytes, replacement characters, control characters, leading digits, a lone leading hyphen, non-string inputs (undefined, true, false, null), and the zero-argument TypeError case — all asserted with Node’s plain assert module rather than a fluent assertion library. There are no TypeScript types, no linter configuration found in the repo, and no code-style enforcement beyond consistent manual formatting; naming is minimal but clear (cssEscape, codeUnit, firstCodeUnit) and closely mirrors the terminology used in the CSSOM specification it implements. Error handling is limited to the single explicit TypeError thrown for a missing argument, matching the spec’s requirement.
API Design The public API is a single static method, CSS.escape(value), matching the native browser API of the same name exactly in signature and behavior — there is no configuration, no options object, and no alternate entry points, so integrating the polyfill requires nothing beyond a require() call or a script include. Because it shadows or extends the native CSS.escape rather than introducing a differently-named function, code written against the polyfill needs no changes when a browser later ships native support, which is close to the ideal developer experience for a polyfill. Documentation is limited to the README’s installation and require() snippets, since the API surface is a single one-argument function with well-known semantics that need little further explanation.
Used by 5 apps in this directory
Enso
Analytics · Data Engineering · Low Code Platforms
A visual and textual programming platform for data prep and analysis where the node graph and the underlying Enso code are always perfectly in sync, built by an Alteryx co-founder on a GraalVM engine.
Plasmic
CMS · Low Code Platforms · No Code Platforms
The open-source visual builder that lets teams design React apps and websites with drag-and-drop while integrating seamlessly with your codebase.
swagger-ui
Developer Tools
Transform OpenAPI specifications into interactive, browser-based API documentation that developers and consumers can explore and test live.
Webstudio
Design Tools · No Code Platforms
Open source visual development platform with complete CSS control, headless CMS integration, and full infrastructure ownership
Zulip
Team Chat
Topic-based team chat that brings the structure of email threads to real-time messaging, so distributed teams never lose context across hundreds of concurrent conversations.