Extending RTLCSS

Your guide on how to use and make the most out of RTLCSS

Time is Priceless, Caffeine is Not! Buy Me a Coffee ☕

Control Directives

Control directives are triggered by CSS comments found between declarations or statements (rules and at-rules). They support processing any node type and can target one node (self-closing) or a set of nodes (block-syntax).

  • Self-closing
.code {
  • Block-syntax
.code {

Control directives are NOT triggered by comments inside selectors, at-rule parameters, or declaration values.

§Control directive defintion object

The definition of a control directive has the following attributes:

  • expect {object}

    An object hash defining the node types this directive is excpected to process, where keys are strings of node types and values are booleans.

    • atrule: At-rule node.
    • comment: Comment node.
    • decl: Declaration node.
    • rule: Rule node.
    • self: Comment node that triggred the directive.

    Find out more about node types at PostCSS API documentation.

    Note: Omitted keys are considred to have a false value.

    "expect": { "rule" : true, "self" : true }
  • begin {function}

    The begin function is responsible for processing nodes of the expected types. It is executed each time a node with the excpected type is encountered.

    'begin': function (node, metadata, context) { ... }

    The begin function must return a boolean value to indicate if it is allowed to process this node by other directives or not.

    • true: prevent further processing.
    • false: allow further processing.
  • end {function}

    The end function is responsible for cleanup and deactivation. It is executed after processing the expected node (if it was self-closing) or when the directive end statement (block-syntax) is encountred.

    'end': function (node, metadata, context) { ... }

    The end functions must return a boolean value to indicate if the directive has finished and should be deactivated or not.

    • true: deactivate.
    • false: keep active.


Here is a complete example of a control directive definition to ignore processing of one node or a set of nodes.

It can be triggered via: /*rtl:ignore*/ or /*rtl:begin:ignore*/.

'ignore': {
// the expected node types
'expect': { 'atrule': true, 'comment': true, 'decl': true, 'rule': true },
// local variable to store ending node
'endNode': null,
// prevent processing all nodes except comments indicating the end of this directive
'begin': function (node, metadata, context) {
// find the ending node in case of self closing directive
if (!this.endNode && metadata.begin && metadata.end) {
var n = node
while (n && n.nodes) {
n = n.nodes[n.nodes.length - 1]
this.endNode = n
var prevent = true
if (node.type === 'comment' &&
(node.text === '!rtl:end:ignore' || node.text === 'rtl:end:ignore')) {
prevent = false
return prevent
// deactivate the directive if:
// 1. block directive and the node is comment
// 2. self closing directive and node is endNode
'end': function (node, metadata, context) {
if (metadata.begin !== metadata.end && node.type === 'comment' ||
metadata.begin && metadata.end && node === this.endNode) {
// clear ending node
this.endNode = null
// deactivate
return true
// keep ignoring
return false