fix(ui): let select dropdowns paint above what follows them - #450
Merged
Conversation
Adapts to @nextcloud/vue 9.11 rather than pinning away from it, and
takes the pin off.
The eleven E2E failures were never an unstable element. The Playwright
trace from CI says so directly:
- locator resolved to <li class="vs__dropdown-option">
- attempting click action
- element is visible, enabled and stable <- stable
- scrolling into view if needed
- <div class="visibility-rule-row__actions"> ... intercepts
The option was VISIBLE, ENABLED AND STABLE. The click was intercepted by
the element painted on top of it.
Both failing areas are the same shape. A column of blocks; a select in
one of them; its dropdown opens downward over the LATER siblings; those
siblings have no stacking context, so they paint last and win:
conditional-visibility <div class="visibility-rule-row__actions">
dashboard-sharing <div class="dashboard-config__field ...public">
<p class="dashboard-config__hint">
9.10's floating-label rework (#8570) is what made it reachable: the
control got taller, so the dropdown now extends far enough to reach them.
That is why 9.9.0 was green and 9.11 is not, without either version being
broken.
The fix is a stacking context on the block that holds the select, in both
places. Nothing else changes, and the dropdown is only raised where a
select actually lives.
⚠️ This could not be verified locally. The same specs PASS against a
seeded launchpad-demo on :8605 built with 9.11 -- the layout there does
not put the dropdown over those siblings. The trace from CI is the
evidence this rests on, and CI is where it has to be confirmed.
Contributor
Quality Report — ConductionNL/launchpad @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| composer | ✅ | ✅ 104/104 | |||
| npm | ✅ | ✅ 526/526 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | 🚨 NO VERDICT — enabled but never ran | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-30 16:08 UTC
Download the full PDF report from the workflow artifacts.
rubenvdlinde
added a commit
that referenced
this pull request
Aug 30, 2026
…e modal mask (#452) The stacking fix in #450 was built on the trace and was not enough. E2E on 9.11 with it merged is still 127 passed / 11 failed, the same eleven. The second trace names a bigger interceptor than the first one did: 70x class="modal-mask" 24x class="checkbox-content__text checkbox-radio-switch__text" 20x class="dashboard-config__hint" 18x class="visibility-rule-row__actions" 8x class="dashboard-config__field dashboard-config__public" is Nextcloud's own modal backdrop, and it dominates. A z-index inside the modal cannot lift the dropdown above the mask if the dropdown is no longer INSIDE the modal: 9.10's NcSelect appears to render its menu outside the dialog (appended/teleported), which puts it beneath the backdrop in stacking order. That is a different defect from the one #450 addressed, and it needs the menu kept in place or lifted above the mask -- not more per-component z-index. The CSS from #450 is KEPT. Those three smaller interceptors are real, the rule is documented against its trace, and it is inert while the dropdown renders inline on 9.9.0. So the pin goes back while that is worked out, because leaving development red to hold a position is not a trade worth making. This is not a decision that 9.11 is unusable -- it is a decision not to sit red while the portal behaviour is understood. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adapts to the new NcSelect rather than pinning away from it, and takes 9.11 again.
The failures were not what their messages said
The Playwright trace from the failing CI run shows the option was found, visible, enabled and stable — and the click was intercepted:
Both are the same bug in two places. These containers are flex columns: the select sits in one block, more content follows. The dropdown opens downward out of its block and lands on the next one — and because that is a later sibling with no stacking context of its own, it paints on top and swallows the click.
Why 9.10 exposed it
fix(NcSelect): floating label design using NcTextField(#8570) makes the control taller, so the dropdown now reaches far enough down to touch what follows. On 9.9.0 it stopped short.So the pin hid a latent stacking bug in our own CSS, rather than avoiding a library defect. That is why it "fixed" eleven tests without anyone changing a selector.
The fix
Give the block that holds the select its own stacking context. Only that block is raised; nothing else moves.
Verification
format,stylelintandeslintexit 0 and webpack compiles. The interception is layout-dependent and does not reproduce on my isolated instance — which is exactly why the earlier local run misled me — so CI is the check that matters here, and it is the same job that produced the trace this fix is built on.