-
-
Notifications
You must be signed in to change notification settings - Fork 129
Why make a complete RTL version ?
It might be, but it will not work in all situations!
Assume we want to RTL the following document:
HTML
<div>
Title
<img width="40"
src="http://upload.wikimedia.org/wikipedia/commons/6/6a/Light_bulb_icon_tips.svg">
<hr>
<br>
Contents Contents Contents
Contents Contents Contents
Contents Contents Contents
Contents Contents Contents
Contents Contents Contents
Contents Contents Contents
</div>
CSS
hr {
margin:10px;
}
img {
float:right;
clear:both;
}
div {
border:solid 10px gray;
width:200px;
height:200px;
padding:2px;
}
div hr {
margin-right:40px;
}
[jsfiddle]
Flipping the above using a subset of RTL overrides is straight forward:
Override CSS
/*override*/
body {
direction:rtl;
}
img {
float:left;
}
div hr {
margin-left:40px;
}
[jsfiddle]
As you may have noticed, the above solution does not address resetting the right margin value of the hr
element! Which led to inconsistencies in the RTL version.
You might say, why not to reset the margin-right
declaration?
Override CSS with RESET
div hr {
margin-left:40px;
margin-right:0 /*or inherit*/;
}
[jsfiddle]
Still inconsistent with the LTR version, as the value should be 10px
(cascaded by the HR
CSS rule).
Override CSS with fixed RESET
div hr {
margin-left:40px;
margin-right:10px;
}
[jsfiddle]
Which is an exact mirror of the original LTR version:
Unless you can figure out the computed style, a subset of RTL overrides approach will fail.
Unfortunately, this method is error-prone, as it messes with rules specificity.
Example CSS:
body h1 {
border-style:dashed dotted solid double;
border-color:red green blue black;
border-width: 1px 2px 3px 4px;
}
div h1 {
border-color:green;
}
The combined version:
body h1 {
border-style: dashed dotted solid double;
border-color: red green blue black;
border-width: 1px 2px 3px 4px
}
div h1{
border-color: green
}
html[dir="rtl"] body h1 {
border-style: dashed double solid dotted;
border-color: red black blue green;
border-width: 1px 4px 3px 2px
}
In the LTR version div h1
has higher specificity, but in the RTL version, the specificity of html[dir="rtl"] body h1
will be higher (JSFiddle).
You might say, What about moving all the directional declarations into a separate rule ?
The same problem still exists!, let's make a slight change in the example CSS:
body h1 {
border-style: dashed dotted solid double;
border-color: red green blue black;
border-width: 1px 2px 3px 4px
}
body h1:not(:last-child) {
border-color: green
}
Then combine it with separate rules:
body h1:not(:last-child) {
border-color: green
}
html[dir="ltr"] body h1 {
border-style: dashed dotted solid double;
border-color: red green blue black;
border-width: 1px 2px 3px 4px
}
html[dir="rtl"] body h1 {
border-style: dashed double solid dotted;
border-color: red black blue green;
border-width: 1px 4px 3px 2px
}
In the original CSS body h1:not(:last-child)
has higher specificity and should render the h1 with green border, But in the combined version, the specificity of html[dir="ltr"] body h1
will be higher. (JSFiddle).
The solution would be to prefix all other rules with html[dir]
maintaining their order, since for rules with same specificity, last one wins (JSFiddle).
For me I think having a separate file is better, as this will bloat your CSS file in terms of size, where changing the direction usually means a different language that will not need both LTR/RTL versions to be available at the same time.