List the selectors used in your CSS. Use as a standalone function, CLI, or PostCSS plugin.
MIT License
What do you want in life? Is it to generate a nicely organized list of all the selectors used in your CSS, showing
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+.
npm install list-selectors
Version 2+ is compatible with PostCSS 5. (Earlier versions are compatible with PostCSS 4.)
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'
]
}
}
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:
And so on.
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.
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.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 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.
-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.
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"
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.
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
});
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.