Styling the Whole Table

In Styling the Table Body, we discussed styling table data with tab_style(). In this article we’ll cover how the same method can be used to style many other parts of the table, like the header, specific spanner labels, the footer, and more. By targeting different location specifiers, you can apply fill colors, borders, and text styles to virtually any region of your table.

Warning

This feature is new, and this page of documentation is still in development.

All locations example

Below is a comprehensive example that shows all possible loc specifiers being used. Each table part receives a distinct background color so you can see exactly which region each specifier targets.

from great_tables import GT, exibble, loc, style

# https://colorbrewer2.org/#type=qualitative&scheme=Paired&n=12 and grey
brewer_colors = [
    "#a6cee3",
    "#1f78b4",
    "#b2df8a",
    "#33a02c",
    "#fb9a99",
    "#e31a1c",
    "#fdbf6f",
    "#ff7f00",
    "#cab2d6",
    "#6a3d9a",
    "#ffff99",
    "#b15928",
    "#808080",
]

c = iter(brewer_colors)

gt = (
    GT(exibble.loc[[0, 1, 4], ["num", "char", "fctr", "row", "group"]])
    .tab_header("title", "subtitle")
    .tab_stub(rowname_col="row", groupname_col="group")
    .tab_source_note("yo")
    .tab_spanner("spanner", ["char", "fctr"])
    .tab_stubhead("stubhead")
    .grand_summary_rows(fns={"Total": lambda x: x.sum(numeric_only=True)})
)

(
    gt.tab_style(style.fill(next(c)), loc.body())
    # Columns -----------
    # TODO: appears in browser, but not vs code
    .tab_style(style.fill(next(c)), loc.column_labels(columns="num"))
    .tab_style(style.fill(next(c)), loc.column_header())
    .tab_style(style.fill(next(c)), loc.spanner_labels(ids=["spanner"]))
    # Header -----------
    .tab_style(style.fill(next(c)), loc.header())
    .tab_style(style.fill(next(c)), loc.subtitle())
    .tab_style(style.fill(next(c)), loc.title())
    # Footer -----------
    .tab_style(style.borders(weight="3px"), loc.source_notes())
    .tab_style(style.fill(next(c)), loc.footer())
    # Stub --------------
    .tab_style(style.fill(next(c)), loc.row_groups())
    .tab_style(style.borders(weight="3px"), loc.stub(rows=1))
    .tab_style(style.fill(next(c)), loc.stub())
    .tab_style(style.fill(next(c)), loc.stubhead())
    # Summary Rows --------------
    .tab_style(style.fill(next(c)), loc.grand_summary())
    .tab_style(style.fill(next(c)), loc.grand_summary_stub())
)
title
subtitle
stubhead num spanner
char fctr
grp_a
row_1 0.1111 apricot one
row_2 2.222 banana two
grp_b
row_5 5550.0 five
Total 5552.3331 --- ---
yo

Each color in the output maps to a specific table region, making it easy to identify the scope of every location specifier available in Great Tables.

Body

The table body is styled using loc.body(), which targets all data cells at once.

gt.tab_style(style.fill("yellow"), loc.body())
title
subtitle
stubhead num spanner
char fctr
grp_a
row_1 0.1111 apricot one
row_2 2.222 banana two
grp_b
row_5 5550.0 five
Total 5552.3331 --- ---
yo

The yellow fill is applied to every data cell in the table body, leaving headers, stubs, and footers unchanged.

Column labels

Column labels can be styled broadly with loc.column_header(), or you can target individual column labels and spanner labels separately for more precise control.

(
    gt
    .tab_style(style.fill("yellow"), loc.column_header())
    .tab_style(style.fill("blue"), loc.column_labels(columns="num"))
    .tab_style(style.fill("red"), loc.spanner_labels(ids=["spanner"]))
)
title
subtitle
stubhead num spanner
char fctr
grp_a
row_1 0.1111 apricot one
row_2 2.222 banana two
grp_b
row_5 5550.0 five
Total 5552.3331 --- ---
yo

Here, loc.column_header() applies a yellow background to the entire column labels row, then individual labels and spanners are overridden with more specific colors. This layered approach lets you set a base style and refine as needed.

Stub

The stub region includes row labels and row group labels. You can style these elements together or individually, and even target specific rows within the stub.

(
    gt.tab_style(style.fill("yellow"), loc.stub())
    .tab_style(style.fill("blue"), loc.row_groups())
    .tab_style(
        style.borders(style="dashed", weight="3px", color="red"),
        loc.stub(rows=[1]),
    )
)
title
subtitle
stubhead num spanner
char fctr
grp_a
row_1 0.1111 apricot one
row_2 2.222 banana two
grp_b
row_5 5550.0 five
Total 5552.3331 --- ---
yo

The stub fills yellow, row group labels turn blue, and a dashed red border highlights a specific row in the stub. Using rows= within loc.stub() lets you target individual row labels.

Stubhead

The stubhead label sits above the stub column and can be styled with loc.stubhead().

gt.tab_style(style.fill("yellow"), loc.stubhead())
title
subtitle
stubhead num spanner
char fctr
grp_a
row_1 0.1111 apricot one
row_2 2.222 banana two
grp_b
row_5 5550.0 five
Total 5552.3331 --- ---
yo

The stubhead label cell receives the yellow background. This is useful for visually linking the stubhead to the stub column below it.

Grand Summary Rows

Grand summary rows appear at the bottom of the table. You can style the summary data cells and the summary stub area independently.

(
    gt.tab_style(
        style.fill("yellow"),
        loc.grand_summary_stub(),
    ).tab_style(
        style.fill("lightblue"),
        loc.grand_summary(),
    )
)
title
subtitle
stubhead num spanner
char fctr
grp_a
row_1 0.1111 apricot one
row_2 2.222 banana two
grp_b
row_5 5550.0 five
Total 5552.3331 --- ---
yo

With tab_style() and the full set of loc specifiers, you can style every part of a Great Tables output. This gives you the ability to create cohesive visual themes, draw attention to specific structural elements, and ensure your table communicates effectively at every level.