├── .editorconfig ├── .gitignore ├── .rollup.js ├── .tape.js ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── INSTALL.md ├── LICENSE.md ├── README.md ├── example.js ├── index.js ├── lib └── plugins.js ├── package.json └── test ├── basic.css ├── basic.disable.expect.css ├── basic.expect.css └── prefix.css /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = tab 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.md] 11 | trim_trailing_whitespace = false 12 | 13 | [*.{json,md,yml}] 14 | indent_size = 2 15 | indent_style = space 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | index.*.* 3 | package-lock.json 4 | *.log* 5 | *.result.css 6 | .* 7 | !.editorconfig 8 | !.gitignore 9 | !.rollup.js 10 | !.tape.js 11 | !.travis.yml 12 | -------------------------------------------------------------------------------- /.rollup.js: -------------------------------------------------------------------------------- 1 | import babel from 'rollup-plugin-babel'; 2 | 3 | export default { 4 | input: 'index.js', 5 | output: [ 6 | { file: 'index.cjs.js', format: 'cjs', sourcemap: true }, 7 | { file: 'index.es.mjs', format: 'es', sourcemap: true } 8 | ], 9 | plugins: [ 10 | babel({ 11 | presets: [ 12 | ['@babel/env', { modules: false, targets: { node: 6 } }] 13 | ] 14 | }) 15 | ] 16 | }; 17 | -------------------------------------------------------------------------------- /.tape.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'postcss-short': { 3 | 'basic': { 4 | message: 'supports basic usage' 5 | }, 6 | 'basic:disable': { 7 | message: 'supports { features { fontWeights: false } } usage', 8 | options: { 9 | features: { 10 | fontWeights: false 11 | } 12 | } 13 | }, 14 | 'prefix': { 15 | message: 'supports { prefix: "x" } usage', 16 | options: { 17 | prefix: 'x' 18 | }, 19 | expect: 'basic.expect.css' 20 | } 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # https://docs.travis-ci.com/user/travis-lint 2 | 3 | language: node_js 4 | 5 | node_js: 6 | - 6 7 | 8 | install: 9 | - npm install --ignore-scripts 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changes to PostCSS Short 2 | 3 | ### 5.0.0 (October 10, 2018) 4 | 5 | - Added: Support for PostCSS 7, Node 6 6 | - Added: Support for `prefix` and `skip` option 7 | - Changed: Features are controlled via `features` option 8 | 9 | ### 4.1.0 (May 28, 2017) 10 | 11 | - Added: PostCSS Overflow 12 | 13 | ### 4.0.0 (May 25, 2017) 14 | 15 | - Added: Support for PostCSS 6, Node 4 16 | - Removed: echint and jscs devDependencies 17 | - Updated: 2 spaces in Markdown 18 | - Updated: dependencies 19 | 20 | ### 3.0.3 (January 2, 2017) 21 | 22 | - Added: Runkit example 23 | 24 | ### 3.0.2 (January 2, 2017) 25 | 26 | - Updated: Require all plugins from start 27 | - Updated: Override plugin#process 28 | 29 | ### 3.0.1 (December 14, 2016) 30 | 31 | - Updated: Plugins 32 | 33 | ### 3.0.0 (December 6, 2016) 34 | 35 | - Added: A test for a disabled plugin 36 | - Updated: Only use plugins on demand 37 | - Updated: boilerplate conventions (Node v6.9.1 LTS) 38 | 39 | ### 2.0.1 (October 5, 2016) 40 | 41 | Updated: `postcss-short-border-radius` package 42 | 43 | ### 2.0.0 (October 3, 2016) 44 | 45 | Added: Use shorthand `border-radius` properties 46 | Updated: Shorthand `font` property divider is now `/` 47 | Updated: Documentation, and Tests 48 | 49 | ### 1.4.0 (December 8, 2015) 50 | 51 | Added: Use shorthand data attributes `[-name]` 52 | Added: Use common `font-weight` names 53 | Updated: Documentation, and Tests 54 | 55 | ### 1.3.1 (September 30, 2015) 56 | 57 | Updated: Documentation 58 | 59 | ### 1.3.0 (September 30, 2015) 60 | 61 | Added: Short Border 1.0.0 62 | Updated: Improved how options are assigned 63 | 64 | ### 1.2.0 (September 30, 2015) 65 | 66 | Added: Short Color 1.0.0 67 | Updated: Short Font-Size 1.0.1 (patch) 68 | Updated: PostCSS 5.0.8 (patch) 69 | Updated: Documentation 70 | 71 | ### 1.1.1 (September 22, 2015) 72 | 73 | Updated: Documentation 74 | 75 | ### 1.1.0 (September 22, 2015) 76 | 77 | - Updated: Shorthand Text plugin 78 | 79 | ### 1.0.1 (September 22, 2015) 80 | 81 | - Updated: Documentation 82 | 83 | ### 1.0.0 (September 21, 2015) 84 | 85 | - Changed: Refactored as plugin pack 86 | - Changed: Switched to PostCSS 5 API 87 | 88 | ### 0.3.0 (July 3, 2015) 89 | 90 | - Added: `.process` method 91 | - Added: `text-spacing` shorthand 92 | - Added: Tests 93 | - Added: Documentation 94 | 95 | ### 0.2.2 (July 3, 2015) 96 | 97 | - Added: Code commenting 98 | - Changed: Tests 99 | 100 | ### 0.2.1 (July 3, 2015) 101 | 102 | - Added: Tests 103 | - Added: Support for CSS var values 104 | - Changed: Code refactoring 105 | - Removed: Unused CSS naming libraries 106 | 107 | ### 0.2.0 (June 29, 2015) 108 | 109 | - Added: Allowance or denial of individual properties from being processed. 110 | - Added: Prefixing of individual properties. 111 | - Removed: Pseudo-classes. Now use [postcss-pseudo-class-enter](https://github.com/jonathantneal/postcss-pseudo-class-enter) 112 | 113 | ### 0.1.0 (May 27, 2015) 114 | 115 | - Added: Initial release 116 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to PostCSS Short 2 | 3 | You want to help? You rock! Now, take a moment to be sure your contributions 4 | make sense to everyone else. 5 | 6 | ## Reporting Issues 7 | 8 | Found a problem? Want a new feature? 9 | 10 | - See if your issue or idea has [already been reported]. 11 | - Provide a [reduced test case] or a [live example]. 12 | 13 | Remember, a bug is a _demonstrable problem_ caused by _our_ code. 14 | 15 | ## Submitting Pull Requests 16 | 17 | Pull requests are the greatest contributions, so be sure they are focused in 18 | scope and avoid unrelated commits. 19 | 20 | 1. To begin; [fork this project], clone your fork, and add our upstream. 21 | ```bash 22 | # Clone your fork of the repo into the current directory 23 | git clone git@github.com:YOUR_USER/postcss-short.git 24 | 25 | # Navigate to the newly cloned directory 26 | cd postcss-short 27 | 28 | # Assign the original repo to a remote called "upstream" 29 | git remote add upstream git@github.com:jonathantneal/postcss-short.git 30 | 31 | # Install the tools necessary for testing 32 | npm install 33 | ``` 34 | 35 | 2. Create a branch for your feature or fix: 36 | ```bash 37 | # Move into a new branch for your feature 38 | git checkout -b feature/thing 39 | ``` 40 | ```bash 41 | # Move into a new branch for your fix 42 | git checkout -b fix/something 43 | ``` 44 | 45 | 3. If your code follows our practices, then push your feature branch: 46 | ```bash 47 | # Test current code 48 | npm test 49 | ``` 50 | ```bash 51 | # Push the branch for your new feature 52 | git push origin feature/thing 53 | ``` 54 | ```bash 55 | # Or, push the branch for your update 56 | git push origin update/something 57 | ``` 58 | 59 | That’s it! Now [open a pull request] with a clear title and description. 60 | 61 | [already been reported]: issues 62 | [fork this project]: fork 63 | [live example]: https://codepen.io/pen 64 | [open a pull request]: https://help.github.com/articles/using-pull-requests/ 65 | [reduced test case]: https://css-tricks.com/reduced-test-cases/ 66 | -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 | # Installing PostCSS Short 2 | 3 | [PostCSS Short] runs in all Node environments, with special instructions for: 4 | 5 | | [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) | 6 | | --- | --- | --- | --- | --- | --- | 7 | 8 | ## Node 9 | 10 | Add [PostCSS Short] to your project: 11 | 12 | ```bash 13 | npm install postcss-short --save-dev 14 | ``` 15 | 16 | Use [PostCSS Short] to process your CSS: 17 | 18 | ```js 19 | const postcssShort = require('postcss-short'); 20 | 21 | postcssShort.process(YOUR_CSS /*, processOptions, pluginOptions */); 22 | ``` 23 | 24 | Or use it as a [PostCSS] plugin: 25 | 26 | ```js 27 | const postcss = require('postcss'); 28 | const postcssShort = require('postcss-short'); 29 | 30 | postcss([ 31 | postcssShort(/* pluginOptions */) 32 | ]).process(YOUR_CSS /*, processOptions */); 33 | ``` 34 | 35 | ## PostCSS CLI 36 | 37 | Add [PostCSS CLI] to your project: 38 | 39 | ```bash 40 | npm install postcss-cli --save-dev 41 | ``` 42 | 43 | Use [PostCSS Short] in your `postcss.config.js` configuration file: 44 | 45 | ```js 46 | const postcssShort = require('postcss-short'); 47 | 48 | module.exports = { 49 | plugins: [ 50 | postcssShort(/* pluginOptions */) 51 | ] 52 | } 53 | ``` 54 | 55 | ## Webpack 56 | 57 | Add [PostCSS Loader] to your project: 58 | 59 | ```bash 60 | npm install postcss-loader --save-dev 61 | ``` 62 | 63 | Use [PostCSS Short] in your Webpack configuration: 64 | 65 | ```js 66 | const postcssShort = require('postcss-short'); 67 | 68 | module.exports = { 69 | module: { 70 | rules: [ 71 | { 72 | test: /\.css$/, 73 | use: [ 74 | 'style-loader', 75 | { loader: 'css-loader', options: { importLoaders: 1 } }, 76 | { loader: 'postcss-loader', options: { 77 | ident: 'postcss', 78 | plugins: () => [ 79 | postcssShort(/* pluginOptions */) 80 | ] 81 | } } 82 | ] 83 | } 84 | ] 85 | } 86 | } 87 | ``` 88 | 89 | ## Create React App 90 | 91 | Add [React App Rewired] and [React App Rewire PostCSS] to your project: 92 | 93 | ```bash 94 | npm install react-app-rewired react-app-rewire-postcss --save-dev 95 | ``` 96 | 97 | Use [React App Rewire PostCSS] and [PostCSS Short] in your 98 | `config-overrides.js` file: 99 | 100 | ```js 101 | const reactAppRewirePostcss = require('react-app-rewire-postcss'); 102 | const postcssShort = require('postcss-short'); 103 | 104 | module.exports = config => reactAppRewirePostcss(config, { 105 | plugins: () => [ 106 | postcssShort(/* pluginOptions */) 107 | ] 108 | }); 109 | ``` 110 | 111 | ## Gulp 112 | 113 | Add [Gulp PostCSS] to your project: 114 | 115 | ```bash 116 | npm install gulp-postcss --save-dev 117 | ``` 118 | 119 | Use [PostCSS Short] in your Gulpfile: 120 | 121 | ```js 122 | const postcss = require('gulp-postcss'); 123 | const postcssShort = require('postcss-short'); 124 | 125 | gulp.task('css', () => gulp.src('./src/*.css').pipe( 126 | postcss([ 127 | postcssShort(/* pluginOptions */) 128 | ]) 129 | ).pipe( 130 | gulp.dest('.') 131 | )); 132 | ``` 133 | 134 | ## Grunt 135 | 136 | Add [Grunt PostCSS] to your project: 137 | 138 | ```bash 139 | npm install grunt-postcss --save-dev 140 | ``` 141 | 142 | Use [PostCSS Short] in your Gruntfile: 143 | 144 | ```js 145 | const postcssShort = require('postcss-short'); 146 | 147 | grunt.loadNpmTasks('grunt-postcss'); 148 | 149 | grunt.initConfig({ 150 | postcss: { 151 | options: { 152 | use: [ 153 | postcssShort(/* pluginOptions */) 154 | ] 155 | }, 156 | dist: { 157 | src: '*.css' 158 | } 159 | } 160 | }); 161 | ``` 162 | 163 | [Gulp PostCSS]: https://github.com/postcss/gulp-postcss 164 | [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss 165 | [PostCSS]: https://github.com/postcss/postcss 166 | [PostCSS CLI]: https://github.com/postcss/postcss-cli 167 | [PostCSS Loader]: https://github.com/postcss/postcss-loader 168 | [PostCSS Short]: https://github.com/jonathantneal/postcss-short 169 | [React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss 170 | [React App Rewired]: https://github.com/timarney/react-app-rewired 171 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # CC0 1.0 Universal 2 | 3 | ## Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an “owner”) of an original work of 8 | authorship and/or a database (each, a “Work”). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific works 12 | (“Commons”) that the public can reliably and without fear of later claims of 13 | infringement build upon, modify, incorporate in other works, reuse and 14 | redistribute as freely as possible in any form whatsoever and for any purposes, 15 | including without limitation commercial purposes. These owners may contribute 16 | to the Commons to promote the ideal of a free culture and the further 17 | production of creative, cultural and scientific works, or to gain reputation or 18 | greater distribution for their Work in part through the use and efforts of 19 | others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation of 22 | additional consideration or compensation, the person associating CC0 with a 23 | Work (the “Affirmer”), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and 25 | publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights (“Copyright and 31 | Related Rights”). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 1. the right to reproduce, adapt, distribute, perform, display, communicate, 34 | and translate a Work; 35 | 2. moral rights retained by the original author(s) and/or performer(s); 36 | 3. publicity and privacy rights pertaining to a person’s image or likeness 37 | depicted in a Work; 38 | 4. rights protecting against unfair competition in regards to a Work, 39 | subject to the limitations in paragraph 4(i), below; 40 | 5. rights protecting the extraction, dissemination, use and reuse of data in 41 | a Work; 42 | 6. database rights (such as those arising under Directive 96/9/EC of the 43 | European Parliament and of the Council of 11 March 1996 on the legal 44 | protection of databases, and under any national implementation thereof, 45 | including any amended or successor version of such directive); and 46 | 7. other similar, equivalent or corresponding rights throughout the world 47 | based on applicable law or treaty, and any national implementations 48 | thereof. 49 | 50 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 51 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 52 | unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright 53 | and Related Rights and associated claims and causes of action, whether now 54 | known or unknown (including existing as well as future claims and causes of 55 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 56 | duration provided by applicable law or treaty (including future time 57 | extensions), (iii) in any current or future medium and for any number of 58 | copies, and (iv) for any purpose whatsoever, including without limitation 59 | commercial, advertising or promotional purposes (the “Waiver”). Affirmer 60 | makes the Waiver for the benefit of each member of the public at large and 61 | to the detriment of Affirmer’s heirs and successors, fully intending that 62 | such Waiver shall not be subject to revocation, rescission, cancellation, 63 | termination, or any other legal or equitable action to disrupt the quiet 64 | enjoyment of the Work by the public as contemplated by Affirmer’s express 65 | Statement of Purpose. 66 | 67 | 3. Public License Fallback. Should any part of the Waiver for any reason be 68 | judged legally invalid or ineffective under applicable law, then the Waiver 69 | shall be preserved to the maximum extent permitted taking into account 70 | Affirmer’s express Statement of Purpose. In addition, to the extent the 71 | Waiver is so judged Affirmer hereby grants to each affected person a 72 | royalty-free, non transferable, non sublicensable, non exclusive, 73 | irrevocable and unconditional license to exercise Affirmer’s Copyright and 74 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 75 | maximum duration provided by applicable law or treaty (including future time 76 | extensions), (iii) in any current or future medium and for any number of 77 | copies, and (iv) for any purpose whatsoever, including without limitation 78 | commercial, advertising or promotional purposes (the “License”). The License 79 | shall be deemed effective as of the date CC0 was applied by Affirmer to the 80 | Work. Should any part of the License for any reason be judged legally 81 | invalid or ineffective under applicable law, such partial invalidity or 82 | ineffectiveness shall not invalidate the remainder of the License, and in 83 | such case Affirmer hereby affirms that he or she will not (i) exercise any 84 | of his or her remaining Copyright and Related Rights in the Work or (ii) 85 | assert any associated claims and causes of action with respect to the Work, 86 | in either case contrary to Affirmer’s express Statement of Purpose. 87 | 88 | 4. Limitations and Disclaimers. 89 | 1. No trademark or patent rights held by Affirmer are waived, abandoned, 90 | surrendered, licensed or otherwise affected by this document. 91 | 2. Affirmer offers the Work as-is and makes no representations or warranties 92 | of any kind concerning the Work, express, implied, statutory or 93 | otherwise, including without limitation warranties of title, 94 | merchantability, fitness for a particular purpose, non infringement, or 95 | the absence of latent or other defects, accuracy, or the present or 96 | absence of errors, whether or not discoverable, all to the greatest 97 | extent permissible under applicable law. 98 | 3. Affirmer disclaims responsibility for clearing rights of other persons 99 | that may apply to the Work or any use thereof, including without 100 | limitation any person’s Copyright and Related Rights in the Work. 101 | Further, Affirmer disclaims responsibility for obtaining any necessary 102 | consents, permissions or other rights required for any use of the Work. 103 | 4. Affirmer understands and acknowledges that Creative Commons is not a 104 | party to this document and has no duty or obligation with respect to this 105 | CC0 or use of the Work. 106 | 107 | For more information, please see 108 | http://creativecommons.org/publicdomain/zero/1.0/. 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PostCSS Short [PostCSS][postcss] 2 | 3 | [![NPM Version][npm-img]][npm-url] 4 | [![Build Status][cli-img]][cli-url] 5 | [![Support Chat][git-img]][git-url] 6 | 7 | [PostCSS Short] lets you use advanced shorthand properties in CSS. 8 | 9 | > PostCSS Short has been featured in **[Smashing Magazine]**. I hope all of 10 | > these shorthands are useful and clear to first-time lookers. I hope they 11 | > improve the readability of your stylesheets and save you development time 12 | > along the way. Thank you so much for your support. 13 | 14 | ## Features 15 | 16 | ### Size 17 | 18 | Declare `width` and `height` together with `size`. 19 | 20 | ```css 21 | /* before */ 22 | 23 | .icon { 24 | size: 48px; 25 | } 26 | 27 | /* after */ 28 | 29 | .icon { 30 | width: 48px; 31 | height: 48px; 32 | } 33 | ``` 34 | 35 | ### Margin and Padding 36 | 37 | Avoid clobbering previous `margin` or `padding` values with a skip token. 38 | 39 | ```css 40 | /* before */ 41 | 42 | .frame { 43 | margin: * auto; 44 | } 45 | 46 | /* after */ 47 | 48 | .frame { 49 | margin-right: auto; 50 | margin-left: auto; 51 | } 52 | ``` 53 | 54 | ### Position 55 | 56 | Declare `top`, `right`, `bottom`, and `left` values in `position`. Just like before, omit sides with a skip token. 57 | 58 | ```css 59 | /* before */ 60 | 61 | .banner { 62 | position: fixed 0 0 *; 63 | } 64 | 65 | /* after */ 66 | 67 | .banner { 68 | position: fixed; 69 | top: 0; 70 | right: 0; 71 | left: 0; 72 | } 73 | ``` 74 | 75 | ### Color 76 | 77 | Declare `color` and `background-color` together. 78 | 79 | ```css 80 | /* before */ 81 | 82 | .canvas { 83 | color: #abccfc #212231; 84 | } 85 | 86 | /* after */ 87 | 88 | .canvas { 89 | color: #abccfc; 90 | background-color: #212231; 91 | } 92 | ``` 93 | 94 | ### Overflow 95 | 96 | Declare individual `x` and `y` values in `overflow`. Omit sides with a skip 97 | token. 98 | 99 | ```css 100 | /* before */ 101 | 102 | .scrollable { 103 | overflow: * auto; 104 | } 105 | 106 | /* after */ 107 | 108 | .scrollable { 109 | overflow-y: auto; 110 | } 111 | ``` 112 | 113 | ### Border 114 | 115 | Omit sides within `border-` properties and fully define individual values on the `border` property. 116 | 117 | ```css 118 | /* before */ 119 | 120 | .container { 121 | border: 1px 2px / * / #343434; 122 | } 123 | 124 | .container--variation { 125 | border-width: * * 3px; 126 | } 127 | 128 | /* after */ 129 | 130 | .container { 131 | border-width: 1px 2px; 132 | border-color: #343434; 133 | } 134 | 135 | .container--variation { 136 | border-bottom-width: 3px; 137 | } 138 | ``` 139 | 140 | ### Border Radius 141 | 142 | Declare `border-radius` properties using the [clockwise syntax]. 143 | 144 | ```css 145 | /* before */ 146 | 147 | .container { 148 | border-bottom-radius: 10px; 149 | } 150 | 151 | /* after */ 152 | 153 | .container { 154 | border-bottom-left-radius: 10px; 155 | border-bottom-right-radius: 10px; 156 | } 157 | ``` 158 | 159 | ### Font Size 160 | 161 | Declare `font-size` and `line-height` together. 162 | 163 | ```css 164 | /* before */ 165 | 166 | .heading { 167 | font-size: 1.25em / 2; 168 | } 169 | 170 | /* after */ 171 | 172 | .heading { 173 | font-size: 1.25em; 174 | line-height: 2; 175 | } 176 | ``` 177 | 178 | ### Font Weight 179 | 180 | Declare `font-weight` with common names. 181 | 182 | ```css 183 | /* before */ 184 | 185 | p { 186 | font-weight: light; 187 | } 188 | 189 | /* after */ 190 | 191 | p { 192 | font-weight: 300; 193 | } 194 | ``` 195 | 196 | ## Usage 197 | 198 | Add [PostCSS Short] to your project: 199 | 200 | ```bash 201 | npm install postcss-short --save-dev 202 | ``` 203 | 204 | Use [PostCSS Short] to process your CSS: 205 | 206 | ```js 207 | const postcssShort = require('postcss-short'); 208 | 209 | postcssShort.process(YOUR_CSS /*, processOptions, pluginOptions */); 210 | ``` 211 | 212 | Or use it as a [PostCSS] plugin: 213 | 214 | ```js 215 | const postcss = require('postcss'); 216 | const postcssShort = require('postcss-short'); 217 | 218 | postcss([ 219 | postcssShort(/* pluginOptions */) 220 | ]).process(YOUR_CSS /*, processOptions */); 221 | ``` 222 | 223 | [PostCSS Short] runs in all Node environments, with special instructions for: 224 | 225 | | [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | 226 | | --- | --- | --- | --- | --- | --- | 227 | 228 | ## Plugins 229 | 230 | [PostCSS Short] is powered by the following plugins: 231 | 232 | - [PostCSS Short Border](https://github.com/jonathantneal/postcss-short-border) 233 | - [PostCSS Short Border Radius](https://github.com/jonathantneal/postcss-short-border-radius) 234 | - [PostCSS Short Color](https://github.com/jonathantneal/postcss-short-color) 235 | - [PostCSS Short Font-Size](https://github.com/jonathantneal/postcss-short-font-size) 236 | - [PostCSS Short Overflow](https://github.com/jonathantneal/postcss-short-overflow) 237 | - [PostCSS Short Position](https://github.com/jonathantneal/postcss-short-position) 238 | - [PostCSS Short Size](https://github.com/jonathantneal/postcss-short-size) 239 | - [PostCSS Short Spacing](https://github.com/jonathantneal/postcss-short-spacing) 240 | - [PostCSS Font Weights](https://github.com/jonathantneal/postcss-font-weights) 241 | 242 | Some of these plugins have more features than are described here. 243 | 244 | ## Options 245 | 246 | ### features 247 | 248 | Each plugin’s options may be configured by targeting the plugin’s namespace. 249 | Any plugin may be disabled by setting the plugin’s options as false. 250 | 251 | ```js 252 | postcssShort({ 253 | features: { 254 | 'font-size': { 255 | prefix: 'x' 256 | }, 257 | 'position': false 258 | } 259 | }); 260 | ``` 261 | 262 | #### prefix 263 | 264 | The `prefix` option defines a prefix required by properties being transformed. 265 | Wrapping dashes are automatically applied, so that `x` would transform 266 | `-x-border`. 267 | 268 | ```js 269 | postcssShort({ prefix: 'x' }); 270 | ``` 271 | 272 | ```pcss 273 | .example-1 { 274 | -x-border-color: blue blue *; 275 | -x-color: * #fafafa; 276 | } 277 | 278 | /* becomes */ 279 | 280 | .example-1 { 281 | border-top-color: blue; 282 | border-right-color: blue; 283 | border-left-color: blue; 284 | background-color: #fafafa; 285 | } 286 | ``` 287 | 288 | #### skip 289 | 290 | The `skip` option defines the skip token used to ignore portions of the 291 | shorthand. 292 | 293 | ```js 294 | postcssShort({ skip: '-' }); 295 | ``` 296 | 297 | ```pcss 298 | .example-1 { 299 | border-color: blue blue -; 300 | color: - #fafafa; 301 | } 302 | 303 | /* becomes */ 304 | 305 | .example-1 { 306 | border-top-color: blue; 307 | border-right-color: blue; 308 | border-left-color: blue; 309 | background-color: #fafafa; 310 | } 311 | ``` 312 | 313 | [cli-img]: https://img.shields.io/travis/jonathantneal/postcss-short.svg 314 | [cli-url]: https://travis-ci.org/jonathantneal/postcss-short 315 | [git-img]: https://img.shields.io/badge/support-chat-blue.svg 316 | [git-url]: https://gitter.im/postcss/postcss 317 | [npm-img]: https://img.shields.io/npm/v/postcss-short.svg 318 | [npm-url]: https://www.npmjs.com/package/postcss-short 319 | 320 | [PostCSS]: https://github.com/postcss/postcss 321 | [PostCSS Short]: https://github.com/jonathantneal/postcss-short 322 | [clockwise syntax]: https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties#Tricky_edge_cases 323 | [Smashing Magazine]: https://www.smashingmagazine.com/2015/12/introduction-to-postcss/#extendedshorthandpropertieswithpostcss-short 324 | -------------------------------------------------------------------------------- /example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Add your CSS code here. 3 | * See https://github.com/jonathantneal/postcss-short#features for more examples 4 | */ 5 | 6 | const css = ` 7 | .banner { 8 | color: #abccfc #212231; 9 | font-size: 1.5em/2; 10 | font-weight: light; 11 | position: fixed 0 0 *; 12 | size: 100% 48px; 13 | } 14 | 15 | .section { 16 | border-top-radius: 50px; 17 | margin: 40px; 18 | } 19 | 20 | .section.inset { 21 | margin: * auto; 22 | } 23 | `; 24 | 25 | /* 26 | * Add your plugin configuration here; see 27 | * https://github.com/jonathantneal/postcss-short#options for more details. 28 | */ 29 | 30 | const pluginOptions = {}; 31 | 32 | /* 33 | * Add your process configuration here; see 34 | * http://api.postcss.org/global.html#processOptions for more details. 35 | */ 36 | 37 | const processOptions = {}; 38 | 39 | /* 40 | * Process the CSS and log it to the console. 41 | */ 42 | 43 | require('postcss-short').process(css, pluginOptions, processOptions).then( 44 | (result) => { 45 | console.log(result.css); 46 | } 47 | ); 48 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import postcss from 'postcss';// plugins by name 2 | import plugins from './lib/plugins'; 3 | 4 | export default postcss.plugin('postcss-short', opts => { 5 | const features = Object.assign({}, Object(opts).features); 6 | const pluginOpts = {}; 7 | 8 | if ('prefix' in Object(opts)) { 9 | pluginOpts.prefix = opts.prefix; 10 | } 11 | 12 | if ('skip' in Object(opts)) { 13 | pluginOpts.skip = opts.skip; 14 | } 15 | 16 | const enabledPlugins = Object.keys(plugins).reduce( 17 | (array, name) => features[name] === false 18 | ? array 19 | : array.concat( 20 | plugins[name]( 21 | Object.assign({}, pluginOpts, features[name]) 22 | ) 23 | ), 24 | [] 25 | ); 26 | 27 | return (root, result) => enabledPlugins.reduce( 28 | (promise, plugin) => promise.then( 29 | () => plugin(result.root, result) 30 | ), 31 | Promise.resolve() 32 | ); 33 | }); 34 | -------------------------------------------------------------------------------- /lib/plugins.js: -------------------------------------------------------------------------------- 1 | import postcssShortBorder from 'postcss-short-border'; 2 | import postcssShortBorderRadius from 'postcss-short-border-radius'; 3 | import postcssShortColor from 'postcss-short-color'; 4 | import postcssShortFontSize from 'postcss-short-font-size'; 5 | import postcssShortOverflow from 'postcss-short-overflow'; 6 | import postcssShortPosition from 'postcss-short-position'; 7 | import postcssShortSize from 'postcss-short-size'; 8 | import postcssShortSpacing from 'postcss-short-spacing'; 9 | import postcssFontWeights from 'postcss-font-weights'; 10 | 11 | export default { 12 | border: postcssShortBorder, 13 | borderRadius: postcssShortBorderRadius, 14 | color: postcssShortColor, 15 | fontSize: postcssShortFontSize, 16 | overflow: postcssShortOverflow, 17 | position: postcssShortPosition, 18 | size: postcssShortSize, 19 | spacing: postcssShortSpacing, 20 | fontWeights: postcssFontWeights 21 | }; 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postcss-short", 3 | "version": "5.0.0", 4 | "description": "Use advanced shorthand properties in CSS", 5 | "author": "Jonathan Neal ", 6 | "license": "CC0-1.0", 7 | "repository": "jonathantneal/postcss-short", 8 | "homepage": "https://github.com/jonathantneal/postcss-short#readme", 9 | "bugs": "https://github.com/jonathantneal/postcss-short/issues", 10 | "main": "index.cjs.js", 11 | "module": "index.es.mjs", 12 | "files": [ 13 | "index.cjs.js", 14 | "index.cjs.js.map", 15 | "index.es.mjs", 16 | "index.es.mjs.map" 17 | ], 18 | "scripts": { 19 | "prepublishOnly": "npm test", 20 | "pretest": "rollup -c .rollup.js --silent", 21 | "test": "npm run test:js && npm run test:tape", 22 | "test:js": "eslint *.js lib/*.js --cache --ignore-path .gitignore --quiet", 23 | "test:tape": "postcss-tape" 24 | }, 25 | "engines": { 26 | "node": ">=6.0.0" 27 | }, 28 | "dependencies": { 29 | "postcss": "^7.0.5", 30 | "postcss-font-weights": "^5.0.0", 31 | "postcss-short-border": "^4.0.0", 32 | "postcss-short-border-radius": "^3.0.0", 33 | "postcss-short-color": "^4.0.0", 34 | "postcss-short-font-size": "^5.0.0", 35 | "postcss-short-overflow": "^1.0.0", 36 | "postcss-short-position": "^4.0.1", 37 | "postcss-short-size": "^4.0.0", 38 | "postcss-short-spacing": "^4.0.0" 39 | }, 40 | "devDependencies": { 41 | "@babel/core": "^7.1.2", 42 | "@babel/plugin-syntax-dynamic-import": "^7.0.0", 43 | "@babel/preset-env": "^7.1.0", 44 | "babel-eslint": "^10.0.1", 45 | "eslint": "^5.6.1", 46 | "eslint-config-dev": "^2.0.0", 47 | "postcss-tape": "^2.2.0", 48 | "pre-commit": "^1.2.2", 49 | "rollup": "^0.66.5", 50 | "rollup-plugin-babel": "^4.0.3" 51 | }, 52 | "eslintConfig": { 53 | "extends": "dev", 54 | "parser": "babel-eslint" 55 | }, 56 | "keywords": [ 57 | "postcss", 58 | "css", 59 | "postcss-plugin", 60 | "shorthands", 61 | "asterisks", 62 | "colors", 63 | "backgrounds", 64 | "margins", 65 | "paddings", 66 | "spacings", 67 | "positions", 68 | "sizes", 69 | "sizings", 70 | "min-sizes", 71 | "max-sizes", 72 | "texts", 73 | "colors", 74 | "font-styles", 75 | "font-variants", 76 | "font-weights", 77 | "font-stretchs", 78 | "text-decorations", 79 | "text-aligns", 80 | "text-renderings", 81 | "text-transforms", 82 | "white-spaces", 83 | "font-sizes", 84 | "line-heights", 85 | "letter-spacings", 86 | "word-spacings", 87 | "font-families", 88 | "font-family", 89 | "datas", 90 | "attributes" 91 | ] 92 | } 93 | -------------------------------------------------------------------------------- /test/basic.css: -------------------------------------------------------------------------------- 1 | .example { 2 | border: 1px 2px / * / #343434; 3 | border-bottom-radius: 10px; 4 | color: #abccfc #212231; 5 | font-size: 12px/1; 6 | font-weight: light; 7 | margin: * auto; 8 | overflow: * auto; 9 | position: fixed 0 0 *; 10 | size: 100% 48px; 11 | } 12 | -------------------------------------------------------------------------------- /test/basic.disable.expect.css: -------------------------------------------------------------------------------- 1 | .example { 2 | border-width: 1px 2px; 3 | border-color: #343434; 4 | border-bottom-left-radius: 10px; 5 | border-bottom-right-radius: 10px; 6 | background-color: #212231; 7 | color: #abccfc; 8 | line-height: 1; 9 | font-size: 12px; 10 | font-weight: light; 11 | margin-left: auto; 12 | margin-right: auto; 13 | overflow-y: auto; 14 | top: 0; 15 | right: 0; 16 | left: 0; 17 | position: fixed; 18 | width: 100%; 19 | height: 48px; 20 | } 21 | -------------------------------------------------------------------------------- /test/basic.expect.css: -------------------------------------------------------------------------------- 1 | .example { 2 | border-width: 1px 2px; 3 | border-color: #343434; 4 | border-bottom-left-radius: 10px; 5 | border-bottom-right-radius: 10px; 6 | background-color: #212231; 7 | color: #abccfc; 8 | line-height: 1; 9 | font-size: 12px; 10 | font-weight: 300; 11 | margin-left: auto; 12 | margin-right: auto; 13 | overflow-y: auto; 14 | top: 0; 15 | right: 0; 16 | left: 0; 17 | position: fixed; 18 | width: 100%; 19 | height: 48px; 20 | } 21 | -------------------------------------------------------------------------------- /test/prefix.css: -------------------------------------------------------------------------------- 1 | .example { 2 | -x-border: 1px 2px / * / #343434; 3 | -x-border-bottom-radius: 10px; 4 | -x-color: #abccfc #212231; 5 | -x-font-size: 12px/1; 6 | -x-font-weight: light; 7 | -x-margin: * auto; 8 | -x-overflow: * auto; 9 | -x-position: fixed 0 0 *; 10 | -x-size: 100% 48px; 11 | } 12 | --------------------------------------------------------------------------------