{"id":20961661,"url":"https://github.com/elchininet/postcss-rtlcss","last_synced_at":"2025-04-05T02:12:29.432Z","repository":{"id":39919959,"uuid":"254932981","full_name":"elchininet/postcss-rtlcss","owner":"elchininet","description":"PostCSS plugin to automatically build Cascading Style Sheets (CSS) with Left-To-Right (LTR) and Right-To-Left (RTL) rules using RTLCSS","archived":false,"fork":false,"pushed_at":"2024-04-14T03:44:31.000Z","size":14357,"stargazers_count":90,"open_issues_count":2,"forks_count":12,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-04-14T16:08:24.809Z","etag":null,"topics":["arabic","automatic-ltr","automatic-rtl","css","direction","hebrew","left-to-right","ltr","plugin","postcss","postcss-plugin","postcss-rtlcss","right-to-left","rtl","rtl-adaptivity","rtl-plugin","rtlcss"],"latest_commit_sha":null,"homepage":"https://elchininet.github.io/postcss-rtlcss/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/elchininet.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null},"funding":{"github":"elchininet"}},"created_at":"2020-04-11T18:46:06.000Z","updated_at":"2024-04-15T23:30:33.179Z","dependencies_parsed_at":"2024-04-15T23:29:56.621Z","dependency_job_id":"5848594b-7a2e-4145-9484-8346c4993a4e","html_url":"https://github.com/elchininet/postcss-rtlcss","commit_stats":{"total_commits":267,"total_committers":3,"mean_commits":89.0,"dds":"0.13108614232209737","last_synced_commit":"b4537f7b20538e3e12d5c054b09529c6d7beac16"},"previous_names":[],"tags_count":61,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elchininet%2Fpostcss-rtlcss","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elchininet%2Fpostcss-rtlcss/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elchininet%2Fpostcss-rtlcss/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elchininet%2Fpostcss-rtlcss/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elchininet","download_url":"https://codeload.github.com/elchininet/postcss-rtlcss/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247276189,"owners_count":20912288,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arabic","automatic-ltr","automatic-rtl","css","direction","hebrew","left-to-right","ltr","plugin","postcss","postcss-plugin","postcss-rtlcss","right-to-left","rtl","rtl-adaptivity","rtl-plugin","rtlcss"],"created_at":"2024-11-19T02:15:11.602Z","updated_at":"2025-04-05T02:12:29.410Z","avatar_url":"https://github.com/elchininet.png","language":"TypeScript","funding_links":["https://github.com/sponsors/elchininet"],"categories":[],"sub_categories":[],"readme":"# PostCSS RTLCSS\n\n[PostCSS] plugin to build Cascading Style Sheets (CSS) with Left-To-Right (LTR) and Right-To-Left (RTL) rules using [RTLCSS]. RTLCSS allows one to flip an entire CSS file with the intention of using the original CSS for one direction and the new generated one for the other. What PostCSS RTLCSS does, is to create a single CSS file with both directions or to create a minimal CSS file only with the flipped rules with the intention of overriding the main one.\n\n[![Deployment Status](https://github.com/elchininet/postcss-rtlcss/actions/workflows/deploy.yaml/badge.svg)](https://github.com/elchininet/postcss-rtlcss/actions/workflows/deploy.yaml)\n[![Test](https://github.com/elchininet/postcss-rtlcss/actions/workflows/test.yaml/badge.svg)](https://github.com/elchininet/postcss-rtlcss/actions/workflows/test.yaml)\n[![Coverage Status](https://coveralls.io/repos/github/elchininet/postcss-rtlcss/badge.svg?branch=master)](https://coveralls.io/github/elchininet/postcss-rtlcss?branch=master)\n[![npm version](https://badge.fury.io/js/postcss-rtlcss.svg)](https://badge.fury.io/js/postcss-rtlcss)\n[![downloads](https://img.shields.io/npm/dw/postcss-rtlcss)](https://www.npmjs.com/package/postcss-rtlcss)\n\n\n[PostCSS]: https://github.com/postcss/postcss\n[RTLCSS]: https://rtlcss.com/\n\nPlayground Demo\n---\n\nhttps://elchininet.github.io/postcss-rtlcss/\n\n\nInstall\n---\n\n#### npm\n\n```bash\nnpm install postcss-rtlcss --save-dev\n```\n\n#### pnpm\n\n```bash\npnpm add -D postcss-rtlcss\n```\n\n#### yarn\n\n```bash\nyarn add postcss-rtlcss -D\n```\n\nBasic usage\n---\n\n#### Usage with commonJS\n\n```javascript\nconst postcss = require('postcss');\nconst postcssRTLCSS = require('postcss-rtlcss');\nconst { Mode, Source } = require('postcss-rtlcss/options');\n\nconst options = { ... available options ... };\nconst result = postcss([\n    postcssRTLCSS(options)\n]).process(cssInput);\n\nconst rtlCSS = result.css;\n```\n\n#### Usage with ES6 modules\n\n```javascript\nimport postcss from 'postcss';\nimport postcssRTLCSS from 'postcss-rtlcss';\nimport { Mode, Source } from 'postcss-rtlcss/options';\n\nconst options = { ... available options ... };\nconst result = postcss([\n    postcssRTLCSS(options)\n]).process(cssInput);\n\nconst rtlCSS = result.css;\n```\n\n#### Usage in Webpack with postcss-loader\n\n```javascript\nrules: [\n    {\n        test: /\\.css$/,\n        use: [\n            { loader: 'style-loader' },\n            { loader: 'css-loader' },\n            {\n                loader: 'postcss-loader',\n                options: {\n                    postcssOptions: {\n                        plugins: [\n                            postcssRTLCSS(options)\n                        ]\n                    }\n                }\n            }\n        ]\n    }\n]\n```\n\nExamples\n---\n\n#### Input\n\n```css\n.test1, .test2 {\n    background-color: #FFF;\n    background-position: 10px 20px;\n    border-radius: 0 2px 0 8px;\n    color: #666;\n    padding-right: 20px;\n    text-align: left;\n    transform: translate(-50%, 50%);\n    width: 100%;\n}\n\n.test3 {\n    direction: ltr;\n    margin: 1px 2px 3px;\n    padding: 10px 20px;\n    text-align: center;\n}\n```\n\n#### Output using the combined mode (default and recommended)\n\nThis is the recommended method, it will generate more CSS code because each direction will have their specific prefixed rules but it is the safest option.\n\n```css\n.test1, .test2 {\n    background-color: #FFF;\n    background-position: 10px 20px;\n    color: #666;\n    width: 100%;\n}\n\n[dir=\"ltr\"] .test1, [dir=\"ltr\"] .test2 {\n    border-radius: 0 2px 0 8px;\n    padding-right: 20px;\n    text-align: left;\n    transform: translate(-50%, 50%);\n}\n\n[dir=\"rtl\"] .test1, [dir=\"rtl\"] .test2 {\n    border-radius: 2px 0 8px 0;\n    padding-left: 20px;\n    text-align: right;\n    transform: translate(50%, 50%);\n}\n\n.test3 {\n    margin: 1px 2px 3px;\n    padding: 10px 20px;\n    text-align: center;\n}\n\n[dir=\"ltr\"] .test3 {\n    direction: ltr;\n}\n\n[dir=\"rtl\"] .test3 {\n    direction: rtl;\n}\n```\n\n#### Output using the override mode\n\n\u003e[!IMPORTANT]\n\u003eThis method is not recommended, [check below why](#disadvantages-of-the-two-methods-to-override)\n\nThis is one of the alternative methods to override. It will generate less code because it lets the main rule intact most of the time and generates shorter specific rules to override the properties that are affected by the direction of the text.\n\n```css\n.test1, .test2 {\n    background-color: #FFF;\n    background-position: 10px 20px;\n    border-radius: 0 2px 0 8px;\n    color: #666;\n    padding-right: 20px;\n    text-align: left;\n    transform: translate(-50%, 50%);\n    width: 100%;\n}\n\n[dir=\"rtl\"] .test1, [dir=\"rtl\"] .test2 {\n    border-radius: 2px 0 8px 0;\n    padding-right: 0;\n    padding-left: 20px;\n    text-align: right;\n    transform: translate(50%, 50%);\n}\n\n.test3 {\n    direction: ltr;\n    margin: 1px 2px 3px;\n    padding: 10px 20px;\n    text-align: center;\n}\n\n[dir=\"rtl\"] .test3 {\n    direction: rtl;\n}\n```\n\n#### Output using the diff mode\n\n\u003e[!IMPORTANT]\n\u003eThis method is not recommended, [check below why](#disadvantages-of-the-two-methods-to-override)\n\nThis is the second alternative method to override. It generates the minimum amount of code because it only outputs the rules that have been flipped and without prefixing them. The intention of this method is to generate a separate stylesheet file that will be loaded on top of the original one to override those rules that need to be flipped in certain direction.\n\n```css\n.test1, .test2 {\n    border-radius: 2px 0 8px 0;\n    padding-right: 0;\n    padding-left: 20px;\n    text-align: right;\n    transform: translate(50%, 50%);\n}\n\n.test3 {\n    direction: rtl;\n}\n```\n\n#### Disadvantages of the two methods to override\n\n1. Some directives as `/*rtl:freeze*/`, `/*rtl:begin:freeze*/` and `/*rtl:end:freeze*/` do not work with these methods\n2. They can override a property that is coming from another class if multiple classes are used at the same time. Take a look at the next `HTML` and `CSS` codes:\n\n```html\n\u003cdiv class=\"test1 test2\"\u003e\n    This is an example\n\u003c/div\u003e    \n```\n\n```css\n.test1 {\n    background: #666;\n    color: #FFF;\n    padding: 20px;\n}\n\n.test2 {\n    padding-right: 10px;\n}\n```\n\nUsing the `combined` method, the generated code will be the next one:\n\n```css\n.test1 {\n    background: #666;\n    color: #FFF;\n    padding: 20px;\n}\n\n[dir=\"ltr\"] .test2 {\n    padding-right: 10px;\n}\n\n[dir=\"rtl\"] .test2 {\n    padding-left: 10px;\n}\n```\n\nSo, the `div` will have a padding of `20px 10px 20px 20px` in `LTR` and `20px 20px 20px 10px` in `RTL`. Everything will work as expected here.\n\nHowever, using the `override` method the generated code will be the next one:\n\n```css\n.test1 {\n    background: #666;\n    color: #FFF;\n    padding: 20px;\n}\n\n.test2 {\n    padding-right: 10px;\n}\n\n[dir=\"rtl\"] .test2 {\n    padding-right: 0;\n    padding-left: 10px;\n}\n```\n\nAnd using the `diff` method the generated code will be the next one:\n\n```css\n.test2 {\n    padding-right: 0;\n    padding-left: 10px;\n}\n```\n\nNow the `div` has a padding of `20px 10px 20px 20px` in `LTR` and `20px 0 20px 10px` in `RTL`, because when the class `test2` is overriden, it is not taken into account that it could be used with `test1` having the same properties. The workaround, in this case, is to provide the property that has been inherited:\n\n```css\n.test1 {\n    background: #666;\n    color: #FFF;\n    padding: 20px;\n}\n\n.test2 {\n    padding-left: 20px;\n    padding-right: 10px;\n}\n```\n\nSo, using the `override` method the generated code will be:\n\n```css\n.test1 {\n    background: #666;\n    color: #FFF;\n    padding: 20px;\n}\n\n.test2 {\n    padding-left: 20px;\n    padding-right: 10px;\n}\n\n[dir=\"rtl\"] .test2 {\n    padding-right: 20px;\n    padding-left: 10px;\n}\n```\n\nAnd using the `diff` method the generated code will be:\n\n```css\n.test2 {\n    padding-right: 20px;\n    padding-left: 10px;\n}\n```\n\nPlugin Options\n---\n\nAll the options are optional, and a default value will be used if any of them is omitted or the type or format of them is wrong\n\n| Option                                                  | Type                      | Default         | Description                                                  |\n| ------------------------------------------------------- | ------------------------- | --------------- | ------------------------------------------------------------ |\n| [mode](#mode)                                           | `Mode (string)`           | `Mode.combined` | Mode of generating the final CSS rules                       |\n| [ltrPrefix](#ltrprefix-and-rtlprefix)                   | `string` or `string[]`    | `[dir=\"ltr\"]`   | Prefix to use in the left-to-right CSS rules                 |\n| [rtlPrefix](#ltrprefix-and-rtlprefix)                   | `string` or `string[]`    | `[dir=\"rtl\"]`   | Prefix to use in the right-to-left CSS rules                 |\n| [bothPrefix](#bothprefix)                               | `string` or `string[]`    | `[dir]`         | Prefix to create a new rule that affects both directions when the specificity of the ltr or rtl rules will override its declarations |\n| [prefixSelectorTransformer](#prefixselectortransformer) | `function`                | `null`          | Transform function to have more control over the selectors prefixing logic |\n| [safeBothPrefix](#safebothprefix)                       | `boolean`                 | `false`         | Add the `bothPrefix` to those declarations that can be affected by the direction to avoid them being overridden by specificity |\n| [ignorePrefixedRules](#ignoreprefixedrules)             | `boolean`                 | `true`          | Ignores rules that have been prefixed with some of the prefixes contained in `ltrPrefix`, `rtlPrefix`, or `bothPrefix` |\n| [source](#source)                                       | `Source (string)`         | `Source.ltr`    | The direction from which the final CSS will be generated     |\n| [processUrls](#processurls)                             | `boolean`                 | `false`         | Change the strings in URLs using the string map              |\n| [processRuleNames](#processrulenames)                   | `boolean`                 | `false`         | Swap two rules containing no directional properties if they match any entry in `stringMap` when the direction changes |\n| [processKeyFrames](#processkeyframes)                   | `boolean`                 | `false`         | Flip keyframe animations                                     |\n| [processEnv](#processenv)                               | `boolean`                 | `true`          | When processEnv is false, it prevents flipping agent-defined environment variables (`safe-area-inset-left` and `safe-area-inset-right`) |\n| [useCalc](#usecalc)                                     | `boolean`                 | `false`         | Flips `background-position-x` and `transform-origin` properties if they are expressed in length units using [calc](https://developer.mozilla.org/en-US/docs/Web/CSS/calc) |\n| [stringMap](#stringmap)                                 | `PluginStringMap[]`       | [Check below](#stringmap) | An array of strings maps that will be used to make the replacements of the declarations' URLs and to match the names of the rules if `processRuleNames` is `true` |\n| [greedy](#greedy)                                       | `boolean`                 | `false`         | When greedy is `true`, the matches of `stringMap` will not take into account word boundaries |\n| [aliases](#aliases)                                     | `Record\u003cstring, string\u003e`  | `{}`            | A strings map to treat some declarations as others           |\n| [processDeclarationPlugins](#processdeclarationplugins) | `DeclarationPlugin[]`     | `[]`            | Plugins applied when processing CSS declarations             |\n\n---\n\n## mode\n\nThe mode option has been explained in the [Output using the combined mode](#output-using-the-combined-mode-default), the [Output using the override mode](#output-using-the-override-mode), and the [Output using the diff mode](#output-using-the-diff-mode) sections. To avoid using magic strings, the package exposes an object with these values, but it is possible to use strings values anyway:\n\n```javascript\nimport postcss from 'postcss';\nimport postcssRTLCSS from 'postcss-rtlcss';\nimport { Mode } from 'postcss-rtlcss/options';\n\nconst input = '... css code ...';\nconst optionsCombined = { mode: Mode.combined }; // This is the default value\nconst optionsOverride = { mode: Mode.override };\nconst optionsDiff = { mode: Mode.diff };\n\nconst outputCombined = postcss([\n    postcssRTLCSS(optionsCombined)\n]).process(input);\n\nconst outputOverride = postcss([\n    postcssRTLCSS(optionsOverride)\n]).process(input);\n\nconst outputDiff = postcss([\n    postcssRTLCSS(optionsDiff)\n]).process(input);\n```\n\n---\n\n## ltrPrefix and rtlPrefix\n\nThese two options manage the prefix strings for each direction. They can be strings or arrays of strings:\n\n##### input\n\n```css\n.test1, .test2 {\n    left: 10px;\n}\n\n.test3,\n.test4 {\n    text-align: left;\n}\n```\n\n##### Using strings\n\n```javascript\nconst options = {\n    ltrPrefix: '.ltr',\n    rtlPrefix: '.rtl'\n};\n```\n\n##### output\n\n```css\n.ltr .test1, .ltr .test2 {\n    left: 10px;\n}\n\n.rtl .test1, .rtl .test2 {\n    right: 10px;\n}\n\n.ltr .test3,\n.ltr .test4 {\n    text-align: left;\n}\n\n.rtl .test3,\n.rtl .test4 {\n    text-align: right;\n}\n```\n\n##### Using arrays of strings\n\n```javascript\nconst options = {\n    ltrPrefix: ['[dir=\"ltr\"]', '.ltr'],\n    rtlPrefix: ['[dir=\"rtl\"]', '.rtl']\n};\n```\n\n##### output\n\n```css\n[dir=\"ltr\"] .test1, .ltr .test1, [dir=\"ltr\"] .test2, .ltr .test2 {\n    left: 10px;\n}\n\n[dir=\"rtl\"] .test1, .rtl .test1, [dir=\"rtl\"] .test2, .rtl .test2 {\n    right: 10px;\n}\n\n[dir=\"ltr\"] .test3,\n.ltr .test3,\n[dir=\"ltr\"] .test4,\n.ltr .test4 {\n    text-align: left;\n}\n\n[dir=\"rtl\"] .test3,\n.rtl .test3,\n[dir=\"rtl\"] .test4,\n.rtl .test4 {\n    text-align: right;\n}\n```\n\n---\n\n## bothPrefix\n\nThis prefix will be used in some specific cases in which a ltr or rtl rule will override declarations located in the main rule due to [specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity). Consider the next example using the option `processUrls` as `true`:\n\n```css\n.test1 {\n    background: url('icons/ltr/arrow.png');\n    background-size: 10px 20px;\n    width: 10px;\n}\n```\n\nThe generated CSS would be:\n\n```css\n.test1 {\n    background-size: 10px 20px;\n    width: 10px;\n}\n\n[dir=\"ltr\"] .test1 {\n    background: url('icons/ltr/arrow.png');\n}\n\n[dir=\"rtl\"] .test1 {\n    background: url('icons/rtl/arrow.png');\n}\n```\n\nIn the previous case, the `background-size` property has been overridden by the `background` one. Even if we change the order of the rules, the last ones have a higher specificity, so they will rule over the first one.\n\nTo solve this, another rule will be created at the end using the `bothPrefix` parameter:\n\n```css\n.test1 {\n    width: 10px;\n}\n\n[dir=\"ltr\"] .test1 {\n    background: url('icons/ltr/arrow.png');\n}\n\n[dir=\"rtl\"] .test1 {\n    background: url('icons/rtl/arrow.png');\n}\n\n[dir] {\n    background-size: 10px 20px;\n}\n```\n\nAnd no matter the direction, the `background-size` property is respected.\n\n---\n\n## prefixSelectorTransformer\n\nThis function will be used to transform the selectors and prefixing them at our will. The first parameter will be the prefix that will be used and the second the current selector:\n\n\u003e[!NOTE]\n\u003e* If the function doesn‘t return a string, the default prefixing logic will be used.\n\u003e* If this function is used, be aware that rules using `html`, `:root` or `::view-transition` will follow the custom prefixing logic. You should cover these cases.\n\n##### input\n\n```css\n.test1 {\n    left: 10px;\n    padding-right: 5px;\n    padding-inline-end: 20px;\n}\n```\n\nIf the `prefixSelectorTransformer` is not sent (default):\n\n##### output \n\n```css\n[dir=\"ltr\"] .test1 {\n    left: 10px;\n    padding-right: 5px;\n}\n\n[dir=\"rtl\"] .test1 {\n    right: 10px;\n    padding-left: 5px;\n}\n\n[dir] .test1 {\n    padding-inline-end: 20px;\n}\n```\n\nSetting a `prefixSelectorTransformer` function\n\n```javascript\nconst options = {\n    prefixSelectorTransformer: function (prefix, selector) {\n        if (prefix === '[dir]') {\n            return `.container \u003e ${prefix} \u003e ${selector}`;\n        }\n        return `${selector}${prefix}`;\n    }\n};\n```\n\n##### output \n\n```css\n.test1[dir=\"ltr\"] {\n    left: 10px;\n    padding-right: 5px;\n}\n\n.test1[dir=\"rtl\"] {\n    right: 10px;\n    padding-left: 5px;\n}\n\n.container \u003e [dir] \u003e .test1 {\n    padding-inline-end: 20px;\n}\n```\n\n---\n\n## safeBothPrefix\n\nThis option will add the `boxPrefix` option to those declarations that can be flipped, no matter if they are not overridden in the same rule. This avoids them being overridden by [specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity) of other flipped declarations contained in other rules. For example, let's consider that we have a `div` element with the next rules:\n\n```html\n\u003cdiv class=\"test1 test2\"\u003e\n    This is an example\n\u003c/div\u003e \n```\n\n```css\n.test1 {\n    color: #FFF;\n    padding: 4px 10px 4px 20px;\n    width: 100%;\n}\n\n.test2 {\n    padding: 0;\n}\n```\n\nThe expecting result is that the `padding` of the element becomes `0` as it has been reset by `test2`. With `safeBothPrefix` in `false`, the generated CSS will be:\n\n```css\n.test1 {\n    color: #FFF;\n    width: 100%;\n}\n\n[dir=\"ltr\"] .test1 {\n    padding: 4px 10px 4px 20px;\n}\n\n[dir=\"rtl\"] .test1 {\n    padding: 4px 20px 4px 10px;\n}\n\n.test2 {\n    padding: 0;\n}\n```\n\nThe result is that the `padding` properties of `test1` have more specificity than the same property in `tes2`, so it is not reset if both rules are applied at the same time. Let's check the result if `safeBothPrefix` is `true`: \n\n```css\n.test1 {\n    color: #FFF;\n    width: 100%;\n}\n\n[dir=\"ltr\"] .test1 {\n    padding: 4px 10px 4px 20px;\n}\n\n[dir=\"rtl\"] .test1 {\n    padding: 4px 20px 4px 10px;\n}\n\n[dir] .test2 {\n    padding: 0;\n}\n```\n\nAs `test2` has the same level of specificity as `test1`, now the result is that the `padding` is reset if both rules are used at the same time.\n\n---\n\n## ignorePrefixedRules\n\nThis option is to ignore the rules that have been prefixed with one of the prefixes contained in `ltrPrefix`, `rtlPrefix`, or `bothPrefix`:\n\n##### input\n\n```css\n[dir=\"ltr\"] test {\n    left: 10px;\n}\n\n[dir=\"rtl\"] test {\n    right: 10px;\n}\n```\n\n##### ignorePrefixedRules true\n\n```javascript\nconst options = { ignorePrefixedRules: true }; // This is the default value\n```\n\n##### output\n\n```css\n[dir=\"ltr\"] test {\n    left: 10px;\n}\n\n[dir=\"rtl\"] test {\n    right: 10px;\n}\n```\n\n##### ignorePrefixedRules false\n\n```javascript\nconst options = { ignorePrefixedRules: false };\n```\n\n##### output\n\n```css\n[dir=\"ltr\"] [dir=\"ltr\"] test {\n    left: 10px;\n}\n\n[dir=\"rtl\"] [dir=\"ltr\"] test {\n    right: 10px;\n}\n\n[dir=\"ltr\"] [dir=\"rtl\"] test {\n    right: 10px;\n}\n\n[dir=\"rtl\"] [dir=\"rtl\"] test {\n    left: 10px;\n}\n```\n\n---\n\n## source\n\nThis option manages if the conversion will be from `LTR` to `RTL` or vice versa.\n\n##### input\n\n```css\n.test1, .test2 {\n    left: 10px;\n}\n```\n\n##### Using Source.ltr in combined mode\n\n```javascript\nimport { Mode, Source } from 'postcss-rtlcss/options';\n\nconst options = {\n    mode: Mode.combined,\n    source: Source.ltr // This is the default value\n};\n```\n\n##### output\n\n```css\n[dir=\"ltr\"] .test1, [dir=\"ltr\"] .test2 {\n    left: 10px;\n}\n\n[dir=\"rtl\"] .test1, [dir=\"rtl\"] .test2 {\n    right: 10px;\n}\n```\n\n##### Using Source.rtl in override mode\n\n```javascript\nimport { Mode, Source } from 'postcss-rtlcss/options';\n\nconst options = {\n    mode: Mode.override,\n    source: Source.rtl\n};\n```\n\n##### output\n\n```css\n.test1, .test2 {\n    left: 10px;\n}\n\n[dir=\"ltr\"] .test1, [dir=\"ltr\"] .test2 {\n    left: auto;\n    right: 10px;\n}\n```\n\n---\n\n## processUrls\n\nThis options manages if the strings of the URLs should be flipped taken into account the string map:\n\n##### input\n\n```css\n.test1, .test2 {\n    background-image: url(\"./folder/subfolder/icons/ltr/chevron-left.png\");\n    left: 10px;\n}\n```\n\n##### processUrls false\n\n```javascript\nconst options = { processUrls: false }; // This is the default value\n```\n\n##### output\n\n```css\n.test1, .test2 {\n    background-image: url(\"./folder/subfolder/icons/ltr/chevron-left.png\");\n}\n\n[dir=\"ltr\"] .test1, [dir=\"ltr\"] .test2 {\n    left: 10px;\n}\n\n[dir=\"rtl\"] .test1, [dir=\"rtl\"] .test2 {\n    right: 10px;\n}\n```\n\n##### processUrls true\n\n```javascript\nconst options = { processUrls: true };\n```\n\n##### output\n\n```css\n[dir=\"ltr\"] .test1, [dir=\"ltr\"] .test2 {\n    background-image: url(\"./folder/subfolder/icons/ltr/chevron-left.png\");\n    left: 10px;\n}\n\n[dir=\"rtl\"] .test1, [dir=\"rtl\"] .test2 {\n    background-image: url(\"./folder/subfolder/icons/rtl/chevron-right.png\");\n    right: 10px;\n}\n```\n\n---\n\n## processRuleNames\n\nIf it is `true`, it swaps two rules containing no directional properties if they match any entry in `stringMap` when the direction changes\n\n\u003e[!IMPORTANT]\n\u003eThis option will not prefix those rules that have been processed already because they had directional properties.\n\n##### input\n\n```css\n.test1-ltr {\n    color: #FFF;\n}\n\n.test2-left::before {\n    content: \"\\f007\";\n}\n\n.test2-right::before {\n    content: \"\\f010\";\n}\n```\n\n##### processRuleNames true\n\n```javascript\nconst options = {\n    processRuleNames: true\n};\n```\n\n##### output\n\n```css\n/* This selector will not be processed because it doesn't have a counterpart */\n.test1-ltr {\n    color: #FFF;\n}\n\n[dir=\"ltr\"] .test2-left::before {\n    content: \"\\f007\";\n}\n\n[dir=\"rtl\"] .test2-left::before {\n    content: \"\\f010\";\n}\n\n[dir=\"ltr\"] .test2-right::before {\n    content: \"\\f010\";\n}\n\n[dir=\"rtl\"] .test2-right::before {\n    content: \"\\f007\";\n}\n```\n\n---\n\n## processKeyFrames\n\nThis option manages if the @keyframes animation rules should be flipped:\n\n##### input\n\n```css\n.test1 {\n    animation: 5s flip 1s ease-in-out;\n    color: #FFF;\n}\n\n@keyframes flip {\n    from {\n        transform: translateX(100px);\n    }\n    to {\n        transform: translateX(0);\n    }\n}\n```\n\n##### processKeyFrames false\n\n```javascript\nconst options = { processKeyFrames: false }; // This is the default value\n```\n\n##### output\n\n```css\n.test1 {\n    animation: 5s flip 1s ease-in-out;\n    color: #FFF;\n}\n\n@keyframes flip {\n    from {\n        transform: translateX(100px);\n    }\n    to {\n        transform: translateX(0);\n    }\n}\n```\n\n##### processKeyFrames true\n\n```javascript\nconst options = { processKeyFrames: true };\n```\n\n##### output\n\n```css\n.test1 {\n    color: #FFF;\n}\n\n[dir=\"ltr\"] .test1 {\n    animation: 5s flip-ltr 1s ease-in-out;\n}\n\n[dir=\"rtl\"] .test1 {\n    animation: 5s flip-rtl 1s ease-in-out;\n}\n\n@keyframes flip-ltr {\n    from {\n        transform: translateX(100px);\n    }\n    to {\n        transform: translateX(0);\n    }\n}\n\n@keyframes flip-rtl {\n    from {\n        transform: translateX(-100px);\n    }\n    to {\n        transform: translateX(0);\n    }\n}\n```\n\n---\n\n## processEnv\n\nThis options manages if the agent-defined environment variables should be flipped:\n\n##### input\n\n```css\nbody {\n    padding:\n        env(safe-area-inset-top, 10px)\n        env(safe-area-inset-right, 20px)\n        env(safe-area-inset-bottom, 30px)\n        env(safe-area-inset-left, 40px)\n    ;\n}\n\n.test1 {\n    margin-right: env(safe-area-inset-right, 10px);\n    margin-left: env(safe-area-inset-left, 20px);\n}\n```\n\n##### processEnv true\n\n```javascript\nconst options = { processEnv: true }; // This is the default value\n```\n\n##### output\n\n```css\n[dir=\\\\\"ltr\\\\\"] body {\n    padding:\n        env(safe-area-inset-top, 10px)\n        env(safe-area-inset-right, 20px)\n        env(safe-area-inset-bottom, 30px)\n        env(safe-area-inset-left, 40px)\n    ;\n}\n\n[dir=\\\\\"rtl\\\\\"] body {\n    padding:\n        env(safe-area-inset-top, 10px)\n        env(safe-area-inset-right, 40px)\n        env(safe-area-inset-bottom, 30px)\n        env(safe-area-inset-left, 20px);\n}\n\n[dir=\\\\\"ltr\\\\\"] .test1 {\n    margin-right: env(safe-area-inset-right, 10px);\n    margin-left: env(safe-area-inset-left, 20px);\n}\n\n[dir=\\\\\"rtl\\\\\"] .test1 {\n    margin-left: env(safe-area-inset-left, 10px);\n    margin-right: env(safe-area-inset-right, 20px);\n}\n```\n\n##### processEnv false\n\n```javascript\nconst options = { processEnv: false };\n```\n\n##### output\n\n```css\n[dir=\\\\\"ltr\\\\\"] body {\n    padding:\n        env(safe-area-inset-top, 10px)\n        env(safe-area-inset-right, 20px)\n        env(safe-area-inset-bottom, 30px)\n        env(safe-area-inset-left, 40px)\n    ;\n}\n\n[dir=\\\\\"rtl\\\\\"] body {\n    padding:\n        env(safe-area-inset-top, 10px)\n        env(safe-area-inset-left, 40px)\n        env(safe-area-inset-bottom, 30px)\n        env(safe-area-inset-right, 20px);\n}\n\n[dir=\\\\\"ltr\\\\\"] .test1 {\n    margin-right: env(safe-area-inset-right, 10px);\n    margin-left: env(safe-area-inset-left, 20px);\n}\n\n[dir=\\\\\"rtl\\\\\"] .test1 {\n    margin-left: env(safe-area-inset-right, 10px);\n    margin-right: env(safe-area-inset-left, 20px);\n}\n```\n\n---\n\n## useCalc\n\nWhen this option is enabled, it flips `background-position-x` and `transform-origin` properties if they are expressed in length units using [calc](https://developer.mozilla.org/en-US/docs/Web/CSS/calc):\n\n##### input\n\n```css\n.test {\n    background-image: url(\"./folder/subfolder/icons/ltr/chevron-left.png\");\n    background-position-x: 5px;\n    left: 10px;\n    transform-origin: 10px 20px;\n    transform: scale(0.5, 0.5);\n}\n```\n\n##### useCalc false\n\n```javascript\nconst options = { useCalc: false }; // This is the default value\n```\n\n##### output\n\n```css\n.test {\n    background-image: url(\"./folder/subfolder/icons/ltr/chevron-left.png\");\n    background-position-x: 5px;\n    transform-origin: 10px 20px;\n    transform: scale(0.5, 0.5);\n}\n\n[dir=\"ltr\"] .test {\n    left: 10px;\n}\n\n[dir=\"rtl\"] .test {\n    right: 10px;\n}\n```\n\n##### useCalc true\n\n```javascript\nconst options = { useCalc: true };\n```\n\n##### output\n\n```css\n.test {\n    background-image: url(\"./folder/subfolder/icons/ltr/chevron-left.png\");\n    transform: scale(0.5, 0.5);\n}\n\n[dir=\"ltr\"] .test {\n    background-position-x: 5px;\n    left: 10px;\n    transform-origin: 10px 20px;\n}\n\n[dir=\"rtl\"] .test {\n    background-position-x: calc(100% - 5px);\n    right: 10px;\n    transform-origin: calc(100% - 10px) 20px;\n}\n```\n\n---\n\n## stringMap\n\nAn array of strings maps that will be used to make the replacements of the declarations' URLs and to match rules selectors names if the `processRuleNames` option is `true`. The name parameter is optional, but if you want to override any of the default string maps, just add your own using the same name.\n\n```javascript\n// This is the default string map object\nconst options = {\n    stringMap: [\n        {\n            name: 'left-right',\n            search : ['left', 'Left', 'LEFT'],\n            replace : ['right', 'Right', 'RIGHT']\n        },\n        {\n            name: 'ltr-rtl',\n            search  : ['ltr', 'Ltr', 'LTR'],\n            replace : ['rtl', 'Rtl', 'RTL'],\n        }\n    ]\n};\n```\n\n---\n\n## greedy\n\nWhen `greedy` is `true`, the matches of the `stringMap` will not take into account word boundaries.\n\n##### input\n\n```css\n.test1 {\n    background: url(\"icon-left.png\");\n}\n\n.test2 {\n    background: url(\"icon-ultra.png\");\n}\n```\n\n##### greedy false\n\n```javascript\nconst options = {\n    processUrls: true,\n    greedy: false // This is the default value\n};\n```\n\n##### output\n\n```css\n[dir=\"ltr\"] .test1 {\n    background: url(\"icon-left.png\");\n}\n\n[dir=\"rtl\"] .test1 {\n    background: url(\"icon-right.png\");\n}\n\n.test2 {\n    background: url(\"icon-ultra.png\");\n}\n```\n\n##### greedy true\n\n```javascript\nconst options = {\n    processUrls: true,\n    greedy: true\n};\n```\n\n##### output\n\n```css\n[dir=\"ltr\"] .test1 {\n    background: url(\"icon-left.png\");\n}\n\n[dir=\"rtl\"] .test1 {\n    background: url(\"icon-right.png\");\n}\n\n[dir=\"ltr\"] .test2 {\n    background: url(\"icon-ultra.png\");\n}\n\n[dir=\"rtl\"] .test2 {\n    background: url(\"icon-urtla.png\");\n}\n```\n\n---\n\n## aliases\n\nThis property consists of a string map to treat some declarations as others, very useful to flip the values of [CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties).\n\n##### input\n\n```css\n:root {\n    --my-padding: 1rem 1rem 1.5rem 1.5rem;\n}\n\n.test {\n    padding: var(--my-padding);\n}\n```\n\n##### No aliases string map (default)\n\n##### output\n\n```css\n:root {\n    --my-padding: 1rem 1rem 1.5rem 1.5rem;\n}\n\n.test {\n    padding: var(--my-padding);\n}\n```\n\n##### Set an aliases string map\n\n```javascript\nconst options = {\n    aliases: {\n        '--my-padding': 'padding'\n    }\n};\n```\n\n##### output\n\n```css\n[dir=\"ltr\"]:root {\n    --my-padding: 1rem 1rem 1.5rem 1.5rem;\n}\n\n[dir=\"rtl\"]:root {\n    --my-padding: 1rem 1.5rem 1.5rem 1rem;\n}\n\n.test {\n    padding: var(--my-padding);\n}\n```\n\n---\n\n## processDeclarationPlugins\n\nThe intention of the processDeclarationPlugins option is to process the declarations to extend or override RTLCSS functionality. For example, we can avoid automatically flipping of `background-potion`.\n\n##### input\n\n```css\n.test {\n    background-position: 0 100%;\n}\n```\n\n##### Convert `0` to `100%` (default)\n\n##### output\n\n```css\n.test {\n    background-position: 100% 100%;\n}\n```\n\n##### Set a plugin to avoid flipping\n\n```javascript\nconst options = {\n\tprocessDeclarationPlugins: [\n        {\n            name: 'avoid-flipping-background',\n            priority: 99, // above the core RTLCSS plugin which has a priority value of 100\n            processors: [{\n                expr: /(background|object)(-position(-x)?|-image)?$/i,\n                action: (prop, value) =\u003e ({prop, value})}\n            ]\n        }\n    ]\n};\n```\n\n##### output\n\n```css\n.test {\n    background-position: 0 100%;\n}\n```\n\n---\n\nControl Directives\n---\n\nControl directives are placed between rules or declarations. They can target a single node or a set of nodes.\n\n\u003e[!IMPORTANT]\n\u003eBlock directives (the ones that start with `begin` and end with `end`) should be placed outside rules to apply the directive to multiple rules or inside a rule to apply the directive to multiple declarations. You should not place the begin of a directive outside a rule and the end inside one (or vice versa) or you will get undesired results.\n\n| Directive                                                      | Description                                             |\n| -------------------------------------------------------------- | ------------------------------------------------------- |\n| [/\\*rtl:ignore\\*/](#rtlignore)                                 | Ignores processing of the following rule or declaration |\n| [/\\*rtl:begin:ignore\\*/](#rtlbeginignore-and-rtlendignore)     | Starts an ignoring block                                |\n| [/\\*rtl:end:ignore\\*/](#rtlbeginignore-and-rtlendignore)       | Ends an ignoring block                                  |\n| [/\\*rtl:freeze\\*/](#rtlfreeze)                                 | Freezes the rule or declaration in the current direction but does nothing with the counterpart direction if there are flippable declarations |\n| [/\\*rtl:begin:freeze\\*/](#rtlbeginfreeze-and-rtlendfreeze)     | Starts a freeze block                                   |\n| [/\\*rtl:end:freeze\\*/](#rtlbeginfreeze-and-rtlendfreeze)       | Ends a freeze block                                     |\n| [/\\*rtl:urls\\*/](#rtlurls)                                     | This directive set the `processUrls` option to `true` in the next declaration or in the declarations of the next rule no mattering the value of the global `processUrls` option |\n| [/\\*rtl:begin:urls\\*/](#rtlbeginrules-and-rtlendrules)         | Starts a `processUrls` block block                      |\n| [/\\*rtl:end:urls\\*/](#rtlbeginrules-and-rtlendrules)           | Ends a `processUrls` block block                        |\n| [/\\*rtl:rules\\*/](#rtlrules)                                   | This directive set the `processRuleNames` option to `true` in the next rule no mattering the value of the global `processRuleNames` option |\n| [/\\*rtl:begin:rules\\*/](#rtlbeginrules-and-rtlendrules)        | Starts a `processRuleNames` block block                 |\n| [/\\*rtl:end:rules\\*/](#rtlbeginrules-and-rtlendrules)          | Ends a `processRuleNames` block block                   | \n| [/\\*rtl:source:{source}\\*/](#rtlsourcesource)                  | Set the source of a rule or a declaration no mattering the value of the `source` property |\n| [/\\*rtl:begin:source:{source}\\*/](#rtlbeginsourcesource-and-rtlendsource) | Starts a source block                        |\n| [/\\*rtl:end:source\\*/](#rtlbeginsourcesource-and-rtlendsource) | Ends a source block                                     |\n| [/\\*rtl:raw:{CSS}\\*/](#rtlrawcss)                              | Parses the `CSS` parameter and inserts it in its place. Depending on the `source` parameter the parsed `CSS` will be treated as `rtl` or `ltr` |\n\n---\n\n## /\\*rtl:ignore\\*/\n\nThis directive ignores processing of the following rule or declaration. In the next block the whole declaration will be ignored.\n\n##### input\n\n```css\n/*rtl:ignore*/\n.test1, .test2 {\n    text-align: left;\n    left: 10px;\n}\n```\n\n##### output\n\n```css\n.test1, .test2 {\n    text-align: left;\n    left: 10px;\n}\n```\n\nIn the next block only the `left` property will be ignored:\n\n##### input\n\n```css\n.test3, .test4 {\n    text-align: left;\n    /*rtl:ignore*/\n    left: 10px;\n}\n```\n\n##### output\n\n```css\n.test3, .test4 {\n    left: 10px;\n}\n\n[dir=\"ltr\"] .test3, [dir=\"ltr\"] .test4 {\n    text-align: left;\n}\n\n[dir=\"rtl\"] .test3, [dir=\"rtl\"] .test4 {\n    text-align: right;\n}\n```\n\n---\n\n## /\\*rtl:begin:ignore\\*/ and /\\*rtl:end:ignore\\*/\n\nThese directives should be used together, they will provide the beginning and the end for ignoring rules or declarations.\n\n\u003e[!NOTE]\n\u003eThe directives inserted between these blocks will be ignored and maintained in the final output.\n\nIgnoring multiple rules:\n\n##### input\n\n```css\n/*rtl:begin:ignore*/\n.test1, .test2 {\n    left: 10px;\n    text-align: left;\n}\n\n.test3 {\n    padding: 1px 2px 3px 4px;\n}\n/*rtl:end:ignore*/\n```\n\n##### output\n\n```css\n.test1, .test2 {\n    left: 10px;\n    text-align: left;\n}\n\n.test3 {\n    padding: 1px 2px 3px 4px;\n}\n```\n\nIgnoring multiple declarations:\n\n##### input\n\n```css\n.test1, .test2 {\n    left: 10px;\n    /*rtl:begin:ignore*/\n    margin-left: 4em;\n    padding: 1px 2px 3px 4px;\n    /*rtl:end:ignore*/\n    text-align: left;\n}\n```\n\n##### output\n\n```css\n.test1, .test2 {\n    margin-left: 4em;\n    padding: 1px 2px 3px 4px;\n}\n\n[dir=\"ltr\"] .test1, [dir=\"ltr\"] .test2 {\n    left: 10px;\n    text-align: left;\n}\n\n[dir=\"rtl\"] .test1, [dir=\"rtl\"] .test2 {\n    right: 10px;\n    text-align: right;\n}\n```\n\n---\n\n## /\\*rtl:freeze\\*/\n\n\u003e[!IMPORTANT]\n\u003eThis directive only works in `combined` mode. If you use it in `override` or `diff` modes it will be ignored.\n\nThis directive freezes the rule or declaration in the current direction but does nothing with the counterpart direction. When used with a rule, it will freeze it in the current direction even if it is doesn't contain flippable declarations. When it is used in a declration, it will freeze the declaration in the current direction even if it is not flippable.\n\n##### input\n\n```css\n/*rtl:freeze*/\n.test1, .test2 {\n    color: red;\n    text-align: left;\n    left: 10px;\n}\n\n.test3 {\n    /*rtl:freeze*/\n    text-align: center;\n    /*rtl:freeze*/\n    padding: 10px 20px 30px 40px;\n    margin: 1px 2px 3px 4px;\n}\n```\n\n##### output\n\n```css\n[dir=\"ltr\"] .test1, [dir=\"ltr\"] .test2 {\n    color: red;\n    text-align: left;\n    left: 10px;\n}\n\n[dir=\"ltr\"] .test3 {\n    text-align: center;\n    padding: 10px 40px 30px 20px;\n    margin: 1px 4px 3px 2px;\n}\n\n[dir=\"rtl\"] .test3 {\n    margin: 1px 4px 3px 2px;\n}\n```\n\n---\n\n## /\\*rtl:begin:freeze\\*/ and /\\*rtl:end:freeze\\*/\n\n\u003e[!IMPORTANT]\n\u003eThis directive only works in `combined` mode. If you use it in `override` or `diff` modes it will be ignored.\n\nThese directives should be used together, they will provide the beginning and the end for freezing rules or declarations. The rules or declarations between these blocks, will be frozen in the current direction even if there are no flippable declarations involved.\n\nFreezing multiple rules:\n\n##### input\n\n```css\n/*rtl:begin:freeze*/\n.test1, .test2 {\n    color: #FFF;\n    left: 10px;\n    text-align: left;\n}\n\n.test3 {\n    padding: 1px 2px 3px 4px;\n}\n/*rtl:end:freeze*/\n```\n\n##### output\n\n```css\n[dir=\"ltr\"] .test1, [dir=\"ltr\"] .test2 {\n    color: #FFF;\n    left: 10px;\n    text-align: left;\n}\n\n[dir=\"ltr\"] .test3 {\n    padding: 1px 2px 3px 4px;\n}\n```\n\nFreezing multiple declarations:\n\n##### input\n\n```css\n.test1, .test2 {\n    color: red;\n    left: 10px;\n    /*rtl:begin:freeze*/\n    margin-left: 4em;\n    padding: 1px 2px 3px 4px;\n    /*rtl:end:freeze*/\n    text-align: left;\n}\n```\n\n##### output\n\n```css\n.test1, .test2 {\n    color: red;\n}\n\n[dir=\"ltr\"] .test1, [dir=\"ltr\"] .test2 {\n    left: 10px;\n    margin-left: 4em;\n    padding: 1px 2px 3px 4px;\n    text-align: left;\n}\n\n[dir=\"rtl\"] .test1, [dir=\"rtl\"] .test2 {\n    right: 10px;\n    text-align: right;\n}\n```\n\n---\n\n## /\\*rtl:urls\\*/\n\nThis directive set the `processUrls` option to `true` in the next declaration or in the declarations of the next rule no mattering the value of the global `processUrls` option:\n\n##### input\n\n```css\n/*rtl:urls*/\n.test1 {\n    background-image: url(\"/buttons/button-ltr.png\");\n}\n\n.test2 {\n    /*rtl:urls*/\n    background-image: url(\"/icons/icon-left.png\");\n}\n```\n\n##### output\n\n```css\n[dir=\"ltr\"] .test1 {\n    background-image: url(\"/buttons/button-ltr.png\");\n}\n\n[dir=\"rtl\"] .test1 {\n    background-image: url(\"/buttons/button-rtl.png\");\n}\n\n[dir=\"ltr\"] .test2 {\n    background-image: url(\"/icons/icon-left.png\");\n}\n\n[dir=\"rtl\"] .test2 {\n    background-image: url(\"/icons/icon-right.png\");\n}\n```\n\n---\n\n## /\\*rtl:begin:urls\\*/ and /\\*rtl:end:urls\\*/\n\nThese directives should be used together, they will provide the beginning and the end for `processUrls` blocks.\n\n##### input\n\n```css\n/*rtl:begin:urls*/\n.test1 {\n    background-image: url(\"/buttons/button-ltr.png\");\n}\n\n.test2 {\n    background-image: url(\"/icons/icon-left.png\");\n}\n/*rtl:end:urls*/\n\n.test3 {\n    /*rtl:begin:urls*/\n    background-image: url(\"/images/background-left.png\");\n    cursor: url(\"/images/cursor-ltr.png\");\n    /*rtl:end:urls*/\n}\n```\n\n##### output\n\n```css\n[dir=\"ltr\"] .test1 {\n    background-image: url(\"/buttons/button-ltr.png\");\n}\n\n[dir=\"rtl\"] .test1 {\n    background-image: url(\"/buttons/button-rtl.png\");\n}\n\n[dir=\"ltr\"] .test2 {\n    background-image: url(\"/icons/icon-left.png\");\n}\n\n[dir=\"rtl\"] .test2 {\n    background-image: url(\"/icons/icon-right.png\");\n}\n\n[dir=\"ltr\"] .test3 {\n    background-image: url(\"/images/background-left.png\");\n    cursor: url(\"/images/cursor-ltr.png\");\n}\n\n[dir=\"rtl\"] .test3 {\n    background-image: url(\"/images/background-right.png\");\n    cursor: url(\"/images/cursor-rtl.png\");\n}\n```\n\n---\n\n## /\\*rtl:rules\\*/\n\nThis directive set the `processRuleNames` option to `true` in the next rule no mattering the value of the global `processRuleNames` option:\n\n##### input\n\n```css\n/*rtl:rules*/\n.test1-ltr {\n    background-image: url('/images/test1-l.png');\n}\n\n/*rtl:rules*/\n.test1-rtl {\n    background-image: url('/images/test1-r.png');\n}\n\n/*rtl:rules*/\n.test2-left::before {\n    content: \"\\f007\";\n}\n\n.test2-right::before {\n    content: \"\\f010\";\n}\n```\n\n##### output\n\n```css\n[dir=\"ltr\"] .test1-ltr {\n    background-image: url('/images/test1-l.png');\n}\n\n[dir=\"rtl\"] .test1-ltr {\n    background-image: url('/images/test1-r.png');\n}\n\n[dir=\"ltr\"] .test1-rtl {\n    background-image: url('/images/test1-r.png');\n}\n\n[dir=\"rtl\"] .test1-rtl {\n    background-image: url('/images/test1-l.png');\n}\n\n/* These selectors will not be processed because only one of them has the rtl:rules directive */\n.test2-left::before {\n    content: \"\\f007\";\n}\n\n.test2-right::before {\n    content: \"\\f010\";\n}\n```\n\n---\n\n## /\\*rtl:begin:rules\\*/ and /\\*rtl:end:rules\\*/\n\nThese directives should be used together, they will provide the beginning and the end for `processRuleNames` blocks.\n\n##### input\n\n```css\n.test1-ltr {\n    background-image: url('/images/test1-l.png');\n}\n\n.test1-rtl {\n    background-image: url('/images/test1-r.png');\n}\n\n/*rtl:begin:rules*/\n.test2-left::before {\n    content: \"\\f007\";\n}\n\n.test2-right::before {\n    content: \"\\f010\";\n}\n/*rtl:begin:rules*/\n```\n\n##### output\n\n```css\n.test1-ltr {\n    background-image: url('/images/test1-l.png');\n}\n\n.test1-rtl {\n    background-image: url('/images/test1-r.png');\n}\n\n[dir=\"ltr\"] .test2-left::before {\n    content: \"\\f007\";\n}\n\n[dir=\"rtl\"] .test2-left::before {\n    content: \"\\f010\";\n}\n\n[dir=\"ltr\"] .test2-right::before {\n    content: \"\\f010\";\n}\n\n[dir=\"rtl\"] .test2-right::before {\n    content: \"\\f007\";\n}\n```\n\n---\n\n## /\\*rtl:source:{source}\\*/\n\nThis directive sets the source of a rule or a directive ignoring the value of the `source` property:\n\n##### input\n\n```css\n/*rtl:source:rtl*/\n.test {\n    color: #FFF;\n    border-left: 1px solid #666;\n    padding: 10px 5px 10px 20px;\n    text-align: left;\n    width: 100%;\n}\n```\n\n##### output\n\n```css\n.test {\n    color: #FFF;\n    width: 100%;\n}\n\n[dir=\"ltr\"] .test {\n    border-right: 1px solid #666;\n    padding: 10px 20px 10px 5px;\n    text-align: right;\n}\n\n[dir=\"rtl\"] .test {\n    border-left: 1px solid #666;\n    padding: 10px 5px 10px 20px;\n    text-align: left;\n}\n```\n\n---\n\n## /\\*rtl:begin:source:{source}\\*/ and /\\*rtl:end:{source}\\*/\n\nThese directives should be used together, they will provide the beginning and the end of source blocks for rules or declarations:\n\n##### input\n\n```css\n.test {\n    color: #FFF;\n    border-left: 1px solid #666;\n    /*rtl:begin:source:rtl*/\n    padding: 10px 5px 10px 20px;\n    text-align: left;\n    /*rtl:end:source*/\n    width: 100%;\n}\n```\n\n##### output\n\n```css\n.test {\n    color: #FFF;\n    width: 100%;\n}\n\n[dir=\"ltr\"] .test {\n    border-left: 1px solid #666;\n    padding: 10px 20px 10px 5px;\n    text-align: right;\n}\n\n[dir=\"rtl\"] .test {\n    border-right: 1px solid #666;\n    padding: 10px 5px 10px 20px;\n    text-align: left;\n}\n```\n\n---\n\n## /\\*rtl:raw:{CSS}\\*/\n\nParses the `CSS` parameter and inserts it in its place. Depending on the `source` parameter the parsed CSS will be treated as `rtl` or `ltr`:\n\n##### input\n\n```css\n.test1 {\n    color: #EFEFEF;\n    left: 10px;\n    /*rtl:raw:\n    height: 50px;\n    width: 100px;*/\n}\n\n/*rtl:raw:.test2 {\n    color: #EFEFEF;\n    left: 10px;\n    width: 100%;    \n}\n\n.test3 {\n    transform: translate(10px, 20px);\n}\n*/\n```\n\n##### output\n\n```css\n.test1 {\n    color: #EFEFEF;\n}\n\n[dir=\"ltr\"] .test1 {\n    left: 10px;\n}\n\n[dir=\"rtl\"] .test1 {\n    right: 10px;\n    height: 50px;\n    width: 100px;\n}\n\n[dir=\"rtl\"] .test2 {\n    color: #EFEFEF;\n    left: 10px;\n    width: 100%;    \n}\n\n[dir=\"rtl\"] .test3 {\n    transform: translate(10px, 20px);\n}\n```\n\n---\n\nValue Directives\n---\n\nValue directives are placed anywhere inside the declaration value. They target the containing declaration node.\n\n| Directive                                     | Description                                                                      |\n| --------------------------------------------- | -------------------------------------------------------------------------------- |\n| [/\\*rtl:ignore\\*/](#rtlignore-1)              | Ignores processing of the declaration                                            |\n| [/\\*rtl:append{value}\\*/](#rtlappendvalue)    | Appends `{value}` to the end of the declaration value                            |\n| [/\\*rtl:insert:{value}\\*/](#rtlinsertvalue)   | Inserts `{value}` to where the directive is located inside the declaration value |\n| [/\\*rtl:prepend:{value}\\*/](#rtlprependvalue) | Prepends `{value}` to the begining of the declaration value                      |\n| [/\\*rtl:{value}\\*/](#rtlvalue)                | Replaces the declaration value with `{value}`                                    |\n\n---\n\n## /\\*rtl:ignore\\*/\n\nThis directive ignores processing of the current declaration:\n\n##### input\n\n```css\n.test1, .test2 {\n    text-align: left /*rtl:ignore*/;\n    left: 10px;\n}\n```\n\n##### output\n\n```css\n.test1, .test2 {\n    text-align: left;\n}\n\n[dir=\"ltr\"] .test1, [dir=\"ltr\"] .test2 {\n    left: 10px;\n}\n\n[dir=\"rtl\"] .test1, [dir=\"rtl\"] .test2 {\n    right: 10px;\n}\n```\n\n---\n\n## /\\*rtl:append{value}\\*/\n\nThis directive appends `{value}` to the end of the declaration value:\n\n##### input\n\n```css\n.test1, .test2 {\n    padding: 10px /*rtl:append20px*/;\n    left: 10px;\n}\n```\n\n##### output\n\n```css\n[dir=\"ltr\"] .test1, [dir=\"ltr\"] .test2 {\n    padding: 10px;\n    left: 10px;\n}\n\n[dir=\"rtl\"] .test1, [dir=\"rtl\"] .test2 {\n    padding: 10px 20px;\n    right: 10px;\n}\n```\n\n---\n\n## /\\*rtl:insert:{value}\\*/\n\nThis directive inserts `{value}` to where the directive is located inside the declaration value:\n\n##### input\n\n```css\n.test1, .test2 {\n    padding: 10px/*rtl:insert 20px*/ 5px;\n    left: 10px;\n}\n```\n\n##### output\n\n```css\n[dir=\"ltr\"] .test1, [dir=\"ltr\"] .test2 {\n    padding: 10px 5px;\n    left: 10px;\n}\n\n[dir=\"rtl\"] .test1, [dir=\"rtl\"] .test2 {\n    padding: 10px 20px 5px;\n    right: 10px;\n}\n```\n\n---\n\n## /\\*rtl:prepend:{value}\\*/\n\nThis directive prepends `{value}` to the begining of the declaration value:\n\n##### input\n\n```css\n.test1, .test2 {\n    font-family: Arial, Helvetica/*rtl:prepend:\"Droid Arabic Kufi\", */;\n    left: 10px;\n}\n```\n\n##### output\n\n```css\n[dir=\"ltr\"] .test1, [dir=\"ltr\"] .test2 {\n    font-family: Arial, Helvetica;\n    left: 10px;\n}\n\n[dir=\"rtl\"] .test1, [dir=\"rtl\"] .test2 {\n    font-family: \"Droid Arabic Kufi\", Arial, Helvetica;\n    right: 10px;\n}\n```\n\n---\n\n## /\\*rtl:{value}\\*/\n\nThis directive replaces the declaration value with `{value}`:\n\n##### input\n\n```css\n.test1, .test2 {\n    font-family: Arial, Helvetica/*rtl:\"Droid Arabic Kufi\"*/;\n    left: 10px;\n}\n```\n\n##### output\n\n```css\n[dir=\"ltr\"] .test1, [dir=\"ltr\"] .test2 {\n    font-family: Arial, Helvetica;\n    left: 10px;\n}\n\n[dir=\"rtl\"] .test1, [dir=\"rtl\"] .test2 {\n    font-family: \"Droid Arabic Kufi\";\n    right: 10px;\n}\n```\n\n---\n\nIf you do not use PostCSS, add it according to [official docs]\nand set this plugin in settings.\n\n[official docs]: https://github.com/postcss/postcss#usage\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felchininet%2Fpostcss-rtlcss","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felchininet%2Fpostcss-rtlcss","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felchininet%2Fpostcss-rtlcss/lists"}