Merge longhand properties into shorthand with PostCSS.
npx @tessl/cli install tessl/npm-postcss-merge-longhand@7.0.00
# postcss-merge-longhand
1
2
postcss-merge-longhand is a PostCSS plugin that optimizes CSS by merging longhand properties into their shorthand equivalents. It automatically combines related longhand properties (like margin-top, margin-right, margin-bottom, margin-left) into concise shorthand declarations (like margin: 10px 20px) when possible, reducing file size and improving performance.
3
4
## Package Information
5
6
- **Package Name**: postcss-merge-longhand
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install postcss-merge-longhand postcss`
10
11
## Core Imports
12
13
```javascript
14
const plugin = require("postcss-merge-longhand");
15
```
16
17
For ES modules:
18
19
```javascript
20
import plugin from "postcss-merge-longhand";
21
```
22
23
## Basic Usage
24
25
```javascript
26
const postcss = require("postcss");
27
const mergeLonghand = require("postcss-merge-longhand");
28
29
// Create PostCSS processor with the plugin
30
const processor = postcss([mergeLonghand()]);
31
32
// Process CSS
33
const result = processor.process(`
34
h1 {
35
margin-top: 10px;
36
margin-right: 20px;
37
margin-bottom: 10px;
38
margin-left: 20px;
39
}
40
`);
41
42
// Output: h1 { margin: 10px 20px; }
43
console.log(result.css);
44
```
45
46
## Capabilities
47
48
### Plugin Creator Function
49
50
Creates a PostCSS plugin instance that merges longhand properties into shorthand equivalents.
51
52
```javascript { .api }
53
/**
54
* Creates a PostCSS plugin instance for merging longhand properties
55
* @returns {Plugin} PostCSS plugin object
56
*/
57
function pluginCreator(): Plugin;
58
59
/** Plugin creator has postcss property set to true */
60
pluginCreator.postcss: true;
61
```
62
63
### Plugin Object
64
65
The PostCSS plugin object returned by the plugin creator.
66
67
```javascript { .api }
68
interface Plugin {
69
/** Plugin name identifier */
70
postcssPlugin: "postcss-merge-longhand";
71
/** Processing function that runs once after CSS parsing */
72
OnceExit(css: PostCSSRoot): void;
73
}
74
75
interface PostCSSRoot {
76
/** Walk through all rules in the CSS AST */
77
walkRules(callback: (rule: PostCSSRule) => void): void;
78
}
79
80
interface PostCSSRule {
81
/** Walk through all declarations in this rule */
82
walkDecls(callback: (decl: PostCSSDeclaration) => void): void;
83
/** Walk through declarations matching a property pattern */
84
walkDecls(prop: RegExp | string, callback: (decl: PostCSSDeclaration) => void): void;
85
}
86
87
interface PostCSSDeclaration {
88
/** CSS property name */
89
prop: string;
90
/** CSS property value */
91
value: string;
92
/** Whether the declaration is marked as !important */
93
important: boolean;
94
/** Parent rule or at-rule */
95
parent: PostCSSRule | null;
96
/** Remove this declaration from its parent */
97
remove(): void;
98
}
99
```
100
101
### Supported Property Groups
102
103
The plugin processes these CSS property groups:
104
105
#### Margin Properties
106
- `margin` - Margin shorthand
107
- `margin-top`, `margin-right`, `margin-bottom`, `margin-left` - Directional margins
108
109
#### Padding Properties
110
- `padding` - Padding shorthand
111
- `padding-top`, `padding-right`, `padding-bottom`, `padding-left` - Directional padding
112
113
#### Border Properties
114
- `border` - General border shorthand (width, style, color)
115
- `border-top`, `border-right`, `border-bottom`, `border-left` - Directional borders
116
- `border-width`, `border-style`, `border-color` - Border aspect shorthands
117
- `border-top-width`, `border-right-width`, `border-bottom-width`, `border-left-width` - Directional border widths
118
- `border-top-style`, `border-right-style`, `border-bottom-style`, `border-left-style` - Directional border styles
119
- `border-top-color`, `border-right-color`, `border-bottom-color`, `border-left-color` - Directional border colors
120
- `border-spacing` - Table border spacing (also minified when appropriate)
121
122
#### Column Properties
123
- `columns` - Columns shorthand
124
- `column-width`, `column-count` - Column longhand properties
125
126
## Usage Examples
127
128
### Basic Margin Merging
129
130
Input CSS:
131
```css
132
.box {
133
margin-top: 10px;
134
margin-right: 15px;
135
margin-bottom: 10px;
136
margin-left: 15px;
137
}
138
```
139
140
Output CSS:
141
```css
142
.box {
143
margin: 10px 15px;
144
}
145
```
146
147
### Border Property Optimization
148
149
Input CSS:
150
```css
151
.card {
152
border-top-width: 2px;
153
border-right-width: 2px;
154
border-bottom-width: 2px;
155
border-left-width: 2px;
156
border-top-style: solid;
157
border-right-style: solid;
158
border-bottom-style: solid;
159
border-left-style: solid;
160
border-top-color: red;
161
border-right-color: red;
162
border-bottom-color: red;
163
border-left-color: red;
164
}
165
```
166
167
Output CSS:
168
```css
169
.card {
170
border: 2px solid red;
171
}
172
```
173
174
### Column Property Merging
175
176
Input CSS:
177
```css
178
.layout {
179
column-width: 200px;
180
column-count: 3;
181
}
182
```
183
184
Output CSS:
185
```css
186
.layout {
187
columns: 200px 3;
188
}
189
```
190
191
### Integration with PostCSS
192
193
```javascript
194
const postcss = require("postcss");
195
const mergeLonghand = require("postcss-merge-longhand");
196
const autoprefixer = require("autoprefixer");
197
198
// Use with other PostCSS plugins
199
const processor = postcss([
200
autoprefixer(),
201
mergeLonghand(),
202
// Add other optimization plugins
203
]);
204
205
processor.process(cssString, { from: undefined })
206
.then(result => {
207
console.log(result.css);
208
});
209
```
210
211
### Build Tool Integration
212
213
```javascript
214
// webpack.config.js
215
module.exports = {
216
module: {
217
rules: [
218
{
219
test: /\.css$/,
220
use: [
221
"style-loader",
222
"css-loader",
223
{
224
loader: "postcss-loader",
225
options: {
226
postcssOptions: {
227
plugins: [
228
require("postcss-merge-longhand")(),
229
]
230
}
231
}
232
}
233
]
234
}
235
]
236
}
237
};
238
```
239
240
## Optimization Behavior
241
242
The plugin performs several types of optimizations:
243
244
1. **Directional Property Merging**: Combines directional properties (top, right, bottom, left) into shorthand when values allow for compression
245
2. **Duplicate Removal**: Removes duplicate and redundant property declarations
246
3. **Value Minimization**: Shortens property values using standard CSS shorthand rules
247
4. **Precedence Handling**: Respects CSS cascade and specificity rules
248
5. **Style Hack Detection**: Preserves CSS hacks and browser-specific workarounds
249
250
## Dependencies
251
252
This plugin requires PostCSS as a peer dependency:
253
254
```json
255
{
256
"peerDependencies": {
257
"postcss": "^8.4.32"
258
}
259
}
260
```
261
262
Internal dependencies:
263
- `postcss-value-parser` - For parsing and manipulating CSS values
264
- `stylehacks` - For detecting and preserving CSS hacks
265
266
## Error Handling
267
268
The plugin gracefully handles various edge cases:
269
270
- **Invalid CSS values**: Malformed or unparseable values are preserved as-is
271
- **Mixed importance levels**: Properties with different `!important` declarations are not merged
272
- **Style hacks**: Browser-specific CSS hacks are detected and preserved
273
- **Custom properties**: CSS variables are preserved and not processed
274
- **Incomplete property sets**: Partial longhand property sets are only merged when safe
275
276
## Limitations
277
278
- Preserves CSS custom properties (CSS variables) and doesn't merge properties containing them
279
- Respects `!important` declarations and doesn't merge properties with different importance levels
280
- Maintains browser-specific style hacks and doesn't optimize them away
281
- Only merges properties within the same CSS rule - doesn't merge across different selectors
282
- Requires PostCSS version 8.4.32 or higher
283
- Does not process properties inside CSS-in-JS template literals or other non-standard CSS contexts