You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiny+bslib布局问题:让navset_hidden/layout_sidebar填充页面高度

解决Shiny中navset_hidden布局高度无法填充页面的问题

问题根源

navset_hidden 默认是自适应内容高度,而直接放在 nav_panel 里的 layout_sidebar 会自动继承 page_navbar 主体区域的100%高度。要让Nav1里的布局和Nav2表现一致,需要给嵌套的容器逐层设置高度继承规则。

修改后的代码

library(shiny)
library(bslib)

nav1UI <- function(id) {
  ns <- NS(id)
  layout_sidebar(
    # 让layout_sidebar占满父容器高度
    height = "100%",
    sidebar = sidebar(
      open = "always",
      paste0("sidebar of ", id)
    ),
    # 主内容区超出高度时自动滚动,避免页面整体滚动
    div(
      style = "height: 100%; overflow-y: auto;",
      paste0("main of ", id),
      lapply(1:20, function(i) h1(i))
    )
  )
}

ui <- page_navbar(
  title = "MyApp",
  nav_panel(
    "Nav1",
    # 让Nav1的面板内容占满page_navbar主体高度
    style = "position: relative; height: 100%;",
    actionButton("nav1_select", "select", style = "position: absolute; top: 0; left: 0; z-index: 1000;"),
    # 让navset_hidden占满父容器高度
    navset_hidden(
      id = "nav1_navset",
      style = "height: 100%;",
      nav_panel_hidden("A", nav1UI("A")),
      nav_panel_hidden("B", nav1UI("B")),
      nav_panel_hidden("C", nav1UI("C")),
      nav_panel_hidden("D", nav1UI("D"))
    )
  ),
  nav_panel(
    "Nav2",
    layout_sidebar(
      sidebar = sidebar("sidebar of Nav2"),
      "main of Nav2"
    )
  ),
  nav_panel("Nav3", "content of Nav3")
)

server <- function(input, output, session) {
  observeEvent(input$nav1_select, {
    showModal(modalDialog(
      title = "Select one",
      selectInput("nav_panel_to_go", NULL, choices = c("A", "B", "C", "D")),
      easyClose = TRUE,
      footer = tagList(
        modalButton("Close"),
        actionButton("go", "Go", class = "btn-success")
      )
    ))
  })

  observeEvent(input$go, {
    nav_select("nav1_navset", input$nav_panel_to_go)
    removeModal()
  })
}

shinyApp(ui, server)

关键修改点

  • 给Nav1的nav_panel添加 height: 100%,确保面板内容区继承page_navbar主体的高度。
  • 给navset_hidden添加 height: 100%,让它占满父容器空间。
  • 给layout_sidebar设置 height = "100%",使其填充navset_hidden的高度。
  • 给主内容区包裹一层div并设置 height: 100%; overflow-y: auto;,这样内容超出时在主区域内滚动,保持整体布局高度不变。

关于抽屉式导航的后续方向

如果要实现GitHub风格的抽屉式搜索导航,可以基于bslib的sidebar组件扩展:

  • 将导航选项放在一个可折叠的左侧sidebar中,默认收起。
  • 在sidebar内添加搜索输入框,通过observeEvent过滤导航选项。
  • 用nav_select实现点击选项切换navset_hidden的面板。

内容的提问来源于stack exchange,提问作者toxin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 00:57:38