diff options
Diffstat (limited to '')
-rw-r--r-- | docs/code-quality/coding-style/rtl_guidelines.rst | 356 |
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>`__ |