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

postcss-nth-nested

v2.0.2

Published

PostCSS plugin for :nth-nested(n) descendent depth selector to select elements by their depth in the DOM

Readme

postcss-nth-nested

PostCSS plugin for selecting elements by how deeply they are nested in matching ancestor elements.

It adds a custom :nth-nested(...) selector and rewrites it to standard CSS using :where(...), :not(...), and :is(...).

/* Input */
li:nth-nested(2) > .text {
  background-color: lime;
}

/* Output */
li:where(li li:not(li li li)) > .text {
  background-color: lime;
}

Try the Demo.

Or tinker with the demo on CodePen.

When to use it

Use this when your markup contains recursive or repeated nested structures, such as menus, trees, comments, or nested lists, and you want CSS for an exact depth or repeating depth pattern.

For example, li:nth-nested(2) matches the second-level li here:

<ul>
  <li>
    Depth 1
    <ul>
      <li>
        Depth 2
        <ul>
          <li>Depth 3</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

Depth is 1-indexed:

  • :nth-nested(1) matches elements that are not nested inside another matching element.
  • :nth-nested(2) matches elements nested inside one matching ancestor.
  • :nth-nested(3) matches elements nested inside two matching ancestors.

This is not CSS nesting, and it is not the same as :nth-child(...). It is about matching ancestor depth.

Install

Install the plugin alongside PostCSS:

npm install --save-dev postcss postcss-nth-nested

Or with another package manager:

pnpm add -D postcss postcss-nth-nested
yarn add -D postcss postcss-nth-nested

Configure PostCSS

Add the plugin to your PostCSS config.

CommonJS:

// postcss.config.js
module.exports = {
  plugins: [
    require('postcss-nth-nested')
  ]
};

ES modules:

// postcss.config.mjs
import nthNested from 'postcss-nth-nested';

export default {
  plugins: [
    nthNested()
  ]
};

If your build tool uses a postcss field in package.json, use:

{
  "postcss": {
    "plugins": {
      "postcss-nth-nested": {}
    }
  }
}

Options

maxDepth

Type: number

Default: 20

Sets the highest nesting depth the plugin will generate selectors for. Values must be positive integers; invalid values fall back to the default.

// postcss.config.js
module.exports = {
  plugins: [
    require('postcss-nth-nested')({ maxDepth: 75 })
  ]
};
// postcss.config.mjs
import nthNested from 'postcss-nth-nested';

export default {
  plugins: [
    nthNested({ maxDepth: 75 })
  ]
};

Examples

Select only the top-level list item:

li:nth-nested(1) {
  font-weight: bold;
}

Generated CSS:

li:where(:not(li li)) {
  font-weight: bold;
}

Select exactly second-level list item text:

li:nth-nested(2) > .text {
  background-color: lime;
}

Generated CSS:

li:where(li li:not(li li li)) > .text {
  background-color: lime;
}

Select .item elements at the third .item nesting level:

.item:nth-nested(3) {
  color: rebeccapurple;
}

Generated CSS:

.item:where(.item .item .item:not(.item .item .item .item)) {
  color: rebeccapurple;
}

Select the first three list item nesting levels using An+B syntax:

li:nth-nested(-n+3) > .text {
  color: rebeccapurple;
}

Generated CSS:

li:where(:not(li li li li)) > .text {
  color: rebeccapurple;
}

Use a container selector:

.menu li:nth-nested(2) {
  padding-left: 2rem;
}

Generated CSS:

.menu li:where(.menu li li:not(.menu li li li)) {
  padding-left: 2rem;
}

Supported syntax

The plugin transforms :nth-nested(...) values that match one or more nesting depths from 1 to 20 by default.

Supported values follow :nth-child(...)-style An+B syntax:

  • integers from 1 to 20, such as 1, 2, or 20
  • odd and even
  • An+B formulas, such as 2n+1, 3n, n+3, -n+3, or -2n+5

Depth is capped at 20 by default. A formula that only matches depths outside the configured range is left unchanged.

Contiguous first-depth formulas such as -n+3 are optimized to a single upper-bound selector instead of being expanded into every exact depth.

Invalid or unsupported forms are left unchanged:

li:nth-nested(0) {}
li:nth-nested(21) {}
li:nth-nested(n+21) {}
li:nth-nested(a) {}
li:nth-nested(1.5) {}

The selector before :nth-nested(...) is reused as the repeated nesting selector. If no selector is provided, * is used:

:nth-nested(2) {}

becomes:

:where(* *:not(* * *)) {}

Selector size warning

Broad An+B formulas can generate very large selectors because the plugin expands every matching depth up to the configured maxDepth. Contiguous first-depth formulas such as -n+3 are optimized, but formulas like :nth-nested(odd) still expand to every odd depth up to maxDepth. Prefer exact depths or narrow finite formulas when possible, and check the generated CSS size before using broad formulas in production.

Browser support

The generated CSS relies on :where(...), :not(...), and, for An+B formulas that match multiple depths, :is(...). Depth guards are kept inside :where(...) so generated ancestry checks do not add specificity. Check that your target browsers support those selectors before using the plugin in production.

Notes

This plugin runs at build time. Browsers do not understand :nth-nested(...) directly; your CSS must be processed by PostCSS before it is served.