# @markuplint/selector

> Extended W3C Selectors matcher

Latest version **5.3.0** (published 2026-10-21) · MIT license · 0 weekly downloads

## Install

```sh
npm install @markuplint/selector
pnpm add @markuplint/selector
yarn add @markuplint/selector
bun add @markuplint/selector
```

## Health

**Score 65/100 (B)** — status: active.

Positive: esm support; no vulnerabilities; has provenance; recently updated; high maintenance score.

Warnings: low downloads; no types.

## Facts

| | |
|---|---|
| Version | 5.3.0 |
| Published | 2026-10-21 |
| First published | 2022-06-26 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM |
| Node | >=24 |
| Dependencies | 6 |
| Unpacked size | 96.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 627 |
| Author | Yusuke Hirao |
| Maintainers | yusukehirao |

## Links

- npm: https://www.npmjs.com/package/@markuplint/selector
- Repository: https://github.com/markuplint/markuplint
- Homepage: https://github.com/markuplint/markuplint#readme
- Issues: https://github.com/markuplint/markuplint/issues
- npm.io page: https://npm.io/package/@markuplint/selector

## Dependencies (6)

- [debug](https://npm.io/package/debug.md) ^4.4.3
- [type-fest](https://npm.io/package/type-fest.md) ^5.10.0
- [@types/debug](https://npm.io/package/@types/debug.md) ^4.1.13
- [@markuplint/shared](https://npm.io/package/@markuplint/shared.md) 5.3.0
- [@markuplint/ml-spec](https://npm.io/package/@markuplint/ml-spec.md) 5.3.0
- [postcss-selector-parser](https://npm.io/package/postcss-selector-parser.md) ^7.1.6

## Recent versions

- 5.3.0 (latest) — 2026-10-21
- 5.0.0-rc.7 (rc) — 2026-08-31
- 5.0.0-rc.1 (next) — 2026-03-27
- 5.0.0-dev.5 (canary) — 2026-02-27
- 3.0.0-alpha.27 (dev) — 2022-12-20
- 5.2.0 — 2026-10-13
- 5.1.1 — 2026-10-09
- 5.1.0 — 2026-10-08
- 5.0.1 — 2026-09-22
- 5.0.0 — 2026-09-11
- 5.0.0-rc.6 — 2026-08-30
- 5.0.0-rc.5 — 2026-08-29
- 4.18.1 — 2026-04-24
- 4.18.0 — 2026-04-22
- 5.0.0-rc.4 — 2026-04-19
- … 114 more at https://npm.io/package/@markuplint/selector/versions

## README

# @markuplint/selector

[![npm version](https://badge.fury.io/js/%40markuplint%2Fselector.svg)](https://www.npmjs.com/package/@markuplint/selector)

**Extended [W3C Selectors](https://www.w3.org/TR/selectors-4/) matcher**

Supported selectors and operators:

| Selector Type                                    | Code Example                                                                              | Support |
| ------------------------------------------------ | ----------------------------------------------------------------------------------------- | ------- |
| Universal selector                               | `*`                                                                                       | ✅      |
| Type selector                                    | `div`                                                                                     | ✅      |
| ID selector                                      | `#id`                                                                                     | ✅      |
| Class selector                                   | `.class`                                                                                  | ✅      |
| Attribute selector                               | `[data-attr]`                                                                             | ✅      |
| Attribute selector, Exact match                  | `[data-attr=value]` `[data-attr=value i]`                                                 | ✅      |
| Attribute selector, Include whitespace separated | `[data-attr~=value]` `[data-attr~=value i]`                                               | ✅      |
| Attribute selector, Subcode match                | <code>[data-attr\|=value]</code> <code>[data-attr\|=value i]</code>                       | ✅      |
| Attribute selector, Partial match                | `[data-attr*=value]` `[data-attr*=value i]`                                               | ✅      |
| Attribute selector, Forward match                | `[data-attr^=value]` `[data-attr^=value i]`                                               | ✅      |
| Attribute selector, Backward match               | `[data-attr$=value]` `[data-attr$=value i]`                                               | ✅      |
| Negation pseudo-class                            | `:not(div)`                                                                               | ✅      |
| Matches-Any pseudo-class                         | `:is(div)`                                                                                | ✅      |
| Specificity-adjustment pseudo-class              | `:where(div)`                                                                             | ✅      |
| Relational pseudo-class                          | `:has(div)` `:has(> div)` `:has(+ div)` `:has(~ div)`                                     | ✅      |
| Directionality pseudo-class                      | `:dir(ltr)`                                                                               | ❌      |
| Language pseudo-class                            | `:lang(en)`                                                                               | ❌      |
| Hyperlink pseudo-class                           | `:any-link`                                                                               | ❌      |
| Link History pseudo-class                        | `:link` `:visited`                                                                        | ❌      |
| Local link pseudo-class                          | `:local-link`                                                                             | ❌      |
| Target pseudo-class                              | `:target`                                                                                 | ❌      |
| Target container pseudo-class                    | `:target-within`                                                                          | ❌      |
| Reference element pseudo-class                   | `:scope`                                                                                  | ✅      |
| Current-element pseudo-class                     | `:current` `:current(div)`                                                                | ❌      |
| Past pseudo-class                                | `:past`                                                                                   | ❌      |
| Future pseudo-class                              | `:future`                                                                                 | ❌      |
| Interactive pseudo-class                         | `:active` `:hover` `:focus` `:focus-within` `:focus-visible`                              | ❌      |
| Enable and disable pseudo-class                  | `:enable` `:disable`                                                                      | ❌      |
| Mutability pseudo-class                          | `:read-write` `:read-only`                                                                | ❌      |
| Placeholder-shown pseudo-class                   | `:placeholder-shown`                                                                      | ❌      |
| Default-option pseudo-class                      | `:default`                                                                                | ❌      |
| Selected-option pseudo-class                     | `:checked`                                                                                | ❌      |
| Indeterminate value pseudo-class                 | `:indeterminate`                                                                          | ❌      |
| Validity pseudo-class                            | `:valid` `:invalid`                                                                       | ❌      |
| Range pseudo-class                               | `:in-range` `:out-of-range`                                                               | ❌      |
| Optionality pseudo-class                         | `:required` `:optional`                                                                   | ❌      |
| Empty-Value pseudo-class                         | `:blank`                                                                                  | ❌      |
| User-interaction pseudo-class                    | `:user-invalid`                                                                           | ❌      |
| Root pseudo-class                                | `:root`                                                                                   | ✅      |
| Empty pseudo-class                               | `:empty`                                                                                  | ❌      |
| Nth-child pseudo-class                           | `:nth-child(2)` `:nth-last-child(2)` `:first-child` `:last-child` `:only-child`           | ❌      |
| Nth-child pseudo-class (`of El` Syntax)          | `:nth-child(2 of div)` `:nth-last-child(2 of div)`                                        | ❌      |
| Nth-of-type pseudo-class                         | `:nth-of-type(2)` `:nth-last-of-type(2)` `:first-of-type` `:last-of-type` `:only-of-type` | ❌      |
| Nth-col pseudo-class                             | `:nth-col(2)` `:nth-last-col(2)`                                                          | ❌      |
| Pseudo elements                                  | `::before` `::after`                                                                      | ❌      |
| Descendant combinator                            | `div span`                                                                                | ✅      |
| Child combinator                                 | `div > span` (`:has(> span)`)                                                             | ✅      |
| Next-sibling combinator                          | `div + span` (`:has(+ span)`)                                                             | ✅      |
| Subsequent-sibling combinator                    | `div ~ span` (`:has(~ span)`)                                                             | ✅      |
| Column combinator                                | <code>div \|\| span</code>                                                                | ❌      |
| Multiple selectors                               | `div, span`                                                                               | ✅      |

## Case sensitivity

Per HTML LS / Selectors Level 4 — Case sensitivity, names are matched
according to the element's namespace:

| Match target    | HTML namespace                                                                                            | SVG / MathML / custom elements                  |
| --------------- | --------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| Tag name        | ASCII case-insensitive (`DIV` matches `div`)                                                              | Case-sensitive                                  |
| Attribute name  | ASCII case-insensitive (`[CHARSET]` matches `<meta CHARSET>` and `<meta charset>`)                        | Case-sensitive (e.g. SVG `viewBox` ≠ `viewbox`) |
| Attribute value | Case-sensitive by default; use the `i` flag (e.g. `[lang="en" i]`) for case-insensitive value comparisons | Same                                            |

The `i` flag scopes to attribute **values** only — it does not affect
attribute name matching, which is governed by the namespace rules above.

## Extended Selector

The below is selectors that are extended by markuplint:

| Selector Type              | Code Example          |
| -------------------------- | --------------------- |
| ARIA pseudo-class          | `:aria(has name)`     |
| ARIA Role pseudo-class     | `:role(heading)`      |
| Content Model pseudo-class | `:model(interactive)` |

### ARIA pseudo-class

```
:aria(syntax)
```

| Syntax        | Example              | Description                                    |
| ------------- | -------------------- | ---------------------------------------------- |
| `has name`    | `:aria(has name)`    | Matches the element has accessible name        |
| `has no name` | `:aria(has no name)` | Matches the element has **no** accessible name |

### ARIA Role pseudo-class

```
:role(roleName)
:role(roleName|version)
```

For example, `:role(button)` matches `<button>` and `<div role="button">`.

You can specify the version of WAI-ARIA by separating the pipe like `:role(form|1.1)`.

### Content Model pseudo-class

```
:model(interactive)
:model(palpable)
```

For example, `:model(interactive)` matches `<a>`(with `href` attr), `<button>`, and so on.

A category that lists custom elements in the HTML Standard, such as `flow`, `phrasing` and `palpable`, also matches custom elements (`<x-foo>`) and components (`<Foo />`). An element that a component pretends to be is judged by the name it pretends to be: it matches only when that name contains a hyphen.

## Regex Selector

```json
{
  "nodeName": "/^[a-z]+$/",
  "attrName": "/^[a-z]+$/",
  "attrValue": "/^[a-z]+$/"
}
```

## Install

[`markuplint`](https://www.npmjs.com/package/markuplint) package includes this package.

<details>
<summary>If you are installing purposely, how below:</summary>

```shell
$ npm install @markuplint/selector

$ yarn add @markuplint/selector
```

</details>

---
_Source: https://npm.io/package/@markuplint/selector · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
