Skip to Content
  • Website
Codsen
  • Home
  • Open Source
  • Articles
  • About

prevOpen Source→string-extract-class-namesnext

string-extract-class-names8.3.0

Extracts class and ID names from isolated CSS selector fragments

Downloads per monthChangelogMIT Licenselibera manifesto
  • the top
  • Installation
  • Quick Take
  • Examples
  • API — EXTRACT()
  • API — READCSSSELEC…
  • API — DECODECSSSEL…
  • API — VERSION
  • API — TYPES
  • THE USE
  • BRACKET NOTA…
  • Changelog

Permalink to InstallationInstallation

Permalink to Quick TakeQuick Take

Permalink to ExamplesExamples

  • Extract selectors from HTML-style attribute selectors
  • Non-parsing algorithm can tackle really dodgy CSS
  • Decode CSS selector escapes
  • Extract raw escaped selectors
  • Isolate a selector prelude before extraction
  • Read one selector token at an exact index
  • Inspect the source ranges of extracted selectors
  • Processes whole CSS selectors

API — extract()

The main function extract() is imported like this:

It’s a function which takes one input argument:

Input argumentTypeObligatoryDescription
str
Type: String
Obligatory: yes
strStringyesAn isolated selector prelude or already-tokenized selector fragment

The function will return a plain object (a Result type above):

Key in a returned objectTypeDescription
res
Type: Array of strings
resArray of stringsRaw class and ID selector spellings
ranges
Type: Array of ranges or null (compatible with Ranges)
rangesArray of ranges or null (compatible with Ranges)Locations of extracted strings

Accepted input

extract() is a context-free scanner. Pass an isolated CSS selector prelude or an already-tokenized selector fragment, not a complete stylesheet or HTML document.

The function does not recognise declarations, comments, strings outside attribute values, URLs, or HTML character references as outer syntax. If those constructs are included in the input, their dots and hashes can be returned as apparent selectors. For example, a colour such as #fff, a URL fragment such as #icon, or a quoted string such as ".example" can all look like selector tokens to a context-free scan.

Let a CSS parser isolate the selector prelude before calling extract(). The slice below is only a short illustration for a single flat rule:

import { extract } from "string-extract-class-names";

const rule =
  '.real { color: #fff; background: url("/icon.svg#mark"); content: ".not-a-selector"; }';
const selectorPrelude = rule.slice(0, rule.indexOf("{"));

console.log(extract(selectorPrelude).res);
// => [".real"]

HTML character-reference decoding belongs to the HTML parsing layer. Decode references there before constructing selector input; extract() does not turn a literal spelling such as © into a character. CSS escapes are a separate CSS feature: extract() preserves their raw spelling, and decodeCssSelector() below decodes one extracted selector when needed.

API — readCssSelectorToken()

The function readCssSelectorToken() is imported like this:

Reads a single class or ID selector starting at an exact index. Use it when you’re already walking a string and know where a . or # sits — extract() scans a whole string, while this function reads one token:

Input argumentTypeObligatoryDescription
str
Type: String
Obligatory: yes
strStringyesA string to read from.
start
Type: Natural number or zero
Obligatory: yes
startNatural number or zeroyesIndex of the leading . or #.

It returns a plain object (a CssSelectorToken type), or null if start doesn’t point at a . or #:

KeyTypeDescription
value
Type: String
valueStringThe selector with any CSS escapes decoded.
raw
Type: String
rawStringThe selector exactly as it appears in the source.
range
Type: Array of two numbers
rangeArray of two numbersWhere the token starts and ends in str.
import { readCssSelectorToken } from "string-extract-class-names";

console.log(readCssSelectorToken(".a-b .c", 0));
// => { value: ".a-b", raw: ".a-b", range: [0, 4] }

console.log(readCssSelectorToken(".a-b .c", 2));
// => null

API — decodeCssSelector()

The function decodeCssSelector() is imported like this:

Decodes the CSS escapes in one already-extracted class or ID selector, keeping its leading dot or hash:

Utility-first CSS frameworks lean on escapes heavily — .md\:w-1\/2 is one class name, not three tokens. This function turns the source form into the class name a browser sees:

import { decodeCssSelector } from "string-extract-class-names";

console.log(decodeCssSelector(".a\\:b"));
// => ".a:b"

console.log(decodeCssSelector(".plain"));
// => ".plain"

It’s what readCssSelectorToken() uses to fill the value key.

API — version

You can import version:

API — types

This package is written in TypeScript and exports the following types:

TypeDescription
Result
Type: Result
ResultWhat extract() returns — res and ranges.
CssSelectorToken
Type: CssSelectorToken
CssSelectorTokenWhat readCssSelectorToken() returns — value, raw and range.
import type { CssSelectorToken, Result } from "string-extract-class-names";

The use

The email-comb library uses string-extract-class-names after it has isolated selector heads from a stylesheet. It then compares those extracted class and ID names with the email’s HTML while detecting and deleting unused CSS styles.

Bracket notation

Normally, class and ID selectors in CSS include dots or hashes, for example, div.first-class.second-class. The ranges include those dots and hashes:

import { extract } from "string-extract-class-names";
const res = extract("div.first-class.second-class");
console.log(res);
// => {
//      res: [".first-class", ".second-class"],
//      ranges: [
//        [3, 15],
//        [15, 28],
//      ],
//    }

Dots above are at indexes 3 and 15.

The function also supports the exact [class=value], whitespace-list [class~=value], and exact [id=value] attribute-selector forms. Attribute names are ASCII-case-insensitive. Values can use CSS identifier or string syntax, and an exact class string can contain multiple HTML class tokens. Partial-match operators such as ^=, $=, and *= do not produce selectors.

For example, instead of td.croodles, CSS can use td[class="croodles"]. This notation was historically useful in email templates because of Yahoo rendering behaviouropens in a new tab:

import { extract } from "string-extract-class-names";
const str = `td[id=" abc-def "]`;
const res = extract(str);
console.log(res);
// => {
//      res: ["#abc-def"],
//      ranges: [[8, 15]],
//    }

// However:

console.log(str.slice(8, 15));
// => "abc-def"
// There is no hash in the source slice because the attribute value did not
// contain one. The hash in `res` is synthetic.

For dot and hash selectors that appear literally in the source, res matches the corresponding String.prototype.slice() calls:

assert.deepEqual(
  res,
  ranges.map(([from, to]) => str.slice(from, to)),
);

Permalink to changelogChangelog

Open Changelog
↑ back to top
prev next

Copyright

All rights reserved © Roy Revelt 2026
All our open source packages are under MIT licenceopens in a new tab

Activities

🐛 See a bug? Raise an issueopens in a new tab
💘 Check out the Indiewebopens in a new tab and Libera manifestoopens in a new tab