CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-rtlcss

Framework for transforming cascading style sheets (CSS) from left-to-right (LTR) to right-to-left (RTL)

Pending
Overview
Eval results
Files

directives.mddocs/

Directives

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.

Capabilities

Control Directives

Control directives modify the processing flow and behavior of RTLCSS transformations.

// Ignore directive - skip RTL processing for elements
/* rtl:ignore */

// Block ignore directive - ignore multiple elements
/* rtl:begin:ignore */
/* rtl:end:ignore */

// Rename directive - apply string mapping to selectors
/* rtl:rename */

// Raw directive - insert raw CSS
/* rtl:raw: .custom { direction: rtl; } */

// Remove directive - remove CSS elements
/* rtl:remove */

// Options directive - temporarily change configuration
/* rtl:begin:options: {"autoRename": true} */
/* rtl:end:options */

Ignore Directive

Prevents RTLCSS from processing specific CSS elements.

/**
 * Ignore directive syntax:
 * - Single element: /* rtl:ignore * /
 * - Block start: /* rtl:begin:ignore * /
 * - Block end: /* rtl:end:ignore * /
 */

Usage Examples:

/* Ignore single declaration */
.header {
  float: left; /* rtl:ignore */
  margin-right: 10px;
}
/* Output: .header { float: left; margin-left: 10px; } */

/* Ignore entire rule */
/* rtl:ignore */
.sidebar {
  float: left;
  margin-right: 20px;
}
/* Output: .sidebar { float: left; margin-right: 20px; } (unchanged) */

/* Block ignore multiple elements */
/* rtl:begin:ignore */
.nav-left {
  float: left;
}
.nav-right {
  float: right;
}
/* rtl:end:ignore */
/* Output: both rules remain unchanged */

/* Self-closing block ignore */
/* rtl:begin:ignore */
.component {
  /* rtl:end:ignore */
  text-align: left;
  /* rtl:begin:ignore */
  float: left;
}
/* rtl:end:ignore */
/* Output: only text-align is transformed */

Rename Directive

Applies string mapping transformations to CSS selectors.

/**
 * Rename directive syntax:
 * /* rtl:rename */
 */

Usage Examples:

/* Apply string mapping to selector */
/* rtl:rename */
.nav-left {
  color: blue;
}
/* Output: .nav-right { color: blue; } (if left-right string map is configured) */

/* Rename with custom string map */
/* With stringMap: [{ search: 'primary', replace: 'أساسي' }] */
/* rtl:rename */
.btn-primary {
  background: blue;
}
/* Output: .btn-أساسي { background: blue; } */

Raw Directive

Inserts raw CSS content without processing.

/**
 * Raw directive syntax:
 * /* rtl:raw: CSS_CONTENT */
 */

Usage Examples:

/* Insert raw RTL-specific CSS */
.container {
  /* rtl:raw:
    direction: rtl;
    text-align: right;
  */
  margin-left: 10px;
}
/* Output includes both the raw CSS and processed margin */

/* Complex raw insertion */
/* rtl:raw:
  .rtl-only {
    font-family: 'Arabic Font', sans-serif;
    letter-spacing: 0;
  }
  .ltr-hidden {
    display: none;
  }
*/
.content {
  text-align: left;
}
/* Raw CSS is inserted before the processed .content rule */

Remove Directive

Removes CSS elements from RTL output.

/**
 * Remove directive syntax:
 * /* rtl:remove */
 */

Usage Examples:

/* Remove entire rule in RTL */
/* rtl:remove */
.ltr-only {
  float: left;
  text-align: left;
}
/* Output: rule is completely removed */

/* Remove specific declaration */
.header {
  color: blue;
  /* rtl:remove */
  direction: ltr;
  text-align: left;
}
/* Output: .header { color: blue; text-align: right; } */

/* Remove at-rule */
/* rtl:remove */
@media print {
  .no-print { display: none; }
}
/* Output: entire @media rule is removed */

