0
# Directives
1
2
RTLCSS provides comment-based directives for fine-grained control over CSS transformations. These directives allow developers to customize transformation behavior for specific CSS rules, declarations, or blocks.
3
4
## Capabilities
5
6
### Control Directives
7
8
Control directives modify the processing flow and behavior of RTLCSS transformations.
9
10
```javascript { .api }
11
// Ignore directive - skip RTL processing for elements
12
/* rtl:ignore */
13
14
// Block ignore directive - ignore multiple elements
15
/* rtl:begin:ignore */
16
/* rtl:end:ignore */
17
18
// Rename directive - apply string mapping to selectors
19
/* rtl:rename */
20
21
// Raw directive - insert raw CSS
22
/* rtl:raw: .custom { direction: rtl; } */
23
24
// Remove directive - remove CSS elements
25
/* rtl:remove */
26
27
// Options directive - temporarily change configuration
28
/* rtl:begin:options: {"autoRename": true} */
29
/* rtl:end:options */
30
```
31
32
### Ignore Directive
33
34
Prevents RTLCSS from processing specific CSS elements.
35
36
```javascript { .api }
37
/**
38
* Ignore directive syntax:
39
* - Single element: /* rtl:ignore * /
40
* - Block start: /* rtl:begin:ignore * /
41
* - Block end: /* rtl:end:ignore * /
42
*/
43
```
44
45
**Usage Examples:**
46
47
```css
48
/* Ignore single declaration */
49
.header {
50
float: left; /* rtl:ignore */
51
margin-right: 10px;
52
}
53
/* Output: .header { float: left; margin-left: 10px; } */
54
55
/* Ignore entire rule */
56
/* rtl:ignore */
57
.sidebar {
58
float: left;
59
margin-right: 20px;
60
}
61
/* Output: .sidebar { float: left; margin-right: 20px; } (unchanged) */
62
63
/* Block ignore multiple elements */
64
/* rtl:begin:ignore */
65
.nav-left {
66
float: left;
67
}
68
.nav-right {
69
float: right;
70
}
71
/* rtl:end:ignore */
72
/* Output: both rules remain unchanged */
73
74
/* Self-closing block ignore */
75
/* rtl:begin:ignore */
76
.component {
77
/* rtl:end:ignore */
78
text-align: left;
79
/* rtl:begin:ignore */
80
float: left;
81
}
82
/* rtl:end:ignore */
83
/* Output: only text-align is transformed */
84
```
85
86
### Rename Directive
87
88
Applies string mapping transformations to CSS selectors.
89
90
```javascript { .api }
91
/**
92
* Rename directive syntax:
93
* /* rtl:rename */
94
*/
95
```
96
97
**Usage Examples:**
98
99
```css
100
/* Apply string mapping to selector */
101
/* rtl:rename */
102
.nav-left {
103
color: blue;
104
}
105
/* Output: .nav-right { color: blue; } (if left-right string map is configured) */
106
107
/* Rename with custom string map */
108
/* With stringMap: [{ search: 'primary', replace: 'أساسي' }] */
109
/* rtl:rename */
110
.btn-primary {
111
background: blue;
112
}
113
/* Output: .btn-أساسي { background: blue; } */
114
```
115
116
### Raw Directive
117
118
Inserts raw CSS content without processing.
119
120
```javascript { .api }
121
/**
122
* Raw directive syntax:
123
* /* rtl:raw: CSS_CONTENT */
124
*/
125
```
126
127
**Usage Examples:**
128
129
```css
130
/* Insert raw RTL-specific CSS */
131
.container {
132
/* rtl:raw:
133
direction: rtl;
134
text-align: right;
135
*/
136
margin-left: 10px;
137
}
138
/* Output includes both the raw CSS and processed margin */
139
140
/* Complex raw insertion */
141
/* rtl:raw:
142
.rtl-only {
143
font-family: 'Arabic Font', sans-serif;
144
letter-spacing: 0;
145
}
146
.ltr-hidden {
147
display: none;
148
}
149
*/
150
.content {
151
text-align: left;
152
}
153
/* Raw CSS is inserted before the processed .content rule */
154
```
155
156
### Remove Directive
157
158
Removes CSS elements from RTL output.
159
160
```javascript { .api }
161
/**
162
* Remove directive syntax:
163
* /* rtl:remove */
164
*/
165
```
166
167
**Usage Examples:**
168
169
```css
170
/* Remove entire rule in RTL */
171
/* rtl:remove */
172
.ltr-only {
173
float: left;
174
text-align: left;
175
}
176
/* Output: rule is completely removed */
177
178
/* Remove specific declaration */
179
.header {
180
color: blue;
181
/* rtl:remove */
182
direction: ltr;
183
text-align: left;
184
}
185
/* Output: .header { color: blue; text-align: right; } */
186
187
/* Remove at-rule */
188
/* rtl:remove */
189
@media print {
190
.no-print { display: none; }
191
}
192
/* Output: entire @media rule is removed */
193
```
194
195
### Options Directive
196
197
Temporarily changes RTLCSS configuration options.
198
199
```javascript { .api }
200
/**
201
* Options directive syntax:
202
* /* rtl:begin:options: JSON_OPTIONS */
203
* /* rtl:end:options */
204
*
205
* Self-closing:
206
* /* rtl:options: JSON_OPTIONS */
207
*/
208
```
209
210
**Usage Examples:**
211
212
```css
213
/* Temporarily enable autoRename */
214
/* rtl:begin:options: {"autoRename": true} */
215
.nav-left {
216
float: left;
217
}
218
.nav-right {
219
float: right;
220
}
221
/* rtl:end:options */
222
/* Both selector names and properties are transformed */
223
224
/* Self-closing options for single rule */
225
/* rtl:options: {"stringMap": [{"search": "brand", "replace": "علامة"}]} */
226
.brand-logo {
227
float: left;
228
}
229
/* Output: .علامة-logo { float: right; } */
230
231
/* Disable cleaning temporarily */
232
/* rtl:begin:options: {"clean": false} */
233
.debug {
234
/* rtl:ignore */
235
float: left; /* This comment will be preserved */
236
}
237
/* rtl:end:options */
238
239
/* Multiple option changes */
240
/* rtl:begin:options: {
241
"autoRename": true,
242
"greedy": true,
243
"stringMap": [
244
{
245
"name": "temp-map",
246
"search": "custom",
247
"replace": "مخصص",
248
"priority": 50
249
}
250
]
251
} */
252
.custom-header {
253
text-align: left;
254
}
255
/* rtl:end:options */
256
```
257
258
## Value Directives
259
260
Value directives transform CSS values inline using regular expressions.
261
262
```javascript { .api }
263
/**
264
* Value directives are processed through plugin system
265
* They modify CSS property values during transformation
266
*/
267
```
268
269
**Custom Value Directive Example:**
270
271
```javascript
272
// Custom value directive plugin
273
const customValueDirective = {
274
name: 'custom-values',
275
priority: 100,
276
directives: {
277
value: [
278
{
279
name: 'flip',
280
action: (node, expr, context) => {
281
// Custom logic to flip values
282
const flipped = node.value.replace(/left/g, 'temp')
283
.replace(/right/g, 'left')
284
.replace(/temp/g, 'right');
285
node.value = flipped;
286
return true;
287
}
288
}
289
]
290
}
291
};
292
293
// Usage in CSS
294
.element {
295
/* rtl:flip */
296
text-align: left;
297
}
298
299
// Another practical example: prepend directive
300
const prependDirective = {
301
name: 'prepend-values',
302
priority: 100,
303
directives: {
304
value: [
305
{
306
name: 'prepend',
307
action: (node, expr, context) => {
308
const match = node.value.match(expr);
309
if (match && match[1]) {
310
node.value = match[1] + node.value;
311
return true;
312
}
313
return false;
314
}
315
}
316
]
317
}
318
};
319
320
// Usage in CSS with prepend directive
321
.rtl-prefix {
322
/* rtl:prepend: "rtl-" */
323
background-image: url(image.png);
324
}
325
```
326
327
## Directive Processing Order
328
329
Directives are processed in the following order:
330
331
1. **Control directives** (ignore, rename, raw, remove, options)
332
2. **Value directives** (inline transformations)
333
3. **Property processors** (CSS property transformations)
334
335
## Error Handling
336
337
RTLCSS provides warnings for directive-related issues:
338
339
```javascript { .api }
340
// Unclosed directive warning
341
/* rtl:begin:ignore */
342
.rule { float: left; }
343
// Missing /* rtl:end:ignore */ - generates warning
344
345
// Unmatched end directive
346
/* rtl:end:ignore */ // No matching begin - generates warning
347
348
// Invalid options JSON
349
/* rtl:options: {invalid json} */ // Generates error
350
351
// Blacklisted directive
352
// If 'ignore' is blacklisted, generates warning:
353
/* rtl:ignore */ // Warning: directive "rtlcss.ignore" is blacklisted
354
```
355
356
**Usage with Error Handling:**
357
358
```javascript
359
const postcss = require("postcss");
360
const rtlcss = require("rtlcss");
361
362
const processor = postcss([rtlcss()]);
363
364
processor.process(css)
365
.then(result => {
366
// Check for warnings
367
result.warnings().forEach(warn => {
368
console.warn(warn.toString());
369
});
370
371
console.log(result.css);
372
})
373
.catch(error => {
374
console.error('RTLCSS processing error:', error);
375
});
376
```