Our target is to make sure that when the firefox browser is set to RTL mode the fullscreen icon flips as well to follow suite.
Introduction
When Firefox is set to an RTL (right-to-left) language like Arabic, the fullscreen icon inside the zoom sidebar still looks like it's designed for LTR (left-to-right) languages. It should be mirrored/flipped to match RTL direction.
What's RTL?
Languages like Arabic and Hebrew read from right to left. Browsers have a concept called dir="rtl" that flips the layout. Icons that have a "direction" to them (like arrows, expand icons) should also flip to feel natural.
The plan:
- First, let's find where the zoom sidebar and its fullscreen icon live in the Firefox codebase
- See how the icon is currently being used
- Figure out how to make it flip for RTL
You can set your firefox browser to read from right-to-left using this in the console CTRL+SHIFT+ALT+I
document.documentElement.setAttribute("dir", "rtl")
1. Find the files:
Zoom sidebar HTML file
We can start by searching Searchfox (Mozilla's online code search) for terms like "zoom sidebar fullscreen" and "appmenu zoom controls." That search led me to appmenu-viewcache.inc.xhtml, and inside it I saw this markup:
<toolbaritem id="appMenu-zoom-controls" class="subviewbutton toolbaritem-combined-buttons" closemenu="none">
<label class="toolbarbutton-text" data-l10n-id="appmenuitem-zoom"/>
...
<toolbarbutton id="appMenu-fullscreen-button2"
class="subviewbutton subviewbutton-iconic"
data-l10n-id="appmenuitem-fullscreen"
type="checkbox"
tooltip="dynamic-shortcut-tooltip">
<observes element="View:FullScreen" attribute="checked"/>
</toolbarbutton>
</toolbaritem>
FLUENT: Firefox uses the fluent localization system (more in later articles)
appmenuitem-zoom is the localization label for the word "Zoom" that sits above the row of buttons (-, 100%, +, fullscreen). It's a distinctive, low-noise string and searching for it locally in VS code is a good way to land on the exact zoom row markup without pulling in unrelated matches.
Let's start by searching for the zoom sidebar files using this grep syntax:
grep -rn "appmenuitem-zoom" browser/base/content/
What we found:
The fullscreen icon lives inside the zoom row of the hamburger menu (☰). In the HTML file at browser/base/content/appmenu-viewcache.inc.xhtml, the button is:
<toolbarbutton id="appMenu-fullscreen-button2"
class="subviewbutton subviewbutton-iconic"
data-l10n-id="appmenuitem-fullscreen"
type="checkbox"
tooltip="dynamic-shortcut-tooltip">
<observes element="View:FullScreen" attribute="checked"/>
</toolbarbutton>
The ID of the fullscreen button in the zoom row of the hamburger menu is appMenu-fullscreen-button2.
This is very important to keep in mind.
Zoom sidebar CSS file
Let us find the CSS file where its icon is defined using this grep syntax
grep -rn "appMenu-fullscreen-button2" browser/themes/
What we found:
This finds browser/themes/shared/menupanel.css, the file where the fullscreen icon's image is actually set, which is where we will make our fix.
The fullscreen icon
grep -rn "fullscreen.svg" browser/themes/shared/
We can see that there is an image fullscreen.svg that serves as the icon, located at browser/themes/shared/icons/fullscreen.svg and gets applied via browser/themes/shared/menupanel.css
Here, we see the fullscreen icon, which looks like pointing outward from a center.
Left-to-right
Right-to-left
2. Figuring out how to make it flip
We need to take note of two things that will guide us to the actual fix.
From what we saw here, we know that the zoom icon could live inside of toolbarbutton
<toolbarbutton id="appMenu-fullscreen-button2"
class="subviewbutton subviewbutton-iconic"
data-l10n-id="appmenuitem-fullscreen"
type="checkbox"
tooltip="dynamic-shortcut-tooltip">
<observes element="View:FullScreen" attribute="checked"/>
</toolbarbutton>
According to Mozilla guidelines, <toolbarbutton> is a Firefox custom element (defined in toolkit code, not in this XHTML file), and it generates its own internal "anonymous content" at runtime; meaning the <image class="toolbarbutton-icon"> and <label class="toolbarbutton-text"> children are injected by the custom element's own implementation at render time.
We can confirm the actual DOM structure using
document.getElementById("appMenu-fullscreen-button2").outerHTML
This returns
<toolbarbutton xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="appMenu-fullscreen-button2" class="subviewbutton subviewbutton-iconic" data-l10n-id="appmenuitem-fullscreen" type="checkbox" tooltip="dynamic-shortcut-tooltip" label="Full screen">
<observes element="View:FullScreen" attribute="checked"/>
<image class="toolbarbutton-icon" type="checkbox" label="Full screen"/>
<label class="toolbarbutton-text" crop="end" flex="1" value="Full screen"/>
</toolbarbutton>
Now, we know <toolbarbutton> elements in Firefox's UI don't render the icon directly on themselves; they render it inside a child element with the class .toolbarbutton-icon
We can confirm this once again by inspecting the element in the Browser Toolbox, when we run
document.getElementById("appMenu-fullscreen-button2").querySelector(".toolbarbutton-icon")
it returned <image class="toolbarbutton-icon" type="checkbox" label="Full screen">, confirming that's where the icon image actually lives.
So the scale or fix has to target that child element .toolbarbutton-icon, NOT the outer <toolbarbutton>, or else nothing visible would flip.
According to Mozilla guidelines, which explicitly says icons implying direction should mirror in RTL, and gives this exact pattern as the recommended technique:
.element-with-icon:dir(rtl) {
transform: scaleX(-1); /** scale: -1 1; does the same horizontal flip **/
}
Now, we know what our fix should be
The Fix
Therefore, the fix is for us to add a CSS rule that uses :dir(rtl) to flip the fullscreen icon horizontally when in RTL mode.
The file to edit is: browser/themes/shared/menupanel.css
/* To flip an icon for RTL using scale: */
#appMenu-fullscreen-button2:dir(rtl) > .toolbarbutton-icon {
scale: -1 1;
}
This means "when this specific button is inside an RTL context, flip its icon child horizontally."
Summary
When you open the hamburger menu (☰) in Firefox, there's a zoom row that looks like: Zoom — [-] 100% [+] [⤢]. That last icon [⤢] is the fullscreen button (appMenu-fullscreen-button2).
In Arabic and other RTL languages, this icon doesn't flip to match the reading direction, it stays the same as in English (LTR). It should be mirrored.
Find the patch here: https://phabricator.services.mozilla.com/D309258
Find the Bug here: https://bugzilla.mozilla.org/show_bug.cgi?id=2029514


Top comments (1)
I found it interesting that the fullscreen icon in the Firefox browser doesn't automatically flip when the browser is set to RTL mode, and I appreciate the detailed steps you've outlined to identify the relevant files in the codebase. I've had similar experiences working with RTL languages, and it's crucial to consider the directionality of icons to maintain a natural user experience. Have you considered using a CSS technique like
transform: scale(-1, 1)to flip the icon for RTL mode, or will you be creating a separate icon for RTL languages?