In a filling context, empty .shiny-html-output containers either receive gap or are included in the allocation of space in the flex container, leading to additional space that most people would not expect to appear. Consider conditional dynamic content shown in a sidebar() or conditional content shown in a card.
In the following example, the intention is to hide the reactable table unless the card is in full-screen
library(shiny)
library(bslib)
library(reactable)
ui <- page_fluid(
card(
id = "table_card",
"A fancy table",
uiOutput("ui_table", fill = TRUE),
full_screen = TRUE
),
# tags$style(HTML(".html-fill-container .shiny-html-output:empty { position: absolute }"))
)
server <- function(input, output) {
output$ui_table <- renderUI({
req(input$table_card_full_screen)
reactableOutput("table")
})
output$table <- renderReactable({
reactable(mtcars)
})
}
shinyApp(ui = ui, server = server)
The card contains an additional row of space that most people would not expect or want.

If we move the empty element out of the document flow, it's no longer accounted for in the flex calculation:
.html-fill-container .shiny-html-output:empty {
position: absolute
}
