PostCSS plugin that detects and removes browser-specific CSS hacks based on target browser support
npx @tessl/cli install tessl/npm-stylehacks@7.0.00
# stylehacks
1
2
stylehacks is a PostCSS plugin that detects and removes browser-specific CSS hacks from stylesheets based on target browser support. It analyzes CSS declarations, rules, and other nodes to identify outdated browser hacks (like underscore hacks for IE6) and either removes them or warns about their presence in lint mode. The library integrates with browserslist to determine which hacks are still needed based on the browsers you need to support.
3
4
## Package Information
5
6
- **Package Name**: stylehacks
7
- **Package Type**: npm
8
- **Language**: JavaScript with TypeScript definitions
9
- **Installation**: `npm install stylehacks`
10
11
## Core Imports
12
13
```javascript
14
const stylehacks = require('stylehacks');
15
```
16
17
For TypeScript or ES modules:
18
19
```typescript
20
import stylehacks from 'stylehacks';
21
```
22
23
## Basic Usage
24
25
### As a PostCSS Plugin
26
27
```javascript
28
const postcss = require('postcss');
29
const stylehacks = require('stylehacks');
30
31
// Default mode - removes detected hacks
32
postcss([stylehacks()])
33
.process(css, { from: undefined })
34
.then(result => {
35
console.log(result.css); // CSS with hacks removed
36
});
37
38
// Lint mode - only warns about hacks
39
postcss([stylehacks({ lint: true })])
40
.process(css, { from: undefined })
41
.then(result => {
42
console.log(result.messages); // Array of warnings
43
});
44
```
45
46
### Standalone Detection
47
48
```javascript
49
const postcss = require('postcss');
50
const stylehacks = require('stylehacks');
51
52
const css = 'h1 { _color: red; color: blue; }';
53
const root = postcss.parse(css);
54
55
root.walkDecls(decl => {
56
if (stylehacks.detect(decl)) {
57
console.log(`Found hack: ${decl.prop}: ${decl.value}`);
58
}
59
});
60
```
61
62
## Architecture
63
64
stylehacks is built around a modular plugin architecture that systematically detects different types of browser-specific CSS hacks:
65
66
- **Plugin System**: Uses 12 specialized detection plugins, each targeting specific hack patterns
67
- **Browser Support Integration**: Leverages browserslist to determine which hacks are still needed based on target browser support
68
- **PostCSS Integration**: Implements the standard PostCSS plugin API with prepare/OnceExit lifecycle
69
- **Selector Parsing**: Uses postcss-selector-parser for sophisticated selector-based hack detection
70
- **Lazy Evaluation**: Only instantiates and runs plugins for hacks that are no longer needed based on browser targets
71
72
The plugin walks through all CSS nodes (declarations, rules, at-rules) and applies relevant detection plugins. Each plugin can either remove hacks (default mode) or emit warnings (lint mode) when hacks are detected.
73
74
### Detection Plugins
75
76
stylehacks includes 12 specialized plugins for different hack types:
77
78
- **bodyEmpty**: `body:empty selector` hacks (Firefox 2)
79
- **htmlCombinatorCommentBody**: `html/**/selector` hacks (IE6)
80
- **htmlFirstChild**: `html:first-child selector` hacks (IE7)
81
- **important**: `!important` variants (various IE versions)
82
- **leadingStar**: `*property: value` hacks (IE5.5-7)
83
- **leadingUnderscore**: `_property: value` hacks (IE6)
84
- **mediaSlash0**: `@media \0screen` hacks (IE8-9)
85
- **mediaSlash0Slash9**: `@media \0screen\,screen\9` hacks (IE8)
86
- **mediaSlash9**: `@media screen\9` hacks (IE8)
87
- **slash9**: `property: value\9` hacks (IE6-8)
88
- **starHtml**: `* html selector` hacks (IE6)
89
- **trailingSlashComma**: `selector\,` hacks (IE6-7)
90
91
## Capabilities
92
93
### Plugin Creator Function
94
95
Creates a PostCSS plugin instance that processes CSS to detect and handle browser hacks.
96
97
```javascript { .api }
98
/**
99
* Creates a PostCSS plugin for detecting and removing CSS browser hacks
100
* @param opts - Configuration options
101
* @returns PostCSS plugin instance
102
*/
103
function stylehacks(opts?: Options): Plugin;
104
105
interface Options {
106
/** Enable lint mode - warnings only, no removal */
107
lint?: boolean;
108
/** Override browserslist configuration */
109
overrideBrowserslist?: string | string[];
110
/** Path for browserslist resolution */
111
path?: string;
112
/** Environment for browserslist */
113
env?: string;
114
/** Custom stats for browserslist */
115
stats?: any;
116
}
117
```
118
119
**Usage:**
120
121
```javascript
122
// Remove hacks (default behavior)
123
const plugin = stylehacks();
124
125
// Lint mode only
126
const lintPlugin = stylehacks({ lint: true });
127
128
// Custom browser support
129
const customPlugin = stylehacks({
130
overrideBrowserslist: ['> 1%', 'last 2 versions']
131
});
132
```
133
134
### Hack Detection Method
135
136
Standalone method to detect if a PostCSS node contains any browser hacks without processing the entire stylesheet.
137
138
```javascript { .api }
139
/**
140
* Detects if a PostCSS node contains any browser hacks
141
* @param node - PostCSS node to analyze
142
* @returns true if hack is detected, false otherwise
143
*/
144
function detect(node: Node): boolean;
145
```
146
147
**Usage:**
148
149
```javascript
150
const postcss = require('postcss');
151
const stylehacks = require('stylehacks');
152
153
const css = 'h1 { _color: red; color: blue; }';
154
const root = postcss.parse(css);
155
156
root.walkDecls(decl => {
157
const isHack = stylehacks.detect(decl);
158
if (isHack) {
159
console.log(`Hack detected: ${decl.toString()}`);
160
}
161
});
162
163
// Example output: "Hack detected: _color: red"
164
```
165
166
### PostCSS Compatibility Flag
167
168
Indicates PostCSS plugin compatibility.
169
170
```javascript { .api }
171
/** PostCSS plugin compatibility flag */
172
const postcss: true;
173
```
174
175
## Dependencies
176
177
stylehacks relies on key dependencies for its functionality:
178
179
- **browserslist**: Determines target browser support for hack relevance
180
- **postcss-selector-parser**: Enables sophisticated selector-based hack detection
181
- **PostCSS**: Core CSS processing framework (peer dependency)
182
183
For the complete list of supported browser hacks, see the [Detection Plugins](#detection-plugins) section above.
184
185
## Browser Support Detection
186
187
stylehacks uses browserslist to determine which hacks should be removed based on your target browser support:
188
189
```javascript
190
// Hacks are only removed if targeted browsers don't require them
191
const plugin = stylehacks({
192
overrideBrowserslist: [
193
'> 1%',
194
'last 2 versions',
195
'not dead'
196
]
197
});
198
```
199
200
If your browserslist doesn't include IE6, for example, all IE6-specific hacks will be removed from your CSS.
201
202
## Types
203
204
```typescript { .api }
205
interface Options {
206
/** Enable lint mode - emit warnings instead of removing hacks */
207
lint?: boolean;
208
/** Override the browserslist configuration */
209
overrideBrowserslist?: string | string[];
210
/** Path for browserslist resolution */
211
path?: string;
212
/** Environment name for browserslist */
213
env?: string;
214
/** Custom usage statistics for browserslist */
215
stats?: any;
216
}
217
218
interface Plugin {
219
/** PostCSS plugin name */
220
postcssPlugin: string;
221
/** Plugin preparation function */
222
prepare(result: Result): PluginInstance;
223
}
224
225
interface PluginInstance {
226
/** Execute after all other plugins */
227
OnceExit(root: Root): void;
228
}
229
230
/** PostCSS AST node types */
231
type Node = Declaration | Rule | AtRule | Comment | Root;
232
```