Making sure your theme works with RTL locales

  • Revision slug: Making_Sure_Your_Theme_Works_with_RTL_Locales
  • Revision title: Making sure your theme works with RTL locales
  • Revision id: 424149
  • Created:
  • Creator: mnoorenberghe
  • Is current revision? Yes
  • Comment typo in property name

Revision Content

Some languages are written from right to left. Of the languages Firefox and Thunderbird are shipped in, that includes Arabic and Hebrew, with Persian available as beta, for a total population in excess of 100 million potential users. The important thing to understand about these locales, is that the entire interface is mirrored right-to-left. That means that text that had a left margin will have a right margin instead (or -moz-margin-start), arrows that pointed right will have to point left and vice versa, and so on.

A screenshot of Firefox 2 in Hebrew
A screenshot of Firefox 2 in Hebrew

What you need to do

At this stage you might ask yourself, "How would I know what language is my theme installed on? Should I make a special theme for these locales?" Don't despair: making a theme RTL-compatible is fairly easy!

Gecko 1.9.2 and later

Gecko 1.9.2 introduced the :-moz-locale-dir CSS pseudoclass, which matches based on whether the user interface is being rendered left-to-right or right-to-left:

  • {{ Cssxref(":-moz-locale-dir(ltr)") }} matches if the user interface is being rendered left to right.
  • {{ Cssxref(":-moz-locale-dir(rtl)") }} matches if the user interface is being rendered right to left.

Example

toolbar[iconsize="large"][mode="icons"] #back-button {
  -moz-image-region: rect(0px 396px 34px 360px);
}

toolbar[iconsize="large"][mode="icons"] #back-button:-moz-locale-dir(rtl) {
  -moz-image-region: rect(0px 516px 34px 480px);
} 

This specifies the default, left-to-right version of the button, then offers an override if the user's interface is being rendered in right-to-left mode.

Gecko 1.9.1 (Firefox 3.5) and earlier

The chromedir attribute

Firefox, Thunderbird and SeaMonkey expose an attribute named chromedir on certain elements. All you have to do is add CSS rules to your theme that test for the value of this attribute, and use that to apply any RTL-specific rules that you may have. That's how the default theme works, so you can use it as an example.

toolbar[iconsize="large"][mode="icons"] #back-button {
  -moz-image-region: rect(0px 398px 34px 360px);
}

toolbar[iconsize="large"][mode="icons"] #back-button[chromedir="rtl"] {
  -moz-image-region: rect(0px 516px 34px 478px);
}

This way, if chromedir is "rtl", the second rule will override the first, and the theme will work in RTL.

Note that not all elements will have the chromedir attribute, so you may need to refer to an ancestor element that does. For example:

/* We want to apply a RTL rule to #c; neither it nor its
 * parent element #b has a chromedir attribute, but its
 * grandparent element #a does.
 */

#a > #b > #c {
  /* normal rules */
}

#a[chromedir="rtl"] > #b > #c {
  /* RTL rules */
}

Tip: sometimes, like in the back and forward arrows, you don't really need new versions of the images. Instead, just use the opposite arrow when in RTL context.

Using start/end rules instead of left/right rules

Directions are mirrored in RTL mode, so left becomes right and right becomes left. As a result, you almost never want to use left/right rules for paddings, borders, and margins. Instead, you should use the following start/end rules instead to ensure RTL compatibility:

  • {{ Cssxref("-moz-padding-start") }}
  • {{ Cssxref("-moz-padding-end") }}
  • {{ Cssxref("-moz-margin-start") }}
  • {{ Cssxref("-moz-margin-end") }}
  • {{ Cssxref("-moz-border-start") }}
  • {{ Cssxref("-moz-border-start-color") }}
  • {{ Cssxref("-moz-border-start-style") }}
  • {{ Cssxref("-moz-border-start-width") }}
  • {{ Cssxref("-moz-border-end") }}
  • {{ Cssxref("-moz-border-end-color") }}
  • {{ Cssxref("-moz-border-end-style") }}
  • {{ Cssxref("-moz-border-end-width") }}
#urlbar-search-splitter {
  min-width: 8px;
  -moz-margin-start: -4px;
  border: none;
  background: transparent;
}

Testing your theme

Testing your theme for RTL compatibility is easy, and you do not even have to go through the hassle of downloading a RTL locale. The Force RTL extension enables you to switch the interface of Firefox from LTR to RTL and the other way around dynamically by toggling a menu item.

{{ languages( { "ja": "ja/Making_Sure_Your_Theme_Works_with_RTL_Locales" } ) }}

Revision Source

<p>Some languages are written from right to left. Of the languages Firefox and Thunderbird are shipped in, that includes Arabic and Hebrew, with Persian <a class="external" href="http://www.mozilla.com/en-US/firefox/all.html#beta_versions">available as beta</a>, for a total population in excess of 100 million potential users. The important thing to understand about these locales, is that the entire interface is mirrored right-to-left. That means that text that had a left margin will have a right margin instead (or <code>-moz-margin-start</code>), arrows that pointed right will have to point left and vice versa, and so on.</p>
<div style="">
  <img align="none" alt="A screenshot of Firefox 2 in Hebrew" class="internal" src="/@api/deki/files/214/=Firefox_2_RTL-header.png" /><br />
  A screenshot of Firefox 2 in Hebrew</div>
<h2 id="What_you_need_to_do">What you need to do</h2>
<p>At this stage you might ask yourself, "How would I know what language is my theme installed on? Should I make a special theme for these locales?" Don't despair: making a theme RTL-compatible is fairly easy!</p>
<h3 id="Gecko_1.9.2_and_later">Gecko 1.9.2 and later</h3>
<p>Gecko 1.9.2 introduced the <code>:-moz-locale-dir</code> CSS&nbsp;pseudoclass, which matches based on whether the user interface is being rendered left-to-right or right-to-left:</p>
<ul>
  <li>{{ Cssxref(":-moz-locale-dir(ltr)") }} matches if the user interface is being rendered left to right.</li>
  <li>{{ Cssxref(":-moz-locale-dir(rtl)") }} matches if the user interface is being rendered right to left.</li>
</ul>
<h4 id="Example">Example</h4>
<pre class="brush: css">
toolbar[iconsize="large"][mode="icons"] #back-button {
&nbsp; -moz-image-region: rect(0px 396px 34px 360px);
}

toolbar[iconsize="large"][mode="icons"] #back-button:-moz-locale-dir(rtl) {
&nbsp; -moz-image-region: rect(0px 516px 34px 480px);
} 
</pre>
<p>This specifies the default, left-to-right version of the button, then offers an override if the user's interface is being rendered in right-to-left mode.</p>
<h3 id="Gecko_1.9.1_(Firefox_3.5).C2.A0and_earlier">Gecko 1.9.1 (Firefox 3.5)&nbsp;and earlier</h3>
<h4 id="The_chromedir_attribute">The <code>chromedir</code> attribute</h4>
<p>Firefox, Thunderbird and SeaMonkey expose an attribute named <code>chromedir</code> on certain elements. All you have to do is add CSS rules to your theme that test for the value of this attribute, and use that to apply any RTL-specific rules that you may have. That's how the default theme works, so you can use it as an example.</p>
<pre>
toolbar[iconsize="large"][mode="icons"] #back-button {
  -moz-image-region: rect(0px 398px 34px 360px);
}

toolbar[iconsize="large"][mode="icons"] #back-button[chromedir="rtl"] {
  -moz-image-region: rect(0px 516px 34px 478px);
}
</pre>
<p>This way, if <code>chromedir</code> is "rtl", the second rule will override the first, and the theme will work in RTL.</p>
<p>Note that not all elements will have the <code>chromedir</code> attribute, so you may need to refer to an ancestor element that does. For example:</p>
<pre>
/* We want to apply a RTL rule to #c; neither it nor its
 * parent element #b has a chromedir attribute, but its
 * grandparent element #a does.
 */

#a &gt; #b &gt; #c {
  /* normal rules */
}

#a[chromedir="rtl"] &gt; #b &gt; #c {
  /* RTL rules */
}
</pre>
<p><strong>Tip:</strong> sometimes, like in the <em>back</em> and <em>forward</em> arrows, you don't really need new versions of the images. Instead, just use the opposite arrow when in RTL context.</p>
<h4 id="Using_start.2Fend_rules_instead_of_left.2Fright_rules" name="Using_start.2Fend_rules_instead_of_left.2Fright_rules">Using start/end rules instead of left/right rules</h4>
<p>Directions are mirrored in RTL mode, so left becomes right and right becomes left. As a result, you almost never want to use left/right rules for paddings, borders, and margins. Instead, you should use the following start/end rules instead to ensure RTL compatibility:</p>
<ul>
  <li>{{ Cssxref("-moz-padding-start") }}</li>
  <li>{{ Cssxref("-moz-padding-end") }}</li>
  <li>{{ Cssxref("-moz-margin-start") }}</li>
  <li>{{ Cssxref("-moz-margin-end") }}</li>
  <li>{{ Cssxref("-moz-border-start") }}</li>
  <li>{{ Cssxref("-moz-border-start-color") }}</li>
  <li>{{ Cssxref("-moz-border-start-style") }}</li>
  <li>{{ Cssxref("-moz-border-start-width") }}</li>
  <li>{{ Cssxref("-moz-border-end") }}</li>
  <li>{{ Cssxref("-moz-border-end-color") }}</li>
  <li>{{ Cssxref("-moz-border-end-style") }}</li>
  <li>{{ Cssxref("-moz-border-end-width") }}</li>
</ul>
<pre>
#urlbar-search-splitter {
  min-width: 8px;
  -moz-margin-start: -4px;
  border: none;
  background: transparent;
}</pre>
<h2 id="Testing_your_theme">Testing your theme</h2>
<p>Testing your theme for RTL compatibility is easy, and you do not even have to go through the hassle of downloading a RTL locale. The <a class="link-https" href="https://addons.mozilla.org/firefox/7438">Force RTL</a> extension enables you to switch the interface of Firefox from LTR&nbsp;to RTL&nbsp;and the other way around dynamically by toggling a menu item.</p>
<p>{{ languages( { "ja": "ja/Making_Sure_Your_Theme_Works_with_RTL_Locales" } ) }}</p>
Revert to this revision