Skip to content

Tweak .visually-hidden to use display:inline-block instead of absolute positioning#41474

Open
patrickhlauke wants to merge 2 commits into
mainfrom
patrickhlauke-tweak-visually-hidden
Open

Tweak .visually-hidden to use display:inline-block instead of absolute positioning#41474
patrickhlauke wants to merge 2 commits into
mainfrom
patrickhlauke-tweak-visually-hidden

Conversation

@patrickhlauke
Copy link
Copy Markdown
Member

@patrickhlauke patrickhlauke commented May 18, 2025

Description

Use display:inline-block instead of position:absolute for .visually-hidden

Motivation & Context

While tried and tested, the regular .visually-hidden styles have unintended consequences in certain scenarios, such as inside responsive tables - see #31885

As the position:absolute is used essentially to force the element to accept explicit width/height/clip even when it's currently inline, this new approach should have the same end result, but without causing any more accidental spacing.


See the redone example from #31885 (replacing the old .sr-only with .visually-hidden), with overrides that mimic the end result of this PR: https://codepen.io/team/bootstrap/pen/azzxqBZ (removing the overrides in the Pen's CSS shows the current broken behaviour: make the viewport/browser window narrow, and notice how - just like in the original #31885 issue - the visually hidden content in the last cell of the first row leads to whitespace to the right of the table that then results in a page-level horizontal scrollbar)


Suggest extensive testing of this, to make sure the change doesn't now cause other unintended consequences elsewhere. Suggest also testing on devices that are notoriously flaky ... like "does it work as expected on iOS/Safari with/without VoiceOver running".

Marking as a breaking change because it has the potential to break things if an author did heavily rely on the old styles for some reason.

Type of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Refactoring (non-breaking change)
  • Breaking change (fix or feature that would change existing functionality)

Checklist

  • I have read the contributing guidelines
  • My code follows the code style of the project (using npm run lint)
  • My change introduces changes to the documentation
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed

Live previews

Related issues

#31885

@ffoodd
Copy link
Copy Markdown
Contributor

ffoodd commented May 26, 2025

I think this needs various test cases for when a visually hidden element is a flex or grid child, for example.

Absolute position ensures context and flow would not be impacted, but I think switching to display could lead to layout changes.

I'll try to pack some cases.

@patrickhlauke
Copy link
Copy Markdown
Member Author

thanks @ffoodd that'd be super helpful ... hoping that there won't be any unforeseen side effects here...

@ffoodd
Copy link
Copy Markdown
Contributor

ffoodd commented Oct 22, 2025

I’m currently working on a CodePen aggregating every reduced test cases I can think of.
Seeking around old issues, I have a first thing to note: removing position: absolute will prevent clip from being applied.

But, FWIW, I also ran into #24906 which removed clip-path for paint issues on Chromium: playing with its reduced test case, I can confirm that this is not an issue anymore (tested on Edge / Ubuntu). So regarding clipping, I think we're safe if we (finally) drop clip and use clip-path: inset(50%) instead.

So, here's the reduced test cases collection on CodePen, using current 5.38 release and this PR's build.

As I thought, there're edge cases when used as grid or flex children (checked on Firefox). IMHO this should not exist, but as it was possible until this change, we can fear that someone used it…

At least, we now have a pen to play with!

@patrickhlauke
Copy link
Copy Markdown
Member Author

thanks for keeping the flame alive @ffoodd .. i know i've really been dropping off from my duties here, but ... life

@ffoodd
Copy link
Copy Markdown
Contributor

ffoodd commented Oct 22, 2025

So, after a few minutes digging around:

  • switching to clip-path does not seem buggy anymore 🎉
  • applying flex: none alongside other resets prevents flex layout from breaking;
  • applying grid-area: none somewhat prevents grid layout from breaking.

I'm not sure that's all to be done, but that a first step :)
And FWIW, using inline-block display in lieu of absolute positioning fixes every unwanted scrollbars cases in Chromium.

@ffoodd ffoodd force-pushed the patrickhlauke-tweak-visually-hidden branch from 341589b to 55f4be7 Compare October 22, 2025 14:00
@ffoodd
Copy link
Copy Markdown
Contributor

ffoodd commented Oct 22, 2025

I rebased the branch and pushed some more improvements:

  1. Switch to clip-path: the de-facto standard since clip is deprecated. Previous performance issues in Chromium seems to have been fixed.
  2. Add flex: none as another reset to protect against layout issues when .visually-hidden is used in a flex container.
  3. Add contain: strict as an overall rule, since anything that could be in a .visually-hidden element should not have any impact regarding layout, paint nor content outside of its containment.

The only edge case I couldn't deal with is when .visually-hidden is a grid child. But I wonder who on earth could set a visually hidden element on a grid?

If I'm missing any case, feel free to fork the CodePen mentioned above to add your case.

@ffoodd ffoodd force-pushed the patrickhlauke-tweak-visually-hidden branch from 55f4be7 to cdc89a0 Compare October 22, 2025 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Needs review

Development

Successfully merging this pull request may close these issues.

3 participants