There are two methods to use in order to flip CSS styles: interpolated properties and the flip() function.
padding-left
, margin-right
, border-right
, left
, etc.)flip()
should be used for all other properties// 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;
}
text-align: -320px;
or right: 5000%;
) don’t need to be flipped unless they are being transitioned or overridden.margin-left: 0; margin-right: 0;
)// 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);
}
background-position
from background
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);
}