htmlrvisualizationgt

Border padding in gt table


I want to add a little padding to my gt table so that the borders don't run up against each other. Ideally, this means the borders just have a little bit of margin within their cell so they look like the orange borders in the amended screenshot (but otherwise keeping the cell exactly the same)... in other words, I want the borders to basically hug the text, not the cell. I can't figure out a way to specify this... any suggestions?

require(gt)

gt(exibble) %>% 
  cols_align(
    align = "center",
    columns = c("char")
  ) %>%
  tab_style(
    style = list(
      cell_borders(
        sides = c("all"),
        weight = px(3)
      ),
      cell_borders(
        sides = c("all"),
        weight = px(2)
      )
    ),
    locations = list(
      cells_body(
        columns = "char",
        rows = !is.na(char)
      ),
      cells_body(
        columns = "datetime",
        rows = !is.na(datetime)
      )
    )
  )

gt generated borders in black, as produced by reprex

Intended borders with margin padding in orange


Solution

  • If you want the border to hug the text, you can apply the style to the text rather than table. We can use gt::text_transform() to define a function with inline html defining the desired style:

    txt_border <- function(x, style = "solid", min_width = 0, border_width = 2, padding = 1, color = "#000000") {
        sprintf(
            "<div style='border: %s %spx; min-width: %spx; padding: %spx; border-color: %s;'>%s</div>",
            style, border_width, min_width, padding, color, x
        )
    }
    

    Then just apply this function to the same cells as previously:

    gt(exibble) |>
        cols_align(align = "center", columns = c("char")) |>
        text_transform(
            fn = txt_border,
            locations = list(
                cells_body(columns = "char", rows = !is.na(char)),
                cells_body(columns = "datetime", rows = !is.na(datetime))
            )
        )
    

    table with inner borders

    I was not entirely clear whether you wanted these borders instead of the previous ones or in addition to them, but if the latter you can just add the text_transform() part to your previous table. You can change the distance of the border from the text with the padding parameter, and also play with the others as well e.g.:

    gt(exibble) |>
        cols_align(align = "center", columns = c("char")) |>
        tab_style(
            style = list(
                cell_borders(sides = c("all"), weight = px(3)),
                cell_borders(sides = c("all"), weight = px(2))
            ),
            locations = list(
                cells_body(columns = "char", rows = !is.na(char)),
                cells_body(columns = "datetime", rows = !is.na(datetime))
            )
        ) |>
        text_transform(
            fn = \(x) txt_border(x, border_width = 3, padding = 3, color = "orange"),
            locations = list(
                cells_body(columns = "char", rows = !is.na(char))
            )
        )
    

    table with orange borders and padding

    For further reading on using html with gt, you might want to see this blog post: Embedding custom HTML in gt tables.