There are two methods to use in order to flip CSS styles: interpolated properties and the flip() function.
- Interpolation should be used for any property which has a direction (e.g.
padding-left
,margin-right
,border-right
,left
, etc.) flip()
should be used for all other properties
- background
- background-position
- border
- border-radius
- clear
- cursor
- direction
- float
- left/right
- margin
- padding
- text-align
- text-indent
// guts/mixins/_rtl.scss
@function flip($value_ltr, $value_rtl) {
@if $rtl { @return $value_rtl; }
@else { @return $value_ltr; }
}
$padding-left: padding-left;
$padding-right: padding-right;
$margin-left: margin-left;
$margin-right: margin-right;
$border-right: border-right;
$left: left;
$right: right;
@if $rtl {
$padding-left: padding-right;
$padding-right: padding-left;
$margin-left: margin-right;
$margin-right: margin-left;
$border-right: border-left;
$left: right;
$right: left;
}
To implement, let's take the following style as an example:
// Original Sass
.class {
float: left;
}
For a RTL layout, float: left;
should be flipped to float: right'
.
We can use the flip()
function to accomplish this.
// Flipped Sass
.class {
float: flip(left, right);
}
When Sass comes across the flip()
function when compiling the code, it will check what the $rtl
variable is set to. This variable is set at the top level, for example in sass/intl-arabic-core.scss
.
If $rtl
is false
, the flip()
function will take the first parameter.
If $rtl
is true
, the flip()
function will take the second parameter.
The Sass will compile out as follows:
// Compiled LTR style
.class {
float: left;
}
// Compiled RTL style
.class {
float: right;
}
This method interpolates the property names from variables which are flipped higher up.
In _rtl.scss
, the $padding-left
variable is declared as padding-left
. Then if $rtl
is true
, it is overridden with padding-right
.
To implement, take the following style as an example:
// Original Sass
.class {
padding-left: 8px;
}
For a RTL layout, padding-left: 8px;
should be flipped to padding-right: 8px;
.
In order to flip this, we have to interpolate the style property:
// Flipped Sass
.class {
#{$padding-left}: 8px;
}
This will compile out to:
// Compiled LTR style
.class {
padding-left: 8px;
}
// Compiled RTL style
.class {
padding-right: 8px;
}
Placing the dir=rtl
attribute on the <html>
tag can cause the scrollbar in certain browsers to be flipped to the left-hand side. This is generally found to be a bad experience for RTL users.
Adding dir=rtl
to the <head>
tag and to a <div>
wrapping the whole page, as recommended by W3C, ensures that the scrollbar isn't flipped.
<!DOCTYPE HTML>
<html>
<head dir="rtl">
...
</head>
<body>
<div dir="rtl">
...
</div>
</body>
</html>
// Flipped Sass
.class {
#{$padding-left}: 8px;
#{$padding-right}: 8px;
#{$margin-left}: 8px;
#{$margin-right}: 8px;
#{$left}: 8px;
#{$right}: 8px;
margin: flip(1px 2px 3px 4px, 1px 4px 3px 2px);
float: flip(left, right);
}
// Compiled LTR style
.class {
padding-left: 8px;
padding-right: 8px;
margin-left: 8px;
margin-right: 8px;
left: 8px;
right: 8px;
margin: 1px 2px 3px 4px;
float: left;
}
// Compiled RTL style
.class {
padding-right: 8px;
padding-left: 8px;
margin-right: 8px;
margin-left: 8px;
right: 8px;
left: 8px;
margin: 1px 4px 3px 2px;
float: right;
}
- Don't flip everything! Only flip what needs to be flipped. This will help keep the CSS as clean as possible.
- Styles which are hiding elements by pushing them off the screen (e.g.
text-align: -320px;
orright: 5000%;
) don't need to be flipped unless they are being transitioned or overridden. - If left and right properties have the same values in the same selector, they dont need to be flipped (e.g.
margin-left: 0; margin-right: 0;
) - Write long values on separate lines:
// Good
.class {
padding: flip($gutter/2 $gutter*2.5 $gutter/4 $gutter/2,
$gutter/2 $gutter/2 $gutter/4 $gutter*2.5);
}
// Bad
.class {
padding: flip($gutter/2 $gutter*2.5 $gutter/4 $gutter/2, $gutter/2 $gutter/2 $gutter/4 $gutter*2.5);
}
- Separate
background-position
frombackground
shorthand
// Good
.class {
background: $pale-grey image-url('icons-sprite.png') no-repeat;
background-position: flip(right -792px, left -792px);
}
// Bad
.class {
background: flip($pale-grey image-url('icons-sprite.png') no-repeat right -792px,
$pale-grey image-url('icons-sprite.png') no-repeat left -792px);
}
- How to fix bi-directional brackets issue: http://blog.jalproductions.co.uk/2013/04/19/how-to-fix-rtl-bracketsparenthesis-problem/
it might be a good practice to create a transform variable that sets transform to 180 for icons like back arrow
Although this is a rare use case, but for example 'rtl' users will consider right as back direction since they write right to left