summaryrefslogtreecommitdiffstats
path: root/docs/code-quality/coding-style/rtl_guidelines.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/code-quality/coding-style/rtl_guidelines.rst')
-rw-r--r--docs/code-quality/coding-style/rtl_guidelines.rst356
1 files changed, 356 insertions, 0 deletions
diff --git a/docs/code-quality/coding-style/rtl_guidelines.rst b/docs/code-quality/coding-style/rtl_guidelines.rst
new file mode 100644
index 0000000000..8b2a6bcf04
--- /dev/null
+++ b/docs/code-quality/coding-style/rtl_guidelines.rst
@@ -0,0 +1,356 @@
+RTL Guidelines
+==============
+
+RTL languages such as Arabic, Hebrew, Persian and Urdu are read and
+written from right-to-left, and the user interface for these languages
+should be mirrored to ensure the content is easy to understand.
+
+When a UI is changed from LTR to RTL (or vice-versa), it’s often called
+mirroring. An RTL layout is the mirror image of an LTR layout, and it
+affects layout, text, and graphics.
+
+In RTL, anything that relates to time should be depicted as moving from
+right to left. For example, forward points to the left, and backwards
+points to the right.
+
+Mirroring layout
+~~~~~~~~~~~~~~~~
+
+When a UI is mirrored, these changes occur:
+
+- Text fields icons are displayed on the opposite side of a field
+- Navigation buttons are displayed in reverse order
+- Icons that communicate direction, like arrows, are mirrored
+- Text is usually aligned to the right
+
+In CSS, while it's possible to apply a rule for LTR and a separate one
+specifically for RTL, it's usually better to use CSS `Logical Properties <https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties>`_
+which provide the ability to control layout through logical, rather than
+physical mappings.
+
++---------------------------------------------------------+--------------------------------------------------+
+| Do | Don't do |
++---------------------------------------------------------+--------------------------------------------------+
+| ``margin-inline-start: 5px`` | ``margin-left: 5px`` |
++---------------------------------------------------------+--------------------------------------------------+
+| ``padding-inline-end: 5px`` | ``padding-right: 5px`` |
++---------------------------------------------------------+--------------------------------------------------+
+| ``float: inline-start`` | ``float: left`` |
++---------------------------------------------------------+--------------------------------------------------+
+| ``inset-inline-start: 5px`` | ``left: 5px`` |
++---------------------------------------------------------+--------------------------------------------------+
+| ``border-inline-end: 1px`` | ``border-right: 1px`` |
++---------------------------------------------------------+--------------------------------------------------+
+| ``border-{start/end}-{start/end}-radius: 2px`` | ``border-{top/bottom}-{left/right}-radius: 2px`` |
++---------------------------------------------------------+--------------------------------------------------+
+| ``padding: 1px 2px`` | ``padding: 1px 2px 1px 2px`` |
++---------------------------------------------------------+--------------------------------------------------+
+| ``margin-block: 1px 3px`` && ``margin-inline: 4px 2px`` | ``margin: 1px 2px 3px 4px`` |
++---------------------------------------------------------+--------------------------------------------------+
+| ``text-align: start`` or ``text-align: match-parent`` | ``text-align: left`` |
+| (depends on the context) | |
++---------------------------------------------------------+--------------------------------------------------+
+
+When there is no special RTL-aware property available, or when
+left/right properties must be used specifically for RTL, use the pseudo
+``:-moz-locale-dir(rtl)`` (for XUL documents) or ``:dir(rtl)`` (for HTML
+documents).
+
+For example, this rule covers LTR to display searchicon.svg 7 pixels
+from the left:
+
+.. code:: css
+
+ .search-box {
+ background-image: url(chrome://path/to/searchicon.svg);
+ background-position: 7px center;
+ }
+
+but an additional rule is necessary to cover RTL and place the search
+icon on the right:
+
+.. code:: css
+
+ .search-box:dir(rtl) {
+ background-position-x: right 7px;
+ }
+
+.. warning::
+
+ It may be inappropriate to use logical properties when embedding LTR
+ within RTL contexts. This is described further in the document.
+
+Mirroring elements
+~~~~~~~~~~~~~~~~~~
+
+RTL content also affects the direction in which some icons and images
+are displayed, particularly those depicting a sequence of events.
+
+What to mirror
+^^^^^^^^^^^^^^
+
+- Icons or animations that imply directionality or motion like
+ back/forward buttons or progress bars
+- Icons that imply text direction, like
+ `reader-mode.svg <https://searchfox.org/mozilla-central/rev/f9beb753a84aa297713d1565dcd0c5e3c66e4174/browser/themes/shared/icons/reader-mode.svg>`__
+- Icons that imply location of UI elements in the screen, like
+ `sidebars-right.svg <https://searchfox.org/mozilla-central/rev/74cc0f4dce444fe0757e2a6b8307d19e4d0e0212/browser/themes/shared/icons/sidebars-right.svg>`__,
+ `open-in-new.svg <https://searchfox.org/mozilla-central/rev/f9beb753a84aa297713d1565dcd0c5e3c66e4174/toolkit/themes/shared/icons/open-in-new.svg>`__,
+ `default theme's preview.svg <https://searchfox.org/mozilla-central/rev/f9beb753a84aa297713d1565dcd0c5e3c66e4174/toolkit/mozapps/extensions/default-theme/preview.svg>`__
+ or
+ `pane-collapse.svg <https://searchfox.org/mozilla-central/rev/74cc0f4dce444fe0757e2a6b8307d19e4d0e0212/devtools/client/debugger/images/pane-collapse.svg>`__
+- Icons representing objects that are meant to be handheld should look
+ like they're being right-handed, like the `magnifying glass
+ icon <https://searchfox.org/mozilla-central/rev/e7c61f4a68b974d5fecd216dc7407b631a24eb8f/toolkit/themes/windows/global/icons/search-textbox.svg>`__
+- Twisties in their collapsed state. Note that if the context in which
+ they appear is LTR (e.g. code in a devtools HTML view), they should
+ not be mirrored, even if the user might be using an RTL locale.
+
+What NOT to mirror
+^^^^^^^^^^^^^^^^^^
+
+- Text/numbers
+- Icons containing text/numbers
+- Icons/animations that are direction neutral
+- Icons that wouldn't look differently if they'd be mirrored, like `X
+ buttons <https://searchfox.org/mozilla-central/rev/a78233c11a6baf2c308fbed17eb16c6e57b6a2ac/devtools/client/debugger/images/close.svg>`__
+ or the `bookmark
+ star <https://searchfox.org/mozilla-central/rev/a78233c11a6baf2c308fbed17eb16c6e57b6a2ac/browser/themes/shared/icons/bookmark-hollow.svg>`__
+ icon, or any other symmetric icon
+- Icons that should look the same as LTR, like icons related to code
+ (which is always LTR) like
+ `tool-webconsole.svg <https://searchfox.org/mozilla-central/rev/74cc0f4dce444fe0757e2a6b8307d19e4d0e0212/devtools/client/themes/images/tool-webconsole.svg>`__
+- Checkmark icons
+- Video/audio player controls
+- Product logos
+- Order of size dimensions (e.g., ``1920x1080`` should not become
+ ``1080x1920``)
+- Order of size units (e.g., ``10 px`` should not become ``px 10``
+ (unless the size unit is localizable))
+
+How
+^^^
+
+The most common way to mirror images is by flipping the X axis:
+
+.. code:: css
+
+ transform: scaleX(-1);
+
+Or, if you're already using ``transform`` with a different value on the same
+element, you can also use `scale`:
+
+.. code:: css
+
+ scale: -1 1;
+
+Note that mirroring images that way doesn't work when the image is a part of
+an element with text using ``background-image``, because then the text would
+be mirrored along with the image, and the image would be positioned incorrectly.
+For such cases, try to use a different method for displaying the image,
+like having it as an element all on its own.
+If that's not possible, add a separate pre-mirrored image asset and specify
+it in a separate ``:dir(rtl)`` rule:
+
+.. code:: css
+
+ .element-with-icon {
+ background-image: url("path/to/image/image.svg");
+ }
+
+ .element-with-icon:dir(rtl) {
+ background-image: url("path/to/image/image-rtl.svg");
+ }
+
+For animations like a progress bar, when using ``@keyframes`` to change
+the ``transform: translateX()`` states, make sure to add a different
+``@keyframes`` suited for RTL, and target that in a separate ``:dir()`` rule:
+
+.. code:: css
+
+ #progressbar {
+ animation: progressbar-animation 1s linear infinite;
+ }
+
+ #progressbar:dir(rtl) {
+ animation-name: progressbar-animation-rtl;
+ }
+
+ @keyframes progressbar-animation {
+ 0% {
+ transform: translateX(-100px);
+ }
+ 100% {
+ transform: translateX(0);
+ }
+ }
+
+ @keyframes progressbar-animation-rtl {
+ 0% {
+ transform: translateX(100px);
+ }
+ 100% {
+ transform: translateX(0);
+ }
+ }
+
+Likewise, if you're using ``transform-origin``, make sure to specify the
+correct origin for RTL:
+
+.. code:: css
+
+ #progressbar {
+ transform-origin: 0 0;
+ }
+
+ #progressbar:dir(rtl) {
+ transform-origin: 100% 0;
+ }
+
+LTR text inside RTL contexts
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, in RTL locales, some symbols like ``/`` and ``.`` will be moved
+around and won't be displayed in the order that they were typed in. This
+may be problematic for URLs for instance, where you don't want dots to
+change position.
+
+Here's a non-exhaustive list of elements that should be displayed like
+they would be in LTR locales:
+
+- Paths (e.g., C:\\Users\\username\\Desktop)
+- Full URLs
+- Code and code containers (like the DevTools' Inspector or the CSS
+ rules panel)
+- about:config preference names and values
+- Telephone numbers
+- Usernames & passwords (most sites on the web expect LTR
+ usernames/passwords, but there may be exceptions)
+- Other text fields where only LTR text is expected
+
+To make sure these are displayed correctly, you can use one of the
+following on the relevant element:
+
+- ``direction: ltr``
+- ``dir="ltr"`` in HTML
+
+Since the direction of such elements is forced to LTR, the text will
+also be aligned to the left, which is undesirable from an UI
+perspective, given that is inconsistent with the rest of the RTL UI
+which has text usually aligned to the right. You can fix this using
+``text-align: match-parent``. In the following screenshot, both text
+fields (username and password) and the URL have their direction set to
+LTR (to display text correctly), but the text itself is aligned to the
+right for consistency with the rest of the UI:
+
+.. image:: about-logins-rtl.png
+ :alt: about:logins textboxes in RTL layout
+
+However, since the direction in LTR, this also means that the start/end
+properties will correspond to left/right respectively, which is probably
+not what you expect. This means you have to use extra rules instead of
+using logical properties.
+
+Here's a full code example:
+
+.. code:: css
+
+ .url {
+ direction: ltr; /* Force text direction to be LTR */
+
+ /* `start` (the default value) will correspond to `left`,
+ * so we match the parent's direction in order to align the text to the right */
+ text-align: match-parent;
+ }
+
+ /* :dir(ltr/rtl) isn't meaningful on .url, since it has direction: ltr, hence
+ * why it is matched on .container. */
+ .container:dir(ltr) .url {
+ padding-left: 1em;
+ }
+
+ .container:dir(rtl) .url {
+ padding-right: 1em;
+ }
+
+.. note::
+
+ The LTR rule is separate from the global rule to avoid having the
+ left padding apply on RTL without having to reset it in the RTL rule.
+
+Auto-directionality
+^^^^^^^^^^^^^^^^^^^
+
+Sometimes, the text direction on an element should vary dynamically
+depending on the situation. This can be the case for a search input for
+instance, a user may input a query in an LTR language, but may also
+input a query in a RTL language. In this case, the search input has to
+dynamically pick the correct directionality based on the first word, in
+order to display the query text correctly. The typical way to do this is
+to use ``dir="auto"`` in HTML. It is essential that
+``text-align: match-parent`` is set, to avoid having the text alignment
+change based on the query, and logical properties also cannot be used on
+the element itself given they can change meaning depending on the query.
+
+Testing
+~~~~~~~
+
+To test for RTL layouts in Firefox, you can go to about:config and
+set ``intl.l10n.pseudo`` to ``bidi``, or select the ``Enable "bidi" locale``
+option in the 3-dots menu in the :doc:`Browser Toolbox </devtools-user/browser_toolbox/index>`.
+The Firefox UI should immediately flip, but a restart may be required
+to take effect in some Firefox features and interactions.
+
+.. note::
+
+ When testing with ``intl.l10n.pseudo`` set to ``bidi``, you may see some
+ oddities regarding text ordering due to the nature of displaying LTR
+ text in RTL layout.
+
+ .. image:: about-protections-rtl.png
+ :alt: about:protections in RTL layout- English vs. Hebrew
+
+ This shouldn't be an issue when using an actual RTL build or language pack.
+
+How to spot RTL-related issues
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Punctuation marks should appear on the left side of a
+ word/sentence/paragraph on RTL, so if a *localizable* string appears
+ in the UI with a dot, colon, ellipsis, question or exclamation mark
+ on the right side of the text, this probably means that the text
+ field is forced to be displayed as LTR.
+- If icons/images/checkmarks do not appear on the opposite side of
+ text, when compared to LTR.
+- If buttons (like the close button, "OK" and "Cancel" etc.) do not
+ appear on the opposite side of the UI and not in the opposite order,
+ when compared to LTR.
+- If paddings/margins/borders are not the same from the opposite side,
+ when compared to LTR.
+- Although Hebrew uses ``1 2 3``, all the other RTL locales we support
+ should use ``١ ٢ ٣`` as digits. So if you see ``1 2 3`` on any such
+ locale, that likely indicates a bug.
+- If navigating in the UI using the left/right arrow keys does not
+ select the correct element (i.e., pressing Left selects an item on
+ the right).
+- If navigating in the UI using the Tab key does not focus elements
+ from right to left, in an RTL context.
+- If code is displayed as RTL (e.g., ``;padding: 20px`` - the semicolon
+ should appear on the right side of the code). Code can still be
+ aligned to the right if it appears in an RTL context.
+
+See also
+~~~~~~~~
+
+- `RTL Best
+ Practices <https://docs.google.com/document/d/1Rc8rvwsLI06xArFQouTinSh3wNte9Sqn9KWi1r7xY4Y/edit#heading=h.pw54h41h12ct>`__
+- Building RTL-Aware Web Apps & Websites: `Part
+ 1 <https://hacks.mozilla.org/2015/09/building-rtl-aware-web-apps-and-websites-part-1/>`__,
+ `Part
+ 2 <https://hacks.mozilla.org/2015/10/building-rtl-aware-web-apps-websites-part-2/>`__
+
+Credits
+~~~~~~~
+
+Google's `Material Design guide for
+RTL <https://material.io/design/usability/bidirectionality.html>`__