1 | [PostCSS]: https://github.com/postcss/postcss
|
2 | [PostCSS-SCSS]: https://github.com/postcss/postcss-scss
|
3 | [LESS]: http://lesless.org
|
4 | [Autoprefixer]: https://github.com/postcss/autoprefixer
|
5 | [Stylelint]: http://stylelint.io/
|
6 |
|
7 | # PostCSS LESS Syntax [![Build Status](https://img.shields.io/travis/shellscape/postcss-less.svg?branch=develop)](https://travis-ci.org/webschik/postcss-less) [![npm Version](https://img.shields.io/npm/v/postcss-less.svg)](https://www.npmjs.com/package/postcss-less)
|
8 |
|
9 | [PostCSS] Syntax for parsing [LESS]
|
10 |
|
11 | <img align="right" width="95" height="95"
|
12 | title="Philosopher's stone, logo of PostCSS"
|
13 | src="http://postcss.github.io/postcss/logo.svg">
|
14 |
|
15 | Please note: poscss-less is not a LESS compiler. For compiling LESS, please use
|
16 | the official toolset for LESS.
|
17 |
|
18 | ## Getting Started
|
19 |
|
20 | First thing's first, install the module:
|
21 |
|
22 | ```
|
23 | npm install postcss-less --save-dev
|
24 | ```
|
25 |
|
26 | ## LESS Transformations
|
27 |
|
28 | The most common use of `postcss-less` is for applying PostCSS transformations
|
29 | directly to LESS source. eg. ia theme written in LESS which uses [Autoprefixer]
|
30 | to add appropriate vendor prefixes.
|
31 |
|
32 | ```js
|
33 | const syntax = require('postcss-less');
|
34 | postcss(plugins)
|
35 | .process(lessText, { syntax: syntax })
|
36 | .then(function (result) {
|
37 | result.content // LESS with transformations
|
38 | });
|
39 | ```
|
40 |
|
41 | ## Inline Comments
|
42 |
|
43 | Parsing of single-line comments in CSS is also supported.
|
44 |
|
45 | ```less
|
46 | :root {
|
47 | // Main theme color
|
48 | --color: red;
|
49 | }
|
50 | ```
|
51 |
|
52 | Note that you don't need a custom stringifier to handle the output; the default
|
53 | stringifier will automatically convert single line comments into block comments.
|
54 | If you need to support inline comments, please use a [custom PostCSSLess stringifier](#stringifier).
|
55 |
|
56 | ## Rule Node
|
57 |
|
58 | [PostCSS Rule Node](https://github.com/postcss/postcss/blob/master/docs/api.md#rule-node)
|
59 |
|
60 | ### rule.empty
|
61 |
|
62 | Determines whether or not a rule contains declarations.
|
63 |
|
64 | _Note: Previously `ruleWithoutBody`. This is a breaking change from v0.16.0 to v1.0.0._
|
65 |
|
66 | ```js
|
67 | import postCssLess from 'postcss-less';
|
68 | const less = `
|
69 | .class2 {
|
70 | &:extend(.class1);
|
71 | .mixin-name(@param1, @param2);
|
72 | }
|
73 | `;
|
74 | const root = postCssLess.parse(less);
|
75 |
|
76 | root.first.nodes[0].empty // => true for &:extend
|
77 | root.first.nodes[1].empty // => true for calling of mixin
|
78 | ```
|
79 |
|
80 | ### rule.extend
|
81 |
|
82 | Determines whether or not a rule is [nested](http://lesscss.org/features/#extend-feature-extend-inside-ruleset).
|
83 |
|
84 | _Note: Previously `extendRule`. This is a breaking change from v0.16.0 to v1.0.0._
|
85 |
|
86 | ```js
|
87 | import postCssLess from 'postcss-less';
|
88 | const less = `
|
89 | .class2 {
|
90 | &:extend(.class1);
|
91 | }
|
92 | `;
|
93 | const root = postCssLess.parse(less);
|
94 |
|
95 | root.first.nodes[0].extend // => true
|
96 | ```
|
97 |
|
98 | ### rule.important
|
99 |
|
100 | Determines whether or not a rule is marked as [important](http://lesscss.org/features/#mixins-feature-the-important-keyword).
|
101 |
|
102 | _Note: This is a breaking change from v0.16.0 to v1.0.0._
|
103 |
|
104 | ```js
|
105 | import postCssLess from 'postcss-less';
|
106 | const less = `
|
107 | .class {
|
108 | .mixin !important;
|
109 | }
|
110 | `;
|
111 | const root = postCssLess.parse(less);
|
112 |
|
113 | root.first.nodes[0].important // => true
|
114 | root.first.nodes[0].selector // => '.mixin'
|
115 | ```
|
116 |
|
117 | ### rule.mixin
|
118 |
|
119 | Determines whether or not a rule is a [mixin](http://lesscss.org/features/#mixins-feature).
|
120 |
|
121 | ```js
|
122 | import postCssLess from 'postcss-less';
|
123 | const less = `
|
124 | .class2 {
|
125 | .mixin-name;
|
126 | }
|
127 | `;
|
128 | const root = postCssLess.parse(less);
|
129 |
|
130 | root.first.nodes[0].mixin // => true
|
131 | ```
|
132 |
|
133 | ### rule.nodes
|
134 |
|
135 | An `Array` of child nodes.
|
136 |
|
137 | **Note** that `nodes` is `undefined` for rules that don't contain declarations.
|
138 |
|
139 | ```js
|
140 | import postCssLess from 'postcss-less';
|
141 | const less = `
|
142 | .class2 {
|
143 | &:extend(.class1);
|
144 | .mixin-name(@param1, @param2);
|
145 | }
|
146 | `;
|
147 | const root = postCssLess.parse(less);
|
148 |
|
149 | root.first.nodes[0].nodes // => undefined for &:extend
|
150 | root.first.nodes[1].nodes // => undefined for mixin
|
151 | ```
|
152 |
|
153 | ## Comment Node
|
154 |
|
155 | [PostCSS Comment Node](https://github.com/postcss/postcss/blob/master/docs/api.md#comment-node)
|
156 |
|
157 | ### comment.inline
|
158 |
|
159 | Determines whether or not a comment is inline.
|
160 |
|
161 | ```js
|
162 | import postCssLess from 'postcss-less';
|
163 |
|
164 | const root = postCssLess.parse('// Hello world');
|
165 |
|
166 | root.first.inline // => true
|
167 | ```
|
168 |
|
169 | ### comment.block
|
170 |
|
171 | Determines whether or not a comment is a block comment.
|
172 |
|
173 | ```js
|
174 | import postCssLess from 'postcss-less';
|
175 |
|
176 | const root = postCssLess.parse('/* Hello world */');
|
177 |
|
178 | root.first.block // => true
|
179 | ```
|
180 |
|
181 | ### comment.raws.begin
|
182 |
|
183 | Precending characters of a comment node. eg. `//` or `/*`.
|
184 |
|
185 | ### comment.raws.content
|
186 |
|
187 | Raw content of the comment.
|
188 |
|
189 | ```js
|
190 | import postCssLess from 'postcss-less';
|
191 |
|
192 | const root = postCssLess.parse('// Hello world');
|
193 |
|
194 | root.first.raws.content // => '// Hello world'
|
195 | ```
|
196 |
|
197 | ## Stringifying
|
198 |
|
199 | To process LESS code without PostCSS transformations, custom stringifier
|
200 | should be provided.
|
201 |
|
202 | ```js
|
203 | import postcss from 'postcss';
|
204 | import postcssLess from 'postcss-less';
|
205 | import stringify from 'postcss-less/less-stringify';
|
206 |
|
207 | const lessCode = `
|
208 | // Non-css comment
|
209 |
|
210 | .container {
|
211 | .mixin-1();
|
212 | .mixin-2;
|
213 | .mixin-3 (@width: 100px) {
|
214 | width: @width;
|
215 | }
|
216 | }
|
217 |
|
218 | .rotation(@deg:5deg){
|
219 | .transform(rotate(@deg));
|
220 | }
|
221 | `;
|
222 |
|
223 | postcss()
|
224 | .process(less, {
|
225 | syntax: postcssLess,
|
226 | stringifier: stringify
|
227 | })
|
228 | .then((result) => {
|
229 | console.log(result.content); // this will be value of `lessCode` without changing comments or mixins
|
230 | });
|
231 | ```
|
232 |
|
233 | ## Use Cases
|
234 |
|
235 | * Lint LESS code with 3rd-party plugins.
|
236 | * Apply PostCSS transformations (such as [Autoprefixer](https://github.com/postcss/autoprefixer)) directly to the LESS source code
|
237 |
|
238 | ## Contribution
|
239 |
|
240 | Please, check our guidelines: [CONTRIBUTING.md](./CONTRIBUTING.md)
|
241 |
|
242 | ## Attribution
|
243 |
|
244 | This module is based on the [postcss-scss](https://github.com/postcss/postcss-scss) library.
|
245 |
|
246 | [![npm Downloads](https://img.shields.io/npm/dt/postcss-less.svg)](https://www.npmjs.com/package/postcss-less)
|
247 | [![npm License](https://img.shields.io/npm/l/postcss-less.svg)](https://www.npmjs.com/package/postcss-less)
|
248 | [![js-strict-standard-style](https://img.shields.io/badge/code%20style-strict-117D6B.svg)](https://github.com/keithamus/eslint-config-strict)
|