如何让gt宽表冻结窗格时表头与表体共用滚动条?
解决gt表格冻结窗格时表头与表体滚动条分离的问题
我想给gt表格设置冻结窗格(同时冻结行和列),用拆分表头和表体的方式实现了部分功能,但当表格过宽超出页面范围时,表头和表体各自出现独立的横向滚动条,希望让两者共用一个横向滚动条。复现问题的代码如下:
library(htmltools) library(gt) gt_scroll <- function(data, gt_fun){ # empty table head_data <- data[0,] tab_topp <- head_data %>% gt_fun() tab_body <- data %>% gt_fun() %>% tab_options( column_labels.hidden = TRUE, container.height = gt::px(750) ) htmltools::div( htmltools::tags$div( tab_topp %>% as_raw_html(), style = htmltools::css( `padding-right` = "12px" ) ), htmltools::tags$div( tab_body, style = htmltools::css( `overflow-x` = "hidden", `overflow-y` = "auto", height = "500px" ) ) ) %>% html_print() } gt_scroll( head(starwars), function(x){ gt(x) %>% cols_width(everything()~ px(50)) %>% tab_options(container.width = px(400)) } )
解决方案
通过调整容器嵌套结构和CSS样式,让表头和表体共用同一个横向滚动容器,同时保持表头纵向固定。修改后的代码如下:
library(htmltools) library(gt) gt_scroll <- function(data, gt_fun){ # 生成空表头数据 head_data <- data[0,] tab_topp <- head_data %>% gt_fun() tab_body <- data %>% gt_fun() %>% tab_options( column_labels.hidden = TRUE, container.height = gt::px(750) ) # 外层容器统一处理横向滚动 htmltools::div( style = htmltools::css( `overflow-x` = "auto", max_width = "100%" ), # 表头容器:固定在顶部,不随纵向滚动 htmltools::tags$div( tab_topp %>% as_raw_html(), style = htmltools::css( position = "sticky", top = 0, background_color = "white", z_index = 10, `border-bottom` = "1px solid #e0e0e0" ) ), # 表体容器:仅纵向滚动,横向滚动由外层控制 htmltools::tags$div( tab_body, style = htmltools::css( `overflow-y` = "auto", height = "500px" ) ) ) %>% html_print() } gt_scroll( head(starwars), function(x){ gt(x) %>% cols_width(everything()~ px(50)) %>% tab_options(container.width = px(400)) } )
关键改动说明
- 外层滚动容器:将表头和表体包裹在同一个设置了
overflow-x: auto的div中,让横向滚动由这个容器统一触发,保证表头和表体同步滚动。 - 表头固定:给表头容器添加
position: sticky; top: 0,让表头在纵向滚动时固定在顶部,同时设置background-color: white和z-index避免被表体内容遮挡。 - 移除表体横向滚动:删掉表体容器的
overflow-x: hidden,让横向滚动完全由外层容器控制,消除独立滚动条。
内容的提问来源于stack exchange,提问作者boshek
相关产品推荐
相关产品推荐