Options Directive

Temporarily changes RTLCSS configuration options.

/**
 * Options directive syntax:
 * /* rtl:begin:options: JSON_OPTIONS */
 * /* rtl:end:options */
 * 
 * Self-closing:
 * /* rtl:options: JSON_OPTIONS */
 */

Usage Examples:

/* Temporarily enable autoRename */
/* rtl:begin:options: {"autoRename": true} */
.nav-left {
  float: left;
}
.nav-right {
  float: right;
}
/* rtl:end:options */
/* Both selector names and properties are transformed */

/* Self-closing options for single rule */
/* rtl:options: {"stringMap": [{"search": "brand", "replace": "علامة"}]} */
.brand-logo {
  float: left;
}
/* Output: .علامة-logo { float: right; } */

/* Disable cleaning temporarily */
/* rtl:begin:options: {"clean": false} */
.debug {
  /* rtl:ignore */
  float: left; /* This comment will be preserved */
}
/* rtl:end:options */

/* Multiple option changes */
/* rtl:begin:options: {
  "autoRename": true,
  "greedy": true,
  "stringMap": [
    {
      "name": "temp-map",
      "search": "custom",
      "replace": "مخصص",
      "priority": 50
    }
  ]
} */
.custom-header {
  text-align: left;
}
/* rtl:end:options */

Value Directives

Value directives transform CSS values inline using regular expressions.

/**
 * Value directives are processed through plugin system
 * They modify CSS property values during transformation
 */

Custom Value Directive Example:

// Custom value directive plugin
const customValueDirective = {
  name: 'custom-values',
  priority: 100,
  directives: {
    value: [
      {
        name: 'flip',
        action: (node, expr, context) => {
          // Custom logic to flip values
          const flipped = node.value.replace(/left/g, 'temp')
                                   .replace(/right/g, 'left')
                                   .replace(/temp/g, 'right');
          node.value = flipped;
          return true;
        }
      }
    ]
  }
};

// Usage in CSS
.element {
  /* rtl:flip */
  text-align: left;
}

// Another practical example: prepend directive
const prependDirective = {
  name: 'prepend-values',
  priority: 100,
  directives: {
    value: [
      {
        name: 'prepend',
        action: (node, expr, context) => {
          const match = node.value.match(expr);
          if (match && match[1]) {
            node.value = match[1] + node.value;
            return true;
          }
          return false;
        }
      }
    ]
  }
};

// Usage in CSS with prepend directive
.rtl-prefix {
  /* rtl:prepend: "rtl-" */
  background-image: url(image.png);
}

Directive Processing Order

Directives are processed in the following order:

  1. Control directives (ignore, rename, raw, remove, options)
  2. Value directives (inline transformations)
  3. Property processors (CSS property transformations)

Error Handling

RTLCSS provides warnings for directive-related issues:

// Unclosed directive warning
/* rtl:begin:ignore */
.rule { float: left; }
// Missing /* rtl:end:ignore */ - generates warning

// Unmatched end directive
/* rtl:end:ignore */ // No matching begin - generates warning

// Invalid options JSON
/* rtl:options: {invalid json} */ // Generates error

// Blacklisted directive
// If 'ignore' is blacklisted, generates warning:
/* rtl:ignore */ // Warning: directive "rtlcss.ignore" is blacklisted

Usage with Error Handling:

const postcss = require("postcss");
const rtlcss = require("rtlcss");

const processor = postcss([rtlcss()]);

processor.process(css)
  .then(result => {
    // Check for warnings
    result.warnings().forEach(warn => {
      console.warn(warn.toString());
    });
    
    console.log(result.css);
  })
  .catch(error => {
    console.error('RTLCSS processing error:', error);
  });

Install with Tessl CLI

npx tessl i tessl/npm-rtlcss

docs

cli.md

configuration.md

core-api.md

directives.md

index.md

tile.json