I came across a strange behavior when it comes to popups that are scroll-able and that contain certain elements in them, such as buttons/links or inputs, for example.
Context:
I have this setup in my css. Very simple overwrites of the existing outsystems popup classes:
The business requirement needs for popups to grow up to a certain height, as its content grows, and past this max-height, the popup should be scroll-able, which is why I added the "overflow-y: scroll" rule.
This works fine, and the popup does become scroll-able when it needs to.
For extra content, the popup will be used with a separate Block built with a title, description, and actions placeholders.
The issue comes when a particular popup, with enough content that it does become scroll-able, contains elements like buttons. When such elements are present in the popup, once the popup is opened, these elements are getting focused without me programmatically setting its focus state whatsoever.
For example, this popup should be opened like so:
But instead, it's opening in this state (completely scrolled to the bottom):
If I run "document.activeElement" as the popup opens, it does indeed return that this link at the bottom is being automatically focused, which explains why the popup opens being scrolled all the way to the bottom.
However, I did not add any code in my app to make this element be focused once the popup opens, this is happening automatically. I even tested on a personal environment in a fresh new app, and the behavior is the exact same.
I tried to add a a dummy expression on the top of the popup (with a tabindex=-1 property), and target it with document.querySelector('.dummy').focus() once it opens, in order to force focus on this element, but it doesn't seem to work. It only worked by doing it manually in the browser console, which is obviously not a solution.
Is there a way to prevent this autofocus behavior from happening?
In mobile (and Reactive Web) there’s no PopupEditor widget and no OnReady event for a popup, so you need a slightly different approach. The underlying issue is the same, though: a focusable element inside your scrollable popup is getting focus automatically, and the container scrolls to make it visible.
You basically have two options:
In mobile / Reactive, your “popup” is typically:
In both cases you can still use SetFocus; you just have to call it from the client action that opens the popup, or from a small “init” client action inside the popup block, instead of an OnReady.
Add a focusable element at the top of the popup content For example:
tabindex="-1"
Give that widget a Name, so you can reference its Id.
Id
In the client action that you use to open the popup (e.g. on Click of the “Open popup” button):
True
Show
Example flow (mobile / Reactive):
OpenPopup
Assign
ShowPopup = True
SetFocus
WidgetId = PopupTopElement.Id
If the popup content is complex and you see SetFocus happening too early, wrap it in a tiny delay using JavaScript or a separate client action triggered by a boolean, but in many cases calling SetFocus right after opening is enough. OutSystems UI team explicitly suggests this approach as a workaround for unwanted autofocus in mobile components DropdownSearch and DropdownTags receive autofocus when entering a screen.
Make sure no other focus operation runs after that:
autofocus
focus()
This way, you “win” the focus race and keep the scroll at the top of the popup.
On mobile, some UI patterns (e.g. DropdownSearch/Tags) still grab focus automatically due to the underlying library, even after fixes for desktop DropdownSearch and DropdownTags receive autofocus when entering a screen. Similar behavior can happen with inputs/buttons in your popup.
If you can’t reliably push focus to the top element, you can try to:
DropdownTogglePopup
This doesn’t give you perfect control, but can reduce the chances that an element at the bottom is focused first.
document.querySelector('.dummy').focus()
In mobile / Reactive:
That’s exactly why OutSystems UI recommends using SetFocus with the right timing in the screen lifecycle as the workaround, and not just arbitrary JS DropdownSearch and DropdownTags receive autofocus when entering a screen.
Even in mobile (no Popup OnReady):
That’s the most practical way to prevent the bottom button/link from being auto-focused and the popup from opening scrolled to the bottom.
This autofocus + scroll-to-bottom behavior is coming from the browser’s native focus handling combined with the popup being scrollable, not from anything specific you coded in the app. Because the popup is part of the same document as the page (OutSystems Traditional Web popup, or a custom modal), when it opens:
overflow-y: scroll
You’re basically seeing the same accessibility behavior as when you tab into a long form: the viewport (or scrollable container) moves to ensure the focused element is visible.
To control this in OutSystems, you have to explicitly manage focus when the popup opens. The key point is when you call focus() / SetFocus:
Below are approaches that work well in OutSystems O11.
OutSystemsUI provides a client action SetFocus exactly for this kind of problem. When using the Popup Editor / Popup Widget:
Inside the popup content, add a focusable element at the top:
Give that widget a known Name (so it has a predictable ID).
Name
In the popup’s OnReady client action:
WidgetId
Example:
WidgetId = MyTopLink.Id
This forces the initial focus into the top of the popup right after it is rendered, instead of letting the browser pick a focusable element at the bottom. That is essentially the same solution described in the “Tab Navigation does not transfer focus to Popup” topic, just adapted to your case Tab Navigation does not transfer focus to Popup unless I click inside.
If this popup is a custom modal with your CSS (.popup-dialog, .popup-backdrop) instead of the built‑in Popup Editor:
.popup-dialog
.popup-backdrop
You mentioned:
“I tried to add a dummy expression at the top with tabindex=-1 and run document.querySelector('.dummy').focus() once it opens, but it doesn’t seem to work. It only worked from the browser console.”
tabindex=-1
Typical reasons in OutSystems:
<span>
To fix that with JS (if needed):
<button>
<a>
<input>
tabindex="0"
setTimeout(function() { var el = document.querySelector('.dummy'); if (el) el.focus(); }, 0);
But in O11, it’s cleaner to use SetFocus instead of custom JS, because it’s designed to run at the correct time in the client lifecycle focus on an input field when opening the popup.
Check the elements inside the popup for anything that might be stealing focus:
Make sure the only focus‑setting logic that runs when the popup opens is the SetFocus for your chosen top element.
Once you start managing focus in a scrollable popup, it’s also good practice to prevent tabbing into elements “behind” the popup while it’s open. On the forums people use:
tabindex
inert
This doesn’t directly fix your scroll problem, but it keeps keyboard navigation consistent.
That will override the browser’s automatic focusing of a button/link near the bottom and keep your scrollable popup opening at the top, in the state you want.