···33**Bare essentials CSS prefixing helpers in less than 1KB ๐**
4455[](https://www.npmjs.com/package/tiny-css-prefixer)
66-[](https://unpkg.com/tiny-css-prefixer)
66+[](https://unpkg.com/tiny-css-prefixer)
7788Currently supports prefixing properties for most browsers as it makes sense.
99[See `SUPPORT.md` for more information on which prefixes and transformations have been omitted.](./SUPPORT.md)
···1111The API is fairly straightforward and only consists of two functions, `prefixProperty` and `prefixValue`.
12121313```js
1414-prefixProperty('margin'); // ['margin']
1515-prefixProperty('appearance'); // ['appearance', '-moz-appearance', '-webkit-appearance']
1414+prefixProperty('margin'); // 0b000
1515+prefixProperty('appearance'); // 0b110
16161717prefixValue('color', 'palevioletred'); // 'palevioletred'
1818prefixValue('position', 'sticky'); // '-webkit-sticky, sticky'
1919```
2020+2121+`prefixProperty` returns a bitmap depending on which prefix should be
2222+applied:
2323+2424+- `0b001` stands for `-ms-`
2525+- `0b010` stands for `-moz-`
2626+- `0b100` stands for `-webkit`
2727+2828+These are combined using a binary OR, so an example usage of the
2929+`prefixProperty` helper may look like the following:
3030+3131+```js
3232+const prefix = (prop, value) => {
3333+ const flag = prefixProperty(prop);
3434+ let css = `${prop}: ${value};\n`;
3535+ if (flag & 0b001) css += `-ms-${css}`;
3636+ if (flag & 0b010) css += `-moz-${css}`;
3737+ if (flag & 0b100) css += `-webkit-${css}`;
3838+ return css;
3939+};
4040+```
4141+4242+Additionally `prefixValue` can accept full declarations to avoid
4343+having to apply it before concatenation, which can be useful in case
4444+you're trying to minimise string operations:
4545+4646+```js
4747+const declaration = 'position: sticky';
4848+prefixValue(declaration, declaration); // 'position: -webkit-sticky, sticky'
4949+```
···11#!/usr/bin/env node
2233-const fs = require('fs');
44-const path = require('path');
53const prefixMap = require('inline-style-prefixer/lib/data').default.prefixMap;
64const mdnProperties = require('mdn-data/css/properties.json');
75···5149// NOTE: Their variants with before/after are not supported
5250// by Firefox and should be avoided
5351properties.push(...[
5454- 'margin-start',
5555- 'margin-end',
5656- 'padding-start',
5757- 'padding-end',
5852 'border-start',
5953 'border-start-color',
6054 'border-start-style',
···8579 !properties.some(({ name }) => name === x)
8680 ));
87818888-/** Lists each prefixed property with the minimum substring that is needed to uniquely identity it */
8989-const prefixPatterns = properties
9090- .map(prop => {
9191- let name = prop.name;
9292- for (let i = 2, l = name.length; i < l; i++) {
9393- const substr = name.slice(0, i);
9494- // Check for any name that conflicts with the substring in all known CSS properties
9595- if (stablePropertyNames.every(x => x === name || !x.startsWith(substr))) {
9696- name = substr;
9797- break;
9898- }
8282+/** Finds the minimum starting substring that uniquely identifier a property out of all known CSS properties */
8383+const findMinimumSubstr = name => {
8484+ for (let i = 2, l = name.length; i < l; i++) {
8585+ const substr = name.slice(0, i);
8686+ // Check for any name that conflicts with the substring in all known CSS properties
8787+ if (stablePropertyNames.every(x => x === name || !x.startsWith(substr))) {
8888+ return substr;
9989 }
9090+ }
10091101101- return { ...prop, name };
102102- });
9292+ return name;
9393+};
9494+9595+/** Lists each prefixed property with the minimum substring that is needed to uniquely identity it */
9696+const prefixPatterns = properties.map(prop => ({
9797+ ...prop,
9898+ name: findMinimumSubstr(prop.name)
9999+}));
100100+101101+/** For Webkit prefixes, these properties will need some values to be prefixed */
102102+const prefixValuePatterns = ['position', 'background-clip'].map(findMinimumSubstr);
103103104104/** Accepts a filter and builds a list of names in `prefixPatterns` */
105105const reducePrefixes = (filter = x => !!x) => {
···108108 return acc;
109109 }, new Set());
110110111111- return [...set].sort();
111111+ return [...set].sort((a, b) => {
112112+ if (a.length === b.length) return a.localeCompare(b);
113113+ return a.length - b.length;
114114+ });
112115};
113116117117+/** Creates a regex matching property names */
114118const buildRegex = groups => `^(${groups.join('|')})`;
115119116120// Create all prefix sets for each prefix
···118122const mozPrefixes = buildRegex(reducePrefixes(x => x.moz));
119123const webkitPrefixes = buildRegex(reducePrefixes(x => x.webkit));
120124125125+// Create a regex for webkit value transforms
126126+const webkitValuePrefix = buildRegex(prefixValuePatterns);
127127+121128module.exports = `
122129var msPrefixRe = /${msPrefixes}/;
123130var mozPrefixRe = /${mozPrefixes}/;
124131var webkitPrefixRe = /${webkitPrefixes}/;
132132+var webkitValuePrefixRe = /${webkitValuePrefix}/;
125133`.trim();
+1-1
src/index.d.ts
···22export as namespace CSSPrefixer;
3344declare namespace CSSPrefixer {
55- function prefixProperty(prop: string): string[];
55+ function prefixProperty(prop: string): 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
66 function prefixValue(prop: string, value: string): string;
77}