Skip to content

Fix outline: auto in user agent style sheets - #1740

Merged
webkit-commit-queue merged 1 commit into
WebKit:mainfrom
nt1m:focusring
Mar 24, 2026
Merged

webkit-commit-queue merged 1 commit into
WebKit:mainfrom
nt1m:focusring

Conversation

@nt1m

@nt1m nt1m commented Jun 23, 2022 •

Copy link
Copy Markdown
Member

a8ca03b

Fix outline: auto in user agent style sheets
https://bugs.webkit.org/show_bug.cgi?id=241102
rdar://94116168

Reviewed by Darin Adler.

It turns out the focus ring width in RenderTheme does not match the
visible width on macOS, which leads to platformFocusRingOffset() being
too wide. Fix this and remove negative outline-offset hacks from user
agent style sheets. We also rename platformFocusRingOffset() to
platformFocusRingWidthOffset() to avoid confusion with outline-offset.

We change outline-width on focus in
imported/blink/transitions/transition-shape-outside-crash.html as
otherwise there is no transition anymore as html.css no longer does
that.

We also properly reflect Adwaita as having a width of 2 now. And while
this is correct and helps for some tests it also clashes with the
default of outline-width. Bug 310543 tracks this for Adwaita
maintainers.

In RenderImage we make the macOS code path the shared code path. Since
the user agent style sheet no longer sets the default color, this
preserves that behavior for image maps on other ports.

Test: LayoutTests/fast/forms/input-search-focusring.html
Canonical link: https://commits.webkit.org/309812@main

1e6e341

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows Apple Internal
✅ 🧪 style ✅ 🛠 ios   🛠 mac ✅ 🛠 wpe   🛠 win ⏳ 🛠 ios-apple
✅ 🧪 bindings ✅ 🛠 ios-sim   🛠 mac-AS-debug   🧪 wpe-wk2   🧪 win-tests ⏳ 🛠 mac-apple
✅ 🧪 webkitperl   🧪 ios-wk2   🧪 api-mac   🧪 api-wpe ⏳ 🛠 vision-apple
  🧪 ios-wk2-wpt   🧪 api-mac-debug   🛠 gtk3-libwebrtc
  🧪 api-ios   🧪 mac-wk1   🛠 gtk
  🛠 ios-safer-cpp   🧪 mac-wk2   🧪 gtk-wk2
✅ 🛠 vision   🧪 mac-AS-debug-wk2   🧪 api-gtk
✅ 🛠 vision-sim   🧪 mac-wk2-stress   🛠 playstation
✅ 🛠 🧪 unsafe-merge   🧪 vision-wk2   🧪 mac-intel-wk2
✅ 🛠 tv   🛠 mac-safer-cpp
  🛠 tv-sim
  🛠 watch
  🛠 watch-sim

@nt1m nt1m self-assigned this Jun 23, 2022
@nt1m nt1m added CSS Cascading Style Sheets implementation WebKit Nightly Build labels Jun 23, 2022
@nt1m
nt1m requested a review from pxlcoder June 23, 2022 21:11
@nt1m
nt1m force-pushed the focusring branch 3 times, most recently from aeb77c2 to c40408f Compare June 23, 2022 21:51
@webkit-early-warning-system webkit-early-warning-system added the merging-blocked Applied to prevent a change from being merged label Jun 23, 2022
darinadler

This comment was marked as resolved.

@nt1m
nt1m marked this pull request as draft October 17, 2022 18:16
@nt1m nt1m removed the merging-blocked Applied to prevent a change from being merged label Feb 18, 2026
@webkit-early-warning-system

This comment was marked as outdated.

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Feb 18, 2026
@nt1m nt1m removed the merging-blocked Applied to prevent a change from being merged label Feb 18, 2026
@webkit-early-warning-system

This comment was marked as outdated.

@nt1m
nt1m marked this pull request as ready for review February 18, 2026 11:12
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Feb 18, 2026

@darinadler darinadler left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t understand why fixing macOS is best done by changing all platforms other than iOS.

@@ -138,6 +138,7 @@ class RenderThemeIOS final : public RenderThemeCocoa {
Color platformActiveSelectionBackgroundColor(OptionSet<StyleColorOptions>) const final;
Color platformInactiveSelectionBackgroundColor(OptionSet<StyleColorOptions>) const final;
Color platformFocusRingColor(OptionSet<StyleColorOptions>) const final;
float platformFocusRingWidth() const final { return 3; }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does this number 3 come from? How was it determined? I think we need a comment, not just an unexplained constant. This was already true in the old code.

Is there a good reason for the number to be in the header rather than in the .cpp file?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is matching +[UIFocusRingStyle borderThickness], which we use in GraphicsContextCG::drawFocusRing.

It would be nice to have platformFocusRingWidth and drawFocusRing call into the same method.

Comment thread Source/WebCore/rendering/RenderTheme.h Outdated
@@ -200,8 +200,8 @@ class RenderTheme {

WEBCORE_EXPORT Color focusRingColor(OptionSet<StyleColorOptions>) const;
virtual Color platformFocusRingColor(OptionSet<StyleColorOptions>) const { return Color::black; }
static float platformFocusRingWidth() { return 3; }
static float platformFocusRingOffset(float outlineWidth) { return std::max<float>(outlineWidth - platformFocusRingWidth(), 0); }
virtual float platformFocusRingWidth() const { return 5; }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does this number 5 come from? How was it determined? I think we need a comment, not just an unexplained constant. This was already true in the old code.

Is there a good reason for the number to be in the header rather than in the .cpp file?

Why is this number 5 a new default for all themes other than iOS? The change log and bug title both talk about macOS, but we’re changing it here everywhere except for iOS. I presume there is a good reason for this, but I don’t know what it is.

Why does this need to be determined at runtime and use a virtual function? I don’t think I understand why some things in RenderTheme.h are simply constants or done with #if and others are based on virtual functions and derived classes at runtime. Do we actually need the same binary to support multiple themes? Seems like this is a leftover of an unusual past choice and it would be nice to move in the right direction.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both of these values were previously in html.css, I just reflected those. Let me see if I can find out more about the rationale

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think macOS should also be 3, matching the value in AppKit. Sadly that constant isn't exposed like the UIKit one.

I believe the 5px from before was because of the outline-offset of -2px on macOS only, which is now being removed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a dim memory of the reason for the -2px that might be helpful.

A long time ago, the way Mac focus rings were rendered, there was a part of the ring that visually didn’t look like it was part of the ring, but was a faint trailing off bit of it, kind of like a barely visible aura or light shadow. Conceptually the ring’s thickness was only 3px, but in terms of invalidation and repainting there was some effect outside the 3px, I think it extended 2px further. We needed the web engine to know about this so it could properly paint the rings when they appeared and disappeared without leaving behind residue, but it didn’t make sense to represent this as part of the outline thickness. At the time, with a less sophisticated understand of CSS than the rest of you, I thought it was important to both know where the visual extent of the outline ended (3px out) and where the complete rendering extent ended (2px further out). I seem to recall that the rectangle you would pass in needed to be outset by the 3px, but the actual drawing would go 2px further out.

I don’t know if this memory is correct, but if so, has this changed? If it has, when? If not, do we have a new solution to this old problem? Or another way of asking this is: What is the correct way to express this kind of thing in our CSS and rendering machinery?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see how this made sense with the slight 3D border we had pre-liquid glass, but with liquid glass, the border is no longer semi-transparent, so the focusring no longer shows underneath:

image

I checked using the digital color meter, and the border-color is identical with or without the focusring.

I'll change the focusring to be 3px instead.

@nt1m nt1m removed the merging-blocked Applied to prevent a change from being merged label Feb 26, 2026
@webkit-early-warning-system

This comment was marked as outdated.

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Feb 26, 2026
@annevk annevk self-assigned this Mar 23, 2026
@webkit-early-warning-system

This comment was marked as outdated.

@webkit-early-warning-system

This comment was marked as outdated.

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Mar 23, 2026
@annevk annevk removed the merging-blocked Applied to prevent a change from being merged label Mar 23, 2026
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Mar 23, 2026
@annevk annevk removed the merging-blocked Applied to prevent a change from being merged label Mar 23, 2026
@annevk
annevk requested a review from a team as a code owner March 23, 2026 15:59
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Mar 23, 2026
@annevk annevk removed the merging-blocked Applied to prevent a change from being merged label Mar 23, 2026
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Mar 23, 2026
@annevk annevk removed the merging-blocked Applied to prevent a change from being merged label Mar 24, 2026
@annevk annevk changed the title Fix outline: auto outline-offset being inflated on macOS Fix outline: auto in user agent style sheets Mar 24, 2026
@annevk annevk added the unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing label Mar 24, 2026
https://bugs.webkit.org/show_bug.cgi?id=241102
rdar://94116168

Reviewed by Darin Adler.

It turns out the focus ring width in RenderTheme does not match the
visible width on macOS, which leads to platformFocusRingOffset() being
too wide. Fix this and remove negative outline-offset hacks from user
agent style sheets. We also rename platformFocusRingOffset() to
platformFocusRingWidthOffset() to avoid confusion with outline-offset.

We change outline-width on focus in
imported/blink/transitions/transition-shape-outside-crash.html as
otherwise there is no transition anymore as html.css no longer does
that.

We also properly reflect Adwaita as having a width of 2 now. And while
this is correct and helps for some tests it also clashes with the
default of outline-width. Bug 310543 tracks this for Adwaita
maintainers.

In RenderImage we make the macOS code path the shared code path. Since
the user agent style sheet no longer sets the default color, this
preserves that behavior for image maps on other ports.

Test: LayoutTests/fast/forms/input-search-focusring.html
Canonical link: https://commits.webkit.org/309812@main
@webkit-commit-queue

Copy link
Copy Markdown
Collaborator

Committed 309812@main (a8ca03b): https://commits.webkit.org/309812@main

Reviewed commits have been landed. Closing PR #1740 and removing active labels.

@webkit-commit-queue
webkit-commit-queue merged commit a8ca03b into WebKit:main Mar 24, 2026
@webkit-commit-queue webkit-commit-queue removed the unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing label Mar 24, 2026
@nt1m
nt1m deleted the focusring branch March 24, 2026 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CSS Cascading Style Sheets implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants