You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

readme.md 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. # Specificity Calculator
  2. A JavaScript module for calculating and comparing the [specificity of CSS selectors](https://www.w3.org/TR/selectors-3/#specificity). The module is used on the [Specificity Calculator](https://specificity.keegan.st/) website.
  3. Specificity Calculator is built for CSS Selectors Level 3. Specificity Calculator isn’t a CSS validator. If you enter invalid selectors it will return incorrect results. For example, the [negation pseudo-class](https://www.w3.org/TR/selectors-3/#negation) may only take a simple selector as an argument. Using a psuedo-element or combinator as an argument for `:not()` is invalid CSS so Specificity Calculator will return incorrect results.
  4. ## Supported runtime environments
  5. The module is provided in two formats: an ECMAScript (ES) module in `dist/specificity.mjs`, and a Universal Module Definition (UMD) in `dist/specificity.js`. This enables support for the following runtime environments:
  6. **Browser**
  7. * Directly loaded ES module
  8. * ES module in a precompiled script (using a bundler like Webpack or Rollup)
  9. * Global variable
  10. **Node.js**
  11. * ES module
  12. * CommonJS module
  13. ### Browser usage as a directly loaded ES module
  14. ```html
  15. <script type="module">
  16. import { calculate } from './specificity/dist/specificity.mjs';
  17. calculate('ul#nav li.active a');
  18. </script>
  19. ```
  20. ### Browser usage as an ES module in a precompiled script
  21. Bundlers like [Webpack and Rollup](https://github.com/rollup/rollup/wiki/pkg.module) import from the `module` field in `package.json`, which is set to the ES module artefact, `dist/specificity.mjs`.
  22. ```js
  23. import { calculate } from 'specificity';
  24. calculate('ul#nav li.active a');
  25. ```
  26. ### Browser usage as a global variable
  27. The UMD artefact, `dist/specificity.js`, sets a global variable, `SPECIFICITY`.
  28. ```html
  29. <script src="./specificity/dist/specificity.js"></script>
  30. <script>
  31. SPECIFICITY.calculate('ul#nav li.active a');
  32. </script>
  33. ```
  34. ### Node.js usage as an ES module
  35. The `main` field in `package.json` has an extensionless value, `dist/specificity`. This allows Node.js to use either the ES module, in `dist/specificity.mjs`, or the CommonJS module, in `dist/specificity.js`.
  36. When Node.js is run with the `--experimental-modules` [flag](https://nodejs.org/api/esm.html) or an [ES module loader](https://www.npmjs.com/package/esm), it will use the ES module artefact.
  37. ```js
  38. import { calculate } from 'specificity';
  39. calculate('ul#nav li.active a');
  40. ```
  41. ### Node.js usage as a CommonJS module
  42. Otherwise, Node.js will use the UMD artefact, which contains a CommonJS module definition.
  43. ```js
  44. const { calculate } = require('specificity');
  45. calculate('ul#nav li.active a');
  46. ```
  47. ## Calculate function
  48. The `calculate` function returns an array containing a result object for each selector input. Each result object has the following properties:
  49. * `selector`: the input
  50. * `specificity`: the result as a string e.g. `0,1,0,0`
  51. * `specificityArray`: the result as an array of numbers e.g. `[0, 1, 0, 0]`
  52. * `parts`: array with details about each part of the selector that counts towards the specificity
  53. ## Example
  54. ```js
  55. calculate('ul#nav li.active a');
  56. /*
  57. [
  58. {
  59. selector: 'ul#nav li.active a',
  60. specificity: '0,1,1,3',
  61. specificityArray: [0, 1, 1, 3],
  62. parts: [
  63. { selector: 'ul', type: 'c', index: 0, length: 2 },
  64. { selector: '#nav', type: 'a', index: 2, length: 4 },
  65. { selector: 'li', type: 'c', index: 5, length: 2 },
  66. { selector: '.active', type: 'b', index: 8, length: 7 },
  67. { selector: 'a', type: 'c', index: 13, length: 1 }
  68. ]
  69. }
  70. ]
  71. */
  72. ```
  73. You can use comma separation to pass in multiple selectors:
  74. ```js
  75. calculate('ul#nav li.active a, body.ie7 .col_3 h2 ~ h2');
  76. /*
  77. [
  78. {
  79. selector: 'ul#nav li.active a',
  80. specificity: '0,1,1,3',
  81. ...
  82. },
  83. {
  84. selector: 'body.ie7 .col_3 h2 ~ h2',
  85. specificity: '0,0,2,3',
  86. ...
  87. }
  88. ]
  89. */
  90. ```
  91. ## Comparing two selectors
  92. Specificity Calculator also exports a `compare` function. This function accepts two CSS selectors or specificity arrays, `a` and `b`.
  93. * It returns `-1` if `a` has a lower specificity than `b`
  94. * It returns `1` if `a` has a higher specificity than `b`
  95. * It returns `0` if `a` has the same specificity than `b`
  96. ```js
  97. compare('div', '.active'); // -1
  98. compare('#main', 'div'); // 1
  99. compare('span', 'div'); // 0
  100. compare('span', [0, 0, 0, 1]); // 0
  101. compare('#main > div', [0, 1, 0, 1]); // 0
  102. ```
  103. ## Ordering an array of selectors by specificity
  104. You can pass the `compare` function to `Array.prototype.sort` to sort an array of CSS selectors by specificity.
  105. ```js
  106. import { compare } from 'specificity';
  107. ['#main', 'p', '.active'].sort(compare); // ['p', '.active', '#main']
  108. ```
  109. ## Command-line usage
  110. Run `npm install specificity` to install the module locally, or `npm install -g specificity` for global installation. Run `specificity` without arguments to learn about its usage:
  111. ```bash
  112. $ specificity
  113. Usage: specificity <selector>
  114. Computes specificity of a CSS selector.
  115. ```
  116. Pass a selector as the first argument to get its specificity computed:
  117. ```bash
  118. $ specificity "ul#nav li.active a"
  119. 0,1,1,3
  120. ```
  121. ## Testing
  122. To install dependencies, run: `npm install`
  123. Then to test, run: `npm test`