Search code examples
cssrshinybslib

Remove cell border in datatable with bslib and Bootstrap styling


In a shiny app, I am applying the yeti theme using the bslib library and a datatable with bootstrap styling. Unlike as if using other bootstrap stylings (e.g. bootstrap5) or the shinythemes library instead of bslib, there are unwanted white cell borders in the datatable, which I don't manage to get rid of.

I tried to do a CSS override which did not seem to work:

library(shiny)
library(DT)
library(bslib)

ui <- navbarPage("A reproducible Shiny app",
  theme = bs_theme(bootswatch = "yeti"),
  tabPanel("MAIN",
    tags$style('#mytable td {cell-border:0}'),
    mainPanel(DT::dataTableOutput('mytable'))
  )
)    

server <- function(input, output,session) {
  output$mytable = DT::renderDataTable(    
    datatable(mtcars[1:3], style="bootstrap")
  ) 
}

runApp(list(ui = ui, server = server))

Datatable with annoying white cell borders


Solution

  • You can actually custom the bs_theme() call using bs_add_rules() and passing some CSS code in it.

    EDIT: see this github issue and bslib documentation.

    By using the Inspect feature on my browser and with pure empirical approach, I found out that the CSS attribute border-collapse was the one you were looking for, and that it is associated with the table.dataTable{} selector. Describing how CSS works is beyond the scope of this question and I'm not an expert, so feel free to document yourself on this topic. You can also indeed use the specific selector for this table (all other datatables would still have the white border) with #mytable dt : {border-collapse: collapse !important;}

    Here's your app without the white border :

    library(shiny)
    library(DT)
    library(bslib)
    
    ui <- navbarPage("A reproducible Shiny app",
                             theme = bs_theme(bootswatch = "yeti") |>
    # add css rule to override yeti's 'separate' border-collapse default option :  
                       bs_add_rules(".table.dataTable { border-collapse : collapse !important;}"),
                             tabPanel("MAIN",
    
                                      # not needed anymore : tags$style('#mytable td {cell-border:0}'),
                                      mainPanel(DT::dataTableOutput('mytable'))
                             )
    )
    
    server <- function(input, output,session) {
      output$mytable = DT::renderDataTable(    
        datatable(mtcars[1:3], style="bootstrap")
      ) 
    }
    
    runApp(list(ui = ui, server = server))
    
    

    Hope this helps.