Basic gt Styling Reference
gt
allows for extensive and precise table styling. This is a non-comprehensive quick reference to aid users in easily knowing the basic, common functions and arguments and what they do.
There are two basic styling functions: tab_style
allows for custom styling of one or more cells and tab_options
modifies the (150+ provided) options of a table. gt
continues adding more specific stand-alone styling functions with opt_*()
, which can be found in its documentation.
tab_style(gt, style, locations)
style =
cell_text()
color = | "wheat" | "#9fd28d" | peach1 | |
---|---|---|---|---|
font = | google_fonts(name = "Merriweather") | "Garamond" | "sans-serif" | default_fonts() |
size = | px(8) | "14px" | "xx-small" | "x-large" |
align = | "center" | "left" | "right" | "justify" |
valign = | "middle" | "top" | "bottom" | |
style = | "normal" | "italic" | "oblique" | |
weight = | "bold" | "lighter" | "bolder" | 8002 |
decorate = | "line-through" | "underline" | "overline" | "underline overline" |
transform = | "uppercase"3 | "lowercase" | "capitalize"3 | |
indent = | px(15) | "25px" | pct(10) | |
1 See above callout tip. | ||||
2 Number from 1-1000 - only with variable fonts. | ||||
3 Code must be written in lowercase - example here shows the output. |
cell_borders()
sides = | "left" | "right" | "top" | c("top", "bottom") | "all" |
---|---|---|---|---|---|
color = | "wheat" | "#9fd28d" | |||
style = | "solid" | "dashed" | "dotted" | ||
weight = | 1 | px(2) | "3px" | px(4) | "5px" |
cell_fill()
locations =
Use one - or more with list()
- of these to target cells.
cells_title(groups = "title") | |||
cells_title(groups = "subtitle") | |||
cells_stubhead() | cells_column_labels(columns = ) | cells_column_spanners(spanners = ) | |
---|---|---|---|
cells_row_groups(groups = "grp1") | |||
cells_stub(rows = 1) | cells_body(column = 2, row = 1) | cells_body() | cells_body() |
cells_stub() | cells_body() | cells_body() | cells_body() |
cells_stub() | cells_body() | cells_body() | cells_body() |
cells_stub() | cells_body() | cells_body() | cells_body() |
cells_stub() | cells_body() | cells_body() | cells_body() |
cells_stub_summary(groups = , rows = ) | cells_summary(groups = , columns = , rows = )
|
||
cells_row_groups(groups = "grp2") | |||
cells_stub() | cells_body() | cells_body() | cells_body() |
cells_stub() | cells_body() | cells_body() | cells_body() |
cells_stub() | cells_body() | cells_body() | cells_body() |
cells_stub() | cells_body() | cells_body() | cells_body() |
cells_stub() | cells_body() | cells_body() | cells_body() |
cells_stub_summary(groups = , rows = ) | cells_summary(groups = , columns = , rows = )
|
||
cells_stub_grand_summary(rows = ) | cells_grand_summary(columns = , rows = )
|
||
cells_source_notes() | |||
cells_footnotes() |
tab_options(gt, options)
Borders
All borders have three associated arguments: .color
, .width
, and .style
. These are (almost) all the borders you can target.
heading.border.lr heading.border.bottom |
|||
row_group.border.top row_group.border.left |
|||
row_group.border.right row_group.border.bottom |
|||
source_notes.border.lr source_note.bottom.border |
|||
footnotes.border.lr footnotes.bottom.border |
table.border.top column_labels.border.top |
|
table_body.border.bottom table.border.bottom |
There’s one missing: table_body.border.top
. It shares space with row_group.border.top
in the first table and column_lables.border.bottom
in the second table. You’ll only need to use it when you don’t have column labels or row groups.
Which Border Wins?
Scenario: You set the color for table.border.bottom.color
, but it’s still gray. But you find if you set table.border.bottom.width
at 3px, suddenly it is the color you set.
There is logic to this - the rules for how CSS handles border conflict. Every cell actually has 4 borders. They’re almost always collapsed because separate borders are ugly. When they collapse, CSS decides which one matters the most.
column_labels.border.bottom
and table_body.border.top
share the same border space so they can be an example here.
If we set a color for each of them, only one of them will show. Both of those options were rendered by gt
in HTML file, but CSS prioritizes one of them.
%>%
border_fight tab_options(
column_labels.border.bottom.color = green,
table_body.border.top.color = peach
%>%
) as_raw_html()
Here are the rules, tailored for gt
table-making:
The style “hidden” beats everything - if any of the borders are “hidden”, none of the borders will show.
%>%
border_fight tab_options(
column_labels.border.bottom.color = green,
column_labels.border.bottom.style = "hidden",
column_labels.border.bottom.width = "2px",
table_body.border.top.color = peach,
table_body.border.top.style = "solid",
table_body.border.top.width = "2px"
%>%
) as_raw_html()
The “none” style hides a border but doesn’t affect any others.
%>%
border_fight tab_options(
column_labels.border.bottom.color = green,
column_labels.border.bottom.style = "none",
column_labels.border.bottom.width = "2px",
table_body.border.top.color = peach,
table_body.border.top.style = "solid",
table_body.border.top.width = "2px"
%>%
) as_raw_html()
Wider borders win.
%>%
border_fight tab_options(
column_labels.border.bottom.color = green,
column_labels.border.bottom.style = "solid",
column_labels.border.bottom.width = "2px",
table_body.border.top.color = peach,
table_body.border.top.style = "solid",
table_body.border.top.width = "3px"
%>%
) as_raw_html()
Then it goes to style in the order: “double”, “solid”, “dashed”, “dotted”.
%>%
border_fight tab_options(
column_labels.border.bottom.color = green,
column_labels.border.bottom.style = "solid",
column_labels.border.bottom.width = "2px",
table_body.border.top.color = peach,
table_body.border.top.style = "double",
table_body.border.top.width = "2px"
%>%
) as_raw_html()
If the only difference is color, then border that will show is the one associated with, in order of priority: cell, row, table part (header, body, or footer), then table.
%>%
border_fight tab_options(
column_labels.border.bottom.color = green,
column_labels.border.bottom.style = "solid",
column_labels.border.bottom.width = "2px",
table_body.border.top.color = peach,
table_body.border.top.style = "solid",
table_body.border.top.width = "2px"
%>%
) as_raw_html()
If you were writing the CSS for an HTML table from scratch, this wouldn’t matter as much. But gt
makes things easier by building in reasonable defaults, which means that occasionally things might not show up as you think they will. There is one surefire way to avoid any of this though, which is to set all your borders at >2px.
More options for tab_options
Table Part | Attribute |
---|---|
.background.color | |
table | |
heading | |
column_labels | |
row_group | |
stub | |
summary_row | |
grand_summary_row | |
footnotes | |
source_notes | |
row.striping | |
.text_transform | |
column_labels | |
row_group | |
stub | |
stub_row_group | |
summary_row | |
grand_summary_row |
Table Part | Attribute |
---|---|
.font.size | |
table | |
heading.title | |
heading.subtitle | |
column_labels | |
row_group | |
stub | |
stub_row_group | |
footnotes | |
source_notes | |
.font.weight | |
table | |
heading.title | |
heading.subtitle | |
column_labels | |
row_group | |
stub | |
stub_row_group |
Table Part | Attribute |
---|---|
.padding | |
heading | |
column_labels | |
row_group | |
data_row | |
summary_row | |
grand_summary_row | |
footnotes | |
source_notes | |
.padding.horizontal | |
heading | |
column_labels | |
row_group | |
data_row | |
summary_row | |
grand_summary_row | |
footnotes | |
source_notes |