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 🙏

© 2024 – Pkg Stats / Ryan Hefner

list-selectors

v2.0.1

Published

List the selectors used in your CSS. Use as a standalone function, CLI, or PostCSS plugin.

Downloads

1,383

Readme

list-selectors Build Status

What do you want in life? Is it to generate a nicely organized list of all the selectors used in your CSS, showing

  • all the unique selectors used anywhere, in alphabetical order;
  • all the unique simple selectors extracted from those sequences, in alphabetical order;
  • those unique simple selectors broken out into id, class, attribute, and type selector categories (also alphabetical)?

Yes, that is probably what you want. And your dreams have been realized: this plugin does those things!

It can be used as a standalone Node function, a CLI, or a PostCSS plugin — so it's bound to fit into your workflow.

v0.2.0+ should be used as a PostCSS plugin only with PostCSS v4.1.0+.

Installation

npm install list-selectors

Version 2+ is compatible with PostCSS 5. (Earlier versions are compatible with PostCSS 4.)

What it Does

While PostCSS parses the input stylesheet(s), list-selectors aggregates a list of all the selectors used. Then it alphabetizes them, extracts the simple selectors, sorts and categorizes those, and spits out an object — with which you can do what you will (some ideas below).

Here's an example input-output, explaining each part of the output object:

/* INPUT */
.fulvous { color: blue; }
#orotund { color: red; }
.Luddite { color: green; }
ul > li { color: pink; }
a[data-biscuit="dunderfunk"] { color: pink; }
div#antipattern:nth-child(3).horsehair [id="ding"] { color: yellow; }
// OUTPUT

// All the lists are *in alphabetical order* with *unique values* only.
//
// The ordering ignores initial characaters that distinguish selectors.
// It also ignores capitalization. So you'd get
// `['#goo', '.faz', '.Freedom', '[href="..."]']` in that order.
{
  selectors: [
    // The selectors used in the input CSS.
    'a[data-biscuit="dunderfunk"]',
    'div#antipattern:nth-child(3).horsehair [id="ding"]',
    '.fulvous',
    '.Luddite',
    '#orotund',
    'ul > li'
  ],
  simpleSelectors: {
    all: [
      // The *simple* selectors used in the input CSS.
      // These have been extracted from the
      // selectors and stripped of pseudo-classes and pseudo-selectors.
      //
      // This list will include the universal selector, `*`, if you use it.
      'a',
      '#antipattern',
      '[data-biscuit="dunderfunk"]',
      'div',
      '.fulvous',
      '.horsehair',
      '[id="ding"]',
      'li',
      '.Luddite',
      '#orotund',
      'ul'
    ],
    attributes: [
      // The attribute selectors used.
      '[data-biscuit="dunderfunk"]',
      '[id="ding"]'
    ],
    classes: [
      // The class selectors used.
      '.fulvous',
      '.horsehair',
      '.Luddite'
    ],
    ids: [
      // The id selectors used.
      '#antipattern',
      '#orotund'
    ],
    types: [
      // The type selectors used.
      'a',
      'div',
      'li',
      'ul'
    ]
  }
}

Why?

Short answer: code review and analysis.

We all have our own reasons for wanting the review/analysis tools that we want. But if you need a prompt, here are some situations in which you might find list-selectors useful:

  • You want an overview of what's going on in some CSS. A nice organized list of all the selectors in play would no doubt help.
  • In CSS code-reviews, you want to ensure that selectors adhere to some established conventions (e.g. SUIT or BEM format, no ids, prefixed classes, whatever else). With this list, you can easily scan through all the selectors and assess conformance.
  • You want a quick look at how Person-or-Company X that you admire writes CSS selectors, names classes, etc. So feed their CSS (even minified) into one end of the tube, and get a selector list out the other end.
  • You want to write a script that compares the selectors your team has actually used against a list of selectors that you are allowing yourself. This plugin will give you the "actual" (which you could compare with the "expected").

And so on.

Usage

listSelectors(source[, options], callback)

Use it as a standalone Node function. Feed it globs of files or a URL, (optional) options, and a callback that will receive the selector list object.

  • {string|string[]} source - Can be a single file glob, or an array of file globs that work together, or the URL of a remote CSS file. URLs are identified by an opening http, so don't forget that. The array of file globs is made possible by multimatch; if you'd like more details about usage and expected matches, have a look at the multimatch tests.
  • {object} [options] - Optional options: see Options.
  • {function} callback - A callback function that will receive the generated list as an argument. If no selectors are found, it will receive an empty object.

Example

var listSelectors = require('list-selectors');

listSelectors(
  ['style/**/*.css', '!style/normalize.css'], // source
  { include: ['ids', 'classes'] }, // options
  function(myList) { // callback
    console.log(myList);
    // ... do other things with your nice selector list
  }
);

As a CLI

As with the standalone function, you feed it globs of files and options. You can pass an array of globs to make multimatch patterns (however, if you use ! or other special characters in your file globs, make sure that you wrap the glob in quotation marks or else your terminal will be flummoxed — see the last example below); and you can pass a URL to a remote CSS file.

The output is converted to a string with JSON.stringify() and written to stdout. You can read it in your terminal or pipe it to a file or another process.

Flags

  • -p or --pretty: This will add line breaks and tabs to make the JSON more legible, if your goal is to read it with human eyes.
  • -i or --include: See Options.

Example


list-selectors foo.css
# {"all":[".horse","#donkey","[data-type='mule']"],"simpleSelectors":{"all":["[data-type='mule']","#donkey",".horse"],"ids":["#donkey"],"classes":[".horse"],"attributes":["[data-type='mule']"],"types":[]}}

list-selectors foo.css -p -i classes
# {
#     "classes": [
#         ".horse"
#     ]
# }

# Remote URL
list-selectors https://www.npmjs.com/static/css/index.css

# Using a `!`: notice the quotation marks
list-selectors "style/**/*.css" "!style/normalize.css"

As PostCSS Plugin

Consume it as a PostCSS plugin, in accordance with your chosen method of consuming PostCSS plugins.

Just use the plugin method:

var listSelectorPlugin = require('list-selectors').plugin;

Pass it (optional) options and a callback that will receive the output object. Then have your way with it.

Examples

With Gulp and gulp-postcss, you can just string it in there with your other plugins.

var gulp = require('gulp');
var gulpPostcss = require('gulp-postcss');
var listSelectorsPlugin = require('listSelectors').plugin;
var customProperties = require('postcss-custom-properties');

gulp.task('analyzeCss', function() {
  return gulp.src(['style/**/*.css', '!style/normalize.css'])
    .pipe(postcss([
      customProperties(),
      listSelectorsPlugin(doSomethingWithList)
    ]))
    .pipe(gulp.dest('./dest'));
});

function doSomethingWithList(mySelectorList) {
  console.log(mySelectorList);
  // ... do other things
}

Straight PostCSS:

var postcss = require('postcss');
var listSelectorsPlugin = require('listSelectors').plugin;

var mySelectorList;
var css = fs.readFileSync('foo.css', 'utf8');
var listOpts = { include: 'ids' };
postcss(listSelectorsPlugin(listOpts, function(list) { mySelectorList = list; }))
  .process(css)
  .then(function() {
    console.log(mySelectorList);
    // ... do other things with result
  });

Options

include {string|string[]}

Only include a subset of lists in the output.

Possible values are:

  • 'selectors': Only the complete list of full selectors.
  • 'simpleSelectors': Only the complete list of simple selectors.
  • 'simple': Same as 'simpleSelectors'.
  • 'attributes': Only attributes.
  • 'classes': Only classes.
  • 'ids': Only ids.
  • 'types': Only types.