Repository navigation
Modals show below full-screened cards #1360
Copy link
Copy link
Closed
Labels
Priority: MediumValid bug or well-defined request with moderate impact or a workaround.Valid bug or well-defined request with moderate impact or a workaround.ai-triage:doneMarks an issue whose AI triage workflow is complete.Marks an issue whose AI triage workflow is complete.
Description
System details
Output of sessionInfo():
R version 4.6.1 (2026-06-24)
Platform: x86_64-apple-darwin23.6.0
Running under: macOS Sonoma 14.6.1
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /usr/local/Cellar/r/4.6.1/lib/R/lib/libRlapack.dylib; LAPACK version 3.12.1
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
time zone: America/Santiago
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] bslib_0.12.0 shiny_1.14.0
loaded via a namespace (and not attached):
[1] jsonlite_2.0.0 dplyr_1.2.1 compiler_4.6.1 promises_1.5.0 tidyselect_1.2.1 Rcpp_1.1.2 later_1.4.8
[8] jquerylib_0.1.4 fastmap_1.2.0 mime_0.13 R6_2.6.1 generics_0.1.4 curl_8.0.0 httr2_1.3.0
[15] tibble_3.3.1 ellmer_0.4.2 pillar_1.11.1 rlang_1.3.0 cachem_1.1.0 httpuv_1.6.17 fs_2.1.0
[22] sass_0.4.10 S7_0.2.2 otel_0.2.0 memoise_2.0.1 cli_3.6.6 withr_3.0.3 magrittr_2.0.5
[29] digest_0.6.39 rstudioapi_0.19.0 xtable_1.8-8 lifecycle_1.0.5 coro_1.1.0 vctrs_0.7.3 glue_1.8.1
[36] tools_4.6.1 pkgconfig_2.0.3 htmltools_0.5.9
Example application or steps to reproduce the problem
Minimal reproducible example:
library(shiny)
library(bslib)
ui <- page_fillable(
card(max_height = 300,
full_screen = TRUE,
card_header("Card example with fullscreen + modal"),
card_body(
p("Full screen this card first, then press", em("open modal")),
actionButton("open_modal", "Open modal"),
actionButton("show_notification", "Show notification")
)
)
)
server <- function(input, output, session) {
observeEvent(input$open_modal, {
showModal(
modalDialog(
title = "Detail",
"Modal content.",
easyClose = TRUE,
footer = modalButton("Close")
)
)
})
observeEvent(input$show_notification, {
showNotification("This is a sample notification.", type = "message")
})
}
shinyApp(ui, server)Describe the problem in detail
When making a bslib::card() show fullcreen, and then invoking a modal window with showModal(), modal appears below the full screen card. It should show up on top of the modal, as it is an interface element created after the full screen card. They should show on top of any other element, just like notifications currently do (this makes me believe this is a Shiny bug, not a bslib bug).
Minimal reproducible example shows exactly this behavior. Maybe Z-value of modal window should be higher than the full-screen card's.
Metadata
Metadata
Assignees
Labels
Priority: MediumValid bug or well-defined request with moderate impact or a workaround.Valid bug or well-defined request with moderate impact or a workaround.ai-triage:doneMarks an issue whose AI triage workflow is complete.Marks an issue whose AI triage workflow is complete.
Activity
gadenbuie commentedon Oct 5, 2026
Thanks @bastianolea. This turns out to be a bslib issue. Bootstrap assigns specific z-index levels to different element types
z-indexWe are currently using 1070 for the full screen card, which means that it has higher z-index and shows above any modals. Reducing the full screen card z-index to 1055 would allow the modal to appear above the card, but it might introduce other problems. I'm looking into this...
gadenbuie commentedon Oct 5, 2026
Proposed stacking
Treat a full-screen card as an overlay in the same family as offcanvas — an overlay on the rest of the app, not a tooltip-tier element. Start by using the offcanvas z-indexes directly; we'll only introduce adjustments if we find that causes problems:
$zindex-offcanvas-backdrop(1040)$zindex-offcanvas(1045)$zindex-offcanvas(1045)Note that the card keeps the same backdrop-to-card relationship as the offcanvas pair (card exactly one tier above its own backdrop), and sits below modals, so modal dialogs (including Shiny
showModal()progress indicators) cover the expanded card.Configurability: proxy through CSS custom properties so themes can adjust at runtime without recompiling Sass:
z-index: var(--bslib-card-full-screen-z-index, #{$zindex-offcanvas})z-index: var(--bslib-card-full-screen-backdrop-z-index, #{$zindex-offcanvas-backdrop})Known accepted behavior changes: the page offcanvas backdrop no longer dims the full-screen card, and stray in-app dropdowns no longer show through the card.
Transient UI dismissal
A z-index alone can't hide open popovers/dropdowns from other parts of the app (their 1070+ would still paint above the card). That's a lifecycle problem, not a stacking one, so in
enterFullScreen()(srcts/src/components/card.ts) we will dismiss all open BootstrapDropdown,Popover, andTooltipinstances whose trigger/element lives outside the card being expanded — including bslib's own web-component popover/tooltip implementations.Adjacent Cleanup
:has(bslib-offcanvas.show, ...)enter-button suppression rule ininst/components/scss/card.scss(~line 139): with the button at the offcanvas tier, an open offcanvas naturally paints over it.yarn buildto regenerateinst/components/dist/.NEWS.mdentry covering the stacking change and the new CSS custom properties.