Framework for transforming Cascading Style Sheets (CSS) from Left-To-Right (LTR) to Right-To-Left (RTL)

  • By Mohammad Younes
  • Last update: Nov 25, 2022
  • Comments: 15

RTLCSS

Join the chat at https://gitter.im/MohammadYounes/rtlcss

GitHub version npm version Build Status

js-standard-style editor Twitter

RTLCSS is a framework for converting Left-To-Right (LTR) Cascading Style Sheets(CSS) to Right-To-Left (RTL).

Documentation

Visit https://rtlcss.com/learn/

Playground

Visit https://rtlcss.com/playground/

Bugs and Issues

Have a bug or a feature request? please feel free to open a new issue.

Release Notes

To view changes in recent versions, see the CHANGELOG.

Support

RTLCSS is saving you and your team a tremendous amount of time and effort? Buy Me a Coffee

Github

https://github.com/MohammadYounes/rtlcss

Comments(15)

  • 1

    Implement configuration file lookup

    Requested by @am11

    Web Essentials requires rtlcss to handle its configuration lookup on its own, searching current working folder all the way up to the root.

  • 2

    Integrating rtlcss into angular apps

    Hello guys.

    I'm looking for a way to integrate rtlcss into angular 4 apps. Has anyone ever tried this before? Since angular does css bundling internally, Do you know any way to apply right to left styles to generated css elements?

    Thanks in advance.

  • 3

    Exclude selectors

    Is it possible to exclude nodes that match a regex pattern? Similar to the Ignore Control Directive, but programmatically?

    Or is it possible to do this with a plugin?

  • 4

    I guess something is wrong here!

    Could you please check this behaviour?

    require("rtlcss").process(`.text-left {
      text-align: left;
    }`, {
      autoRename: false
    });
    // output: '.text-left { text-align: right; }'
    
    require("rtlcss").process(`.text-left {
      text-align: left;
    }`, {
      autoRename: true
    });
    // output: '.text-left { text-align: right; }'
    

    How could I get it to rename them both or ignore them both?

  • 5

    release patch for rtlcss 2.6.x with updated dependency postcss

    Hi, @MohammadYounes, I stumbled upon a vulnerability introduced by package [email protected]:

    Issue Description

    When I build my project, I notice that a vulnerability CVE-2021-23382 detected in package postcss(<7.0.36,>=8.0.0 <8.2.13) is directly referenced by [email protected]. However, [email protected] is so popular that a large number of latest versions of active and popular downstream projects depend on it (41,811 downloads per week and about 34 downstream projects, e.g., gulp-rtlcss 1.4.2, rtlcss-webpack-plugin 4.0.6, @oroinc/oro-webpack-config-builder 5.1.0-alpha20, @automattic/social-previews 1.1.1, select2-bootstrap-5-theme 1.1.1, etc.). In this case, the vulnerability CVE-2021-23382 can be propagated into these downstream projects and expose security threats to them. As you can see, [email protected] is introduced into the above projects via the following package dependency paths: (1)[email protected] ➔ @bazel/[email protected][email protected][email protected] ......

    I know that it's kind of you to have removed the vulnerability since [email protected]. But, in fact, the above large amount of downstream projects cannot easily upgrade rtlcss from version 2.6.2 to (>=3.0.0): The projects such as @bazel/postcss, which introduced [email protected], are not maintained anymore. These unmaintained packages can neither upgrade rtlcss nor be easily migrated by the large amount of affected downstream projects.

    Given the large number of downstream users, is it possible to release a new patched version with the updated dependency to remove the vulnerability from package [email protected]?

    Suggested Solution

    Since these inactive projects set a version constaint 2.6.* for rtlcss on the above vulnerable dependency paths, if rtlcss removes the vulnerability from 2.6.2 and releases a new patched version [email protected], such a vulnerability patch can be automatically propagated into the downstream projects.

    In [email protected], maybe you can try to perform the following upgrade: postcss ^6.0.23 ➔ ^7.0.36;
    Note: [email protected](>=7.0.36 <8.0.0) has fixed the vulnerability CVE-2021-23382.

    Thank you for your attention to this issue and welcome to share other ways to resolve the issue.

  • 6

    Bootstrap 5.2 LTR and RTL at the same time (scss with Laravel vite)

    Hello, i'm trying to use bootstrap with both RTL and LTR in the same scss file (as described in here LTR and RTL at the same time

    /* rtl:begin:options: {
      "autoRename": true,
      "stringMap":[ {
        "name": "ltr-rtl",
        "priority": 100,
        "search": ["ltr"],
        "replace": ["rtl"],
        "options": {
          "scope": "*",
          "ignoreCase": false
        }
      } ]
    } */
    .ltr {
      @import "../node_modules/bootstrap/scss/bootstrap";
    }
    /*rtl:end:options*/
    

    But for some reason it doesn't seem to be working, i'm not sure whether i'm using it incorrectly or smth as in Laravel all what we need to build the css..etc is using this command npm run build but it doesn't build .rtl class so i thought i might need to implement this in my postcss.config.js

    const rtlcss = require("rtlcss");
    module.exports = {
        plugins: [
            rtlcss(),
        ]
    }
    

    this one works but there is no more .ltr class working,instead it shows errors in css image so there is now only .rtl but fully incorrect as you can see image

    This is how it works like in .ltr (without using rtlcss()) image

    Actually i should post this issue in Laravel or Vite but no one seem to be able to help, hope fully you can find a solution for me.

  • 7

    Adding an option to switch class names

    Consider this css file:

    .float-right {
        float: right;
    }
    .float-left {
        float: left;
    }
    

    rtlcss converts that to:

    .float-right {
        float: left;
    }
    .float-left {
        float: right;
    }
    

    As you can see now .float-right class make an item left floating. An option to update class names is really necessary.

  • 8

    Usage with Webpack

    It's not an issue but rather a question on how to use it with Webpack and postcss. My scenario is to produce two different packages one with RTL and the other is with LTR and to request one of them based on interface switching.

    Any idea would be highly appreciated!

  • 9

    Bidirectional output mode

    I work on the CSS infrastructure team at Google, and we're considering adopting RTLCSS as the standard for language conversion. However, one feature we'd really like to see that doesn't exist yet is the ability to emit a single output file that supports both LTR and RTL browsers.

    Specifically, we'd like to be able to specify a pair of parent selectors (say [dir="ltr"] and [dir="rtl"], or :host-context([dir="ltr"]) and :host-context([dir="rtl"])) and have RTLCSS copy the subset of each ruleset that contains convertible rules into new rulesets nested under those selectors. So for example, with {bidi: {ltr: '[dir="ltr"]', rtl: '[dir="rtl"]'}}:

    .example {
       margin: 0;
       padding: 1em 2em .5em 1em;
    }
    

    would compile to:

    .example {
       margin: 0;
    }
    
    [dir="ltr"] .example {
       padding: 1em 2em .5em 1em;
    }
    
    [dir="rtl"] .example {
      padding: 1em 1em .5em 2em;
    }
    

    Is this a feature you'd be open to adding?

  • 10

    Better README

    RTLCSS is awesome. I want to use as example of PostCSS power. But I can puut a link, because RTLCSS’s README doesn’t tell what plugin does (many of users doesn’t know what is RTL is).

    Maybe you put a CSS input/output example and some before/after screenshot?

  • 11

    Can not set font-size for $font-size-base SASS bootstrap file for RTL mode

    When I want to override _variables.scss bootstrap. I don't have any problem with set specific font family in rtl mode with this code:

    $font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif #{'/*rtl:prepend:"Yekan", */'} !default;

    But when I want to set new font size for rtl mode, this code does not works:

    $font-size-base: 18px #{'/*rtl:40px*/'} !default;

    And give me this error when compiling:

    [19:07:48] gulp-ruby-sass: directory
    
    events.js:141
          throw er; // Unhandled 'error' event
          ^
     Error: error bower_components/bootstrap-sass/assets/stylesheets/bootstrap/_variables.scss (Line 53: Undefined operation: "18px /*rtl:40px*/ times 1.25".)
    

    In line 53 of bootstrap/_variables.scss file is this:

    $font-size-large: ceil(($font-size-base * 1.25)) !default; // ~18px

    Do you have any suggestion?

  • 12

    processUrls shouldn't process non-URL expressions in at-rules

    Currently, if "processUrls" is set to true, the string map will apply to any parenthesized expression in an at-rule. For example:

    /*rtl:options:{
      "stringMap": [
        {
          "name"    : "ltr-rtl",
          "priority": 100,
          "search"  : ["ltr"],
          "replace" : ["rtl"],
          "options" :	{
              "scope" : "url",
              "ignoreCase" : true
            }
        }
      ],
      "processUrls": true
    }*/
    @foo (rtl);
    

    This is particularly problematic when combined with other PostCSS plugins that add custom at-rules, which may involve the text rtl at various points. As a workaround, I can set "processUrls": {"atrule": false}, but that means that an actual url() expression in an at-rule doesn't get converted.

  • 13

    Support src() with processUrls

    The src() function defined by CSS Values and Units 4 provides an alternative, easier-to-parse syntax that's semantically equivalent to url() and usable in all the same places. It would be useful if RTLCSS supported converting text in strings passed to src() if processUrls: true was set.

  • 14

    Don't process data URLs

    Currently if you enable the processUrls option, RTLCSS will apply its string map even to data: URLs. This will typically corrupt the URL contents, especially for base64-encoded URLs (which contain the text ltr or rtl reasonably often). Here's an example:

    /*rtl:options:{
      "stringMap": [
        {
          "name"    : "ltr-rtl",
          "priority": 100,
          "search"  : ["ltr"],
          "replace" : ["rtl"],
          "options" :	{
              "scope" : "url",
              "ignoreCase" : true
            }
        }
      ],
      "processUrls": true
    }*/
    .example {
       background: url(data:image/svg+xml;base64,ltr)
    }
    
  • 15

    Update CodeQL workflow

    @MohammadYounes there is a Polynomial regular expression and maybe other issues. This PR should tighten things.

    In case you have missed it, you can see the CodeQL issues on https://github.com/MohammadYounes/rtlcss/security/code-scanning (only collaborators can)