Focus changes landing in Firefox 78
I’ve been spending a bunch of time side-tracked working on focus-related things these last couple weeks, and there have been a few significant changes that I hope will make both web developers and users happier.
There are various goals that I tried to accomplish, I will try to explain the reasoning for them, and then drop an executive summary of the changes below.
First, there will be no change for natively-styled controls. These are the default and work reasonably well, with all the caveats that native theming brings. So to the extent possible they should remain looking native / we shouldn’t regress their rendering.
With that out of the way…
Preventing missing focus indicators by default
This was my main goal (that is, fixing bug 1311444).
Different platforms have different conventions on when to show outlines (more on this below). One thing is clear though: When navigating using the keyboard, missing focus indicators are a bug.
When these are hidden by default by the browser, it should be fixed, and that’s
what I did. This was a bit harder than it seems (as usual) because we had to
enable outline-style: auto
everywhere first.
The TLDR is that form controls have outline-style: auto
by default in the
UA style sheet when :-moz-focusring
applies. This matches both Blink and
WebKit, as far as I can tell.
This is useful because using the auto
value allows us to have magic behavior
for themed controls that draw their own focus indicators (so as to not draw both
a “web” outline and the theme’s outline), while allowing authors to override it,
and while displaying the outlines in non-themed form controls.
Improving stylability
My other main goal was to improve stylability and interoperability with other browsers. This one is the one that I hope will bring more joy to web developers :)
Firefox has some, er, interesting behavior with respect to focus indicators, mostly due to the unstyled buttons wanting to look like the native Windows buttons.
These span from the stylable but ugly inner border on buttons
(::-moz-focus-inner
),
from the totally unstylable and un-removable inner focus ring for <select>
elements, for which
people use terrible hacks to
hide.
These indicators were also annoying for users too, specially on Android, where WebKit-based browsers dominate, and web developers don’t usually bother removing them if they don’t want them. The mobile team and users had filed multiple bugs about this.
I believe that we should give web developers a way to style their controls as they please, and that we shouldn’t make web developers go out of their way to get a nice experience on Firefox.
The biggest change here is that un-themed form controls no longer show “inner”
focus indicators (like ::-moz-focus-inner
). That is, setting
-moz-appearance: none
(or background, or borders), on your <select>
/ <button>
becomes enough to remove these. This is again something that we
could only do after fixing the missing default focus indicators. Now the inner
indicator is effectively superseded by the outline
.
Another related patch that I plan to
land is to make the
::-moz-focus-outer
pseudo-element a no-op, using outline
instead. This
pseudo-element (which only applies to <input type=range>
) was a hack to show
outlines on non-natively styled <input type=range>
by default. The previous
work also effectively supersedes it, and allows authors and the implementation
to just use outline
for it, as one would expect.
Bonus (hopefully): Linux outline changes
This change has still not landed, but I hope the Linux maintainers agree with it, as the behavior matches (to the best of my knowledge) that of GTK.
Firefox’s focus model has two switches, historically, based on platform conventions:
-
Whether focus rings are shown on all focused elements unconditionally. This is true for Linux, dependent on a system setting on Windows (but default false), and false everywhere else. Additionally, once you move the focus using the keyboard on any platform, it becomes true for that window.
-
Whether, if the above switch is false, focus indicators are shown for each element, unless it’s focused via mouse / pointer, and the element is a link, a
<video>
or an<audio>
element. Yeah, that’s the condition, really. This is true for all platforms except Windows.
That means that on Linux you get all the outlines, all the time, regardless of system settings or whether you’ve used the keyboard to navigate the page. This is very annoying, as you get outlines even when clicking links on Google.
My proposal is to align with GTK’s behavior (which also happens to be
Windows’ behavior by default). That is, outlines will only show once you’ve
navigated by keyboard. You will still be able to go back to the current
behavior by toggling the browser.display.show_focus_rings
preference back to
true
in about:config
.
Questions? Issues? Follow-up suggestions?
Please test this stuff out on Nightly, and if you disagree with some of the changes / think they’re harmful for either users or developers, or such things, please reach out! Either Bugzilla, email or Twitter works :)