0
# PostCSS Plugin
1
2
The PostCSS Focus Within plugin transforms CSS containing `:focus-within` pseudo-selectors into compatible attribute/class selectors with optional polyfill-ready class prefixing for browsers that don't support the native selector.
3
4
## Capabilities
5
6
### Plugin Factory Function
7
8
Creates a PostCSS plugin instance that transforms `:focus-within` selectors in CSS rules.
9
10
```javascript { .api }
11
/**
12
* Creates PostCSS plugin instance for transforming :focus-within selectors
13
* @param options - Plugin configuration options
14
* @returns PostCSS plugin object with postcssPlugin property
15
*/
16
function postcssFocusWithin(options?: pluginOptions): Plugin;
17
18
interface pluginOptions {
19
/** Preserve the original notation. Default: true */
20
preserve?: boolean;
21
/** The replacement class/attribute to be used in the polyfill. Default: "[focus-within]" */
22
replaceWith?: string;
23
/** Disable the selector prefix that prevents flash of incorrectly styled content. Default: false */
24
disablePolyfillReadyClass?: boolean;
25
}
26
27
interface Plugin {
28
/** PostCSS plugin identifier */
29
postcssPlugin: string;
30
/** Plugin preparation function */
31
prepare(): PluginProcessor;
32
}
33
34
interface PluginProcessor {
35
/** PostCSS plugin identifier */
36
postcssPlugin: string;
37
/** Rule processing function */
38
Rule(rule: Rule, helpers: { result: Result }): void;
39
}
40
```
41
42
**Usage Examples:**
43
44
```javascript
45
import postcss from "postcss";
46
import postcssFocusWithin from "postcss-focus-within";
47
48
// Basic usage with default options
49
const result = await postcss([
50
postcssFocusWithin()
51
]).process(css);
52
53
// With custom options
54
const result = await postcss([
55
postcssFocusWithin({
56
preserve: false,
57
replaceWith: ".focus-within",
58
disablePolyfillReadyClass: true
59
})
60
]).process(css);
61
```
62
63
### Plugin Options
64
65
#### preserve
66
67
Controls whether the original `:focus-within` rules are preserved in the output CSS.
68
69
```javascript { .api }
70
preserve?: boolean; // Default: true
71
```
72
73
**Usage:**
74
75
```javascript
76
// Keep original rules (default)
77
postcssFocusWithin({ preserve: true });
78
79
// Remove original rules
80
postcssFocusWithin({ preserve: false });
81
```
82
83
**Example transformation with `preserve: false`:**
84
85
```css
86
/* Input */
87
.form:focus-within { border: blue; }
88
89
/* Output */
90
.form[focus-within].js-focus-within, .js-focus-within .form[focus-within] {
91
border: blue;
92
}
93
```
94
95
#### replaceWith
96
97
Defines the selector used to replace `:focus-within` in the generated fallback rules.
98
99
```javascript { .api }
100
replaceWith?: string; // Default: "[focus-within]"
101
```
102
103
**Usage:**
104
105
```javascript
106
// Use attribute selector (default)
107
postcssFocusWithin({ replaceWith: "[focus-within]" });
108
109
// Use class selector
110
postcssFocusWithin({ replaceWith: ".focus-within" });
111
112
// Use custom attribute
113
postcssFocusWithin({ replaceWith: "[data-focus-within]" });
114
```
115
116
**Example transformation with `replaceWith: ".focus-within"`:**
117
118
```css
119
/* Input */
120
.form:focus-within { border: blue; }
121
122
/* Output */
123
.form.focus-within.js-focus-within, .js-focus-within .form.focus-within {
124
border: blue;
125
}
126
.form:focus-within { border: blue; }
127
```
128
129
#### disablePolyfillReadyClass
130
131
Controls whether selectors are prefixed with the `.js-focus-within` class that indicates the polyfill is loaded and active.
132
133
```javascript { .api }
134
disablePolyfillReadyClass?: boolean; // Default: false
135
```
136
137
**Usage:**
138
139
```javascript
140
// Include polyfill-ready class (default)
141
postcssFocusWithin({ disablePolyfillReadyClass: false });
142
143
// Disable polyfill-ready class
144
postcssFocusWithin({ disablePolyfillReadyClass: true });
145
```
146
147
**Example transformation with `disablePolyfillReadyClass: true`:**
148
149
```css
150
/* Input */
151
.form:focus-within { border: blue; }
152
153
/* Output */
154
.form[focus-within] { border: blue; }
155
.form:focus-within { border: blue; }
156
```
157
158
### Plugin Static Properties
159
160
The plugin function includes a static property to identify it as a PostCSS plugin.
161
162
```javascript { .api }
163
postcssFocusWithin.postcss: true;
164
```
165
166
### Error Handling
167
168
The plugin validates the `replaceWith` option and provides warnings for invalid selectors:
169
170
```javascript
171
// Invalid selector examples that will trigger warnings:
172
postcssFocusWithin({ replaceWith: ".class > .child" }); // Contains >
173
postcssFocusWithin({ replaceWith: "[attr]:hover" }); // Contains :
174
postcssFocusWithin({ replaceWith: "#id" }); // Contains #
175
```
176
177
Invalid `replaceWith` values cause the plugin to warn and skip transformation, as such selectors cannot be applied to single elements.