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

如何调整R Shiny可排序列表的边距与宽度,实现组件对齐?

问题描述

我正在开发一个R Shiny UI,需要实现用户从左侧bucket list拖拽数值到右侧不同bucket list完成分类,每个右侧bucket list上方设有textInput用于分类命名。为使界面整洁,希望textInput与左右bucket list的左右边框对齐,且垂直间距极小。我尝试用CSS调整bucket list边距,如margin-left: -20px有效,但设为margin-left: 0无效果,也不知如何调整宽度使其与textInput一致。请问确保组件边框对齐的最佳方法是什么?

可复现代码

library(shiny)
library(sortable)

ui <- fluidPage(
  tags$head(
    # Note the wrapping of the string in HTML()
    tags$style(HTML("
      .buckets-right {
        margin-top: -25px;
        margin-left: -20px;
        margin-bottom: -10px;
        margin-right: -20px;
      }
      .bucket-left {
        margin-top: -20px;
        margin-left: -20px;
        margin-right: -10px;
      }
      
    "))
  ),
  column(6,
         bucket_list(
           header = NULL,
           group_name = "bucket_list_group",
           class = c("default-sortable", "bucket-left"),
           add_rank_list(
             text = "Values left",
             labels = c("One", "Two", "Three"),
             input_id = "list_orignal_values"
           )
         )
  ),
  column(6,
         tagList(
           textInput("name_cat1",
                     label = NULL),
           bucket_list(
             header = NULL,
             group_name = "bucket_list_group",
             orientation = "vertical",
             class = c("default-sortable", "buckets-right"),
             add_rank_list(
               text = NULL,
               labels = NULL,
               input_id = "list_cat1")
             ),
           ),
         tagList(
           textInput("name_cat2",
           label = NULL),
           bucket_list(
             header = NULL,
             group_name = "bucket_list_group",
             orientation = "vertical",
             class = c("default-sortable", "buckets-right"),
             add_rank_list(
               text = NULL,
               labels = NULL,
               input_id = "list_cat2")
           ),
         )
  )
)

server <- function(input, output, session) {
}

shinyApp(ui, server)

解决方案

核心思路是统一组件的盒模型样式,覆盖sortable包自带的内边距、外边距,同时让bucket list继承父容器宽度,和textInput保持一致:

1. 重置默认样式,解决边距不生效问题

sortable的容器自带默认padding和margin,会导致与textInput对齐错位,需强制覆盖:

.bucket-list-container, .rank-list-container {
  padding: 0 !important;
  margin: 0 !important;
}

使用!important确保优先级高于包自带样式,解决margin-left:0不生效的问题。

2. 统一宽度与垂直间距

让bucket list和textInput继承相同的父容器宽度,同时精准控制textInput与下方bucket的垂直间距:

.buckets-right, .bucket-left {
  width: 100%;
  margin-top: 4px !important; /* 可按需调整垂直间距 */
}

3. 匹配textInput的视觉样式

调整rank list的边框、内边距,使其与textInput的视觉风格完全一致:

.rank-list {
  border: 1px solid #ccc;
  border-radius: 4px;
  min-height: 60px; /* 保证空bucket有可拖拽区域 */
  padding: 6px 12px; /* 和textInput内边距一致 */
}

4. 优化布局结构

把每个分类的textInput和对应bucket放在同一个div中,避免布局错位,提升代码可读性。

修改后的完整代码

library(shiny)
library(sortable)

ui <- fluidPage(
  tags$head(
    tags$style(HTML("
      /* 重置bucket和rank容器的默认边距内边距 */
      .bucket-list-container, .rank-list-container {
        padding: 0 !important;
        margin: 0 !important;
      }
      /* 统一左右bucket的宽度和垂直间距 */
      .buckets-right, .bucket-left {
        width: 100%;
        margin-top: 4px !important;
      }
      /* 让rank list样式匹配textInput */
      .rank-list {
        border: 1px solid #ccc;
        border-radius: 4px;
        min-height: 60px;
        padding: 6px 12px;
      }
      /* 调整左侧rank list的标题位置 */
      .rank-list-header {
        margin-bottom: 8px;
        font-weight: bold;
      }
    "))
  ),
  column(6,
         bucket_list(
           header = NULL,
           group_name = "bucket_list_group",
           class = c("default-sortable", "bucket-left"),
           add_rank_list(
             text = "Values left",
             labels = c("One", "Two", "Three"),
             input_id = "list_orignal_values"
           )
         )
  ),
  column(6,
         # 把每个分类的textInput和bucket放在同一个容器里
         div(
           textInput("name_cat1", label = NULL, placeholder = "分类1名称"),
           bucket_list(
             header = NULL,
             group_name = "bucket_list_group",
             orientation = "vertical",
             class = c("default-sortable", "buckets-right"),
             add_rank_list(
               text = NULL,
               labels = NULL,
               input_id = "list_cat1")
           )
         ),
         div(
           textInput("name_cat2", label = NULL, placeholder = "分类2名称"),
           bucket_list(
             header = NULL,
             group_name = "bucket_list_group",
             orientation = "vertical",
             class = c("default-sortable", "buckets-right"),
             add_rank_list(
               text = NULL,
               labels = NULL,
               input_id = "list_cat2")
           )
         )
  )
)

server <- function(input, output, session) {
}

shinyApp(ui, server)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 04:17:17