如何将Bootswatch主题代码应用到Shiny组件?
在Shiny中应用Bootswatch复杂组件样式的解决方案
背景说明
已将Bootswatch Pulse主题的CSS文件放入Shiny项目的www目录,并通过以下代码引入:
tags$head(tags$link(rel = "stylesheet", type = "text/css", href = "mytheme.css"))
简单组件(如actionButton)可通过class = "btn-success"直接设置样式,但对复杂组件(如下拉按钮组、单选按钮)的样式适配存在疑问。
问题1:将Bootswatch Success样式下拉组应用到selectInput
Bootswatch提供的下拉按钮组HTML结构与Shiny默认selectInput的生成结构不同,无法直接套用,可通过两种方式实现:
方式1:自定义HTML替代selectInput
直接插入Bootswatch的HTML代码,结合shinyjs监听点击事件获取选中值:
library(shiny) library(shinyjs) ui <- fluidPage( tags$head(tags$link(rel = "stylesheet", type = "text/css", href = "mytheme.css")), useShinyjs(), # Success样式下拉按钮组 HTML(' <div class="btn-group" role="group" aria-label="Button group with nested dropdown"> <button type="button" class="btn btn-success">请选择</button> <div class="btn-group" role="group"> <button id="btnGroupDrop2" type="button" class="btn btn-success dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></button> <div class="dropdown-menu" aria-labelledby="btnGroupDrop2"> <a class="dropdown-item" href="#" data-value="option1">选项1</a> <a class="dropdown-item" href="#" data-value="option2">选项2</a> </div> </div> </div> '), verbatimTextOutput("selected_value") ) server <- function(input, output, session) { # 监听下拉项点击,传递选中值 runjs(' $(".dropdown-item").on("click", function() { const selectedVal = $(this).data("value"); Shiny.setInputValue("selected_dropdown", selectedVal); // 更新按钮显示文本 $(this).closest(".btn-group").find(".btn:first").text($(this).text()); }); ') output$selected_value <- renderPrint({ input$selected_dropdown }) } shinyApp(ui, server)
方式2:修改selectInput的class并补充CSS
禁用Shiny默认的selectize样式,添加Bootswatch的按钮class,再用自定义CSS调整外观:
# UI中的selectInput设置 selectInput( inputId = "my_select", label = NULL, choices = c("选项1", "选项2"), selectize = FALSE, class = "btn btn-success" )
在www目录新建custom.css,添加以下代码:
select.btn-success { appearance: none; background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"); background-position: right 0.5rem center; background-repeat: no-repeat; background-size: 16px 12px; padding-right: 2.5rem; border: none; }
最后在UI中引入该CSS:
tags$head( tags$link(rel = "stylesheet", type = "text/css", href = "mytheme.css"), tags$link(rel = "stylesheet", type = "text/css", href = "custom.css") )
问题2:修改单选按钮样式为Bootswatch风格
通过自定义CSS覆盖Shiny默认的单选按钮样式,在www/custom.css中添加:
/* 隐藏原生单选按钮 */ input[type="radio"] { opacity: 0; position: absolute; } /* 自定义单选按钮外层容器 */ input[type="radio"] + label { position: relative; padding-left: 2rem; cursor: pointer; margin-bottom: 0.5rem; } /* 未选中状态的按钮外观 */ input[type="radio"] + label::before { content: ""; position: absolute; left: 0; top: 0; width: 1.25rem; height: 1.25rem; border: 2px solid #28a745; /* Pulse主题success色 */ border-radius: 50%; background-color: #fff; } /* 选中状态的填充样式 */ input[type="radio"]:checked + label::after { content: ""; position: absolute; left: 0.4rem; top: 0.4rem; width: 0.5rem; height: 0.5rem; border-radius: 50%; background-color: #28a745; } /* 悬停状态效果 */ input[type="radio"] + label:hover::before { border-color: #218838; }
确保UI中已引入custom.css,即可将单选按钮改为目标样式。
内容的提问来源于stack exchange,提问作者SimonSimon
相关产品推荐
相关产品推荐

