parsel

A tiny, permissive CSS selector parser

Specificity: parsel.specificity(selector);

Tokens parsel.tokenize(selector);

AST parsel.parse(selector);

Usage

Parsel is an ES module. You import it like so:

import * as parsel from "https://projects.verou.me/parsel/parsel.js"

Note that to use that your script needs to use type="module" or be imported from a script that does. If you can't or don't want to use ES modules you can use parsel_nomodule.js in a regular <script> tag:


		<script src="https://projects.verou.me/parsel/parsel_nomodule.js"></script>
	

After that, you can use parsel as a global.

Fun fact: You could also use the module version of Parsel and convert it to a global this way:


		<script type="module">
			import * as parsel from "https://projects.verou.me/parsel/parsel.js";
			window.parsel = parsel;
		</script>
	

Then, assuming your code runs after the DOMContentLoaded event, you can use the global normally. In fact, we are assigning parsel to a global in this very page this way, so you can open your console and play with it!

You can also intall via npm: npm install parsel-js

API

Get list of tokens as a flat array:

parsel.tokenize(selector)

Get AST:

parsel.parse(selector)

You can also provide options:

parsel.parse(selector, {recursive: false, list: false})

The recursive option parses the arguments of pseudo-classes whose argument is a selector like :not(), :is(), :where() etc into a subtree property. The list option parses selector lists (A, B, C). The only reason to turn it off is as a performance optimization when you are processing a large volume of selectors that are not lists (e.g. the output of certain CSS parsers like Rework)

Traverse all tokens of a (sub)tree:

parsel.walk(node, callback)

callback is called with each node as the only argument.

Calculate specificity (returns an array of 3 numbers):

parsel.specificity(selectorOrNode)

To convert the specificity array to a number, you can use parsel.specificityToNumber(specificity [, base]). If a base is not provided, it will be the max specificity component + 1.

Try it out! In this page, parsel is assigned to a global so you can experiment with the API in the console!