├── .gitignore
├── README.md
├── index.js
├── index.test.js
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | coverage/
2 | node_modules/
3 | npm-debug.log
4 | yarn-error.log
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PostCSS will change transition
2 | [PostCSS]: https://github.com/postcss/postcss
3 |
4 |
7 |
8 | [PostCSS] plugin to generate will-change for transition props.
9 |
10 | This plugin adds `will-change` property after `transition` property to speed up animations.
11 |
12 | Can be combined with [postcss-will-change](https://github.com/postcss/postcss-will-change) plugin.
13 |
14 |
15 |
16 | ```css
17 | .foo {
18 | transition: opacity 0.2s ease, width 0.2s ease;
19 | }
20 | ```
21 |
22 | ```css
23 | .foo {
24 | transition: opacity 0.2s ease, width 0.2s ease;
25 | will-change: opacity, width;
26 | }
27 | ```
28 |
29 | ## Important note
30 |
31 | Make sure that if you use this plugin it does not contradict with `will-change` idea. Please see links below:
32 |
33 | - https://developer.mozilla.org/en-US/docs/Web/CSS/will-change
34 | - https://www.sitepoint.com/introduction-css-will-change-property/
35 | - https://css-tricks.com/almanac/properties/w/will-change/
36 |
37 | ## Usage
38 |
39 | ```js
40 | postcss([ require('postcss-will-change-transition') ])
41 |
42 | // with fallback plugin:
43 | postcss([ require('postcss-will-change-transition'), require('postcss-will-change') ])
44 | ```
45 |
46 | See [PostCSS] docs for examples for your environment.
47 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const postcss = require('postcss');
2 | const cssProps = require('css-properties-values');
3 |
4 | const transitionProps = cssProps.map(prop => prop.property);
5 |
6 | module.exports = postcss.plugin('postcss-will-change-transition', function () {
7 | return function (css) {
8 | css.walkDecls('transition', function (decl) {
9 | const already = decl.parent.some(elem =>
10 | elem.type === 'decl' && elem.prop === 'will-change'
11 | );
12 |
13 | if (already || /all/.test(decl.value)) {
14 | return;
15 | }
16 |
17 | const value = decl.value
18 | .split(',')
19 | .map(str => str.trim().split(' '))
20 | .filter(splitted => transitionProps.includes(splitted[0]))
21 | .map(splitted => splitted[0])
22 | .join(', ');
23 |
24 | if (!value) {
25 | return;
26 | }
27 |
28 | decl.cloneAfter({
29 | prop: 'will-change',
30 | value
31 | });
32 | });
33 | };
34 | });
35 |
--------------------------------------------------------------------------------
/index.test.js:
--------------------------------------------------------------------------------
1 | const postcss = require('postcss');
2 |
3 | const plugin = require('./');
4 |
5 | function run(input, output) {
6 | return postcss([ plugin ]).process(input).then(result => {
7 | expect(result.css).toEqual(output);
8 | expect(result.warnings().length).toBe(0);
9 | });
10 | }
11 |
12 | it('adds will-change prop', () => {
13 | const input = `
14 | a {
15 | transition: opacity 0.2s ease, width;
16 | }
17 | `;
18 | const output = `
19 | a {
20 | transition: opacity 0.2s ease, width;
21 | will-change: opacity, width;
22 | }
23 | `;
24 |
25 | return run(
26 | input,
27 | output
28 | );
29 | });
30 |
31 | it('does not override existing properties', () => {
32 | return run('a{ transition: opacity 0.2s ease, width; will-change: top; }',
33 | 'a{ transition: opacity 0.2s ease, width; will-change: top; }');
34 | });
35 |
36 | it('does not get confused by other selectors', () => {
37 | const input = `
38 | a {
39 | will-change: initial;
40 | }
41 |
42 | b {
43 | transition: top .2s ease-in-out, left 5s linear;
44 | }
45 | `;
46 | const output = `
47 | a {
48 | will-change: initial;
49 | }
50 |
51 | b {
52 | transition: top .2s ease-in-out, left 5s linear;
53 | will-change: top, left;
54 | }
55 | `;
56 | return run(input, output);
57 | });
58 |
59 | it('ignore `all` prop', () => {
60 | const input = `
61 | a {
62 | transition: all .2s ease-in-out;
63 | }
64 | `;
65 | const output = `
66 | a {
67 | transition: all .2s ease-in-out;
68 | }
69 | `;
70 | return run(input, output);
71 | });
72 |
73 | it('ignore `all` shorthands', () => {
74 | const input = `
75 | a {
76 | transition: .25s;
77 | }
78 |
79 | b {
80 | transition: 0.25s;
81 | }
82 |
83 | c {
84 | transition: 0.25s ease;
85 | }
86 | `;
87 | const output = `
88 | a {
89 | transition: .25s;
90 | }
91 |
92 | b {
93 | transition: 0.25s;
94 | }
95 |
96 | c {
97 | transition: 0.25s ease;
98 | }
99 | `;
100 | return run(input, output);
101 | });
102 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "postcss-will-change-transition",
3 | "version": "1.2.0",
4 | "description": "PostCSS plugin to generate will-change for transition props",
5 | "keywords": [
6 | "postcss",
7 | "css",
8 | "postcss-plugin",
9 | "will-change",
10 | "transition"
11 | ],
12 | "author": "Anatoly Ostrovsky ",
13 | "license": "MIT",
14 | "repository": "megatolya/postcss-will-change-transition.git",
15 | "dependencies": {
16 | "css-properties-values": "1.0.0",
17 | "postcss": "^6.0.1"
18 | },
19 | "devDependencies": {
20 | "eslint": "^3.19.0",
21 | "eslint-config-postcss": "^2.0.2",
22 | "jest": "^20.0.0",
23 | "lint-staged": "^3.4.1",
24 | "pre-commit": "^1.2.2"
25 | },
26 | "scripts": {
27 | "lint-staged": "lint-staged",
28 | "test": "jest --colors --silent=false --coverage index.test.js && eslint *.js"
29 | },
30 | "jest": {
31 | "coverageThreshold": {
32 | "global": {
33 | "statements": 100
34 | }
35 | }
36 | },
37 | "eslintConfig": {
38 | "extends": "eslint-config-postcss/es5",
39 | "env": {
40 | "jest": true
41 | }
42 | },
43 | "lint-staged": {
44 | "*.js": "eslint"
45 | },
46 | "pre-commit": [
47 | "lint-staged"
48 | ]
49 | }
50 |
--------------------------------------------------------------------------------