Skip to contents

One verb, one cascade. Each style() call appends a single style_layer (location + style attributes) to the spec or template. Layers accumulate in declaration order; the engine merges them at render time so later layers win per attribute, NA-valued fields leave the prior layer intact.

Usage

style(.spec, ..., .at = cells_body())

Arguments

.spec

A tabular_spec OR a tabular_style_template. <tabular_spec | tabular_style_template>: required. Dot-prefixed so R's partial argument matching cannot accidentally bind a short attribute name in ... to the spec slot. When piping through style_template() |> style(...) layers accumulate onto the template instead of a spec.

...

Named style attributes. At least one required. See the Style attributes section for the recognised names.

.at

Location object selecting which surface the layer targets. <tabular_location>: default cells_body(). Build with one of the cells_*() constructors; see cells_body() and siblings. Dot-prefixed (tidyverse convention) because it comes AFTER ... — that way a user-passed style attribute can never collide with this arg's name.

Value

The updated tabular_spec (or tabular_style_template, when called against one).

Locations

The .at argument selects which surface the layer targets. Every region of the rendered page has a cells_*() constructor:

Body filters live on cells_body(): i = 1:3 for integer-index rows, j = "Total" for column-name targeting, where = <expr> for a quosure-captured predicate evaluated against spec@data.

Style attributes

Each layer carries a style_node built from .... Recognised attribute names:

  • Text — bold, italic, underline, color, background, font_family, font_size

  • Alignment — halign ("left" / "center" / "right"), valign ("top" / "middle" / "bottom")

  • Borders — border (umbrella), border_top, border_bottom, border_left, border_right (each takes a brdr() value or the literal "none"); per-side scalars border_<side>_{style,width,color} for finer control

  • Padding — padding (a scalar applies to all four sides; a named vector c(top = , right = , bottom = , left = ) sets each side); or the per-side scalars padding_<side> directly

  • Spacing — blank_above, blank_below (integer blank lines above / below the block — for cells_title() / cells_footnotes() / cells_subgroup_labels())

  • Inline — pretext, posttext (literal text prepended / appended around the cell value)

Unknown attribute names emit a cli::cli_warn and drop from the constructed node; the engine never sees a foreign property.

Examples

# ---- AE table by SOC and PT with per-row indent + styled hierarchy ----
# `cdisc_saf_aesocpt` ships with `indent_level` (0 on overall/SOC rows,
# 1 on PT rows); `col_spec(indent = "indent_level")` drives the
# PT indent on the `label` column.
tabular(cdisc_saf_aesocpt, titles = "Adverse Events by SOC / PT",
        footnotes = "") |>
  cols(
    label    = col_spec(label = "Category", align = "left",
                        indent = "indent_level"),
    soc      = col_spec(visible = FALSE),
    row_type = col_spec(visible = FALSE),
    soc_n    = col_spec(visible = FALSE),
    n_total  = col_spec(visible = FALSE),
    placebo  = col_spec(label = "Placebo",  align = "decimal"),
    drug_50  = col_spec(label = "Drug 50",  align = "decimal"),
    drug_100 = col_spec(label = "Drug 100", align = "decimal"),
    Total    = col_spec(label = "Total",    align = "decimal")
  ) |>
  # SOC summary rows bolded (depth 0 — flush)
  style(bold = TRUE,
        .at = cells_body(where = row_type == "soc")) |>
  # Overall row gets a light background
  style(background = "#f0f0f0",
        .at = cells_body(where = row_type == "overall"))

 

Adverse Events by SOC / PT

 

CategoryPlaceboDrug 50Drug 100Total
TOTAL SUBJECTS WITH AN EVENT52 (60.5)81 (84.4)66 (91.7)199 (78.3)
SKIN AND SUBCUTANEOUS TISSUE DISORDERS19 (22.1)36 (37.5)35 (48.6) 90 (35.4)
PRURITUS 8 ( 9.3)21 (21.9)25 (34.7) 54 (21.3)
ERYTHEMA 8 ( 9.3)14 (14.6)14 (19.4) 36 (14.2)
RASH 5 ( 5.8)13 (13.5) 8 (11.1) 26 (10.2)
HYPERHIDROSIS 2 ( 2.3) 4 ( 4.2) 8 (11.1) 14 ( 5.5)
SKIN IRRITATION 3 ( 3.5) 6 ( 6.2) 5 ( 6.9) 14 ( 5.5)
GENERAL DISORDERS AND ADMINISTRATION SITE CONDITIONS15 (17.4)36 (37.5)30 (41.7) 81 (31.9)
APPLICATION SITE PRURITUS 6 ( 7.0)23 (24.0)21 (29.2) 50 (19.7)
APPLICATION SITE ERYTHEMA 3 ( 3.5)13 (13.5)14 (19.4) 30 (11.8)
APPLICATION SITE DERMATITIS 5 ( 5.8) 9 ( 9.4) 7 ( 9.7) 21 ( 8.3)
APPLICATION SITE IRRITATION 3 ( 3.5) 9 ( 9.4) 9 (12.5) 21 ( 8.3)
APPLICATION SITE VESICLES 1 ( 1.2) 5 ( 5.2) 5 ( 6.9) 11 ( 4.3)
GASTROINTESTINAL DISORDERS13 (15.1)12 (12.5)17 (23.6) 42 (16.5)
DIARRHOEA 9 (10.5) 5 ( 5.2) 3 ( 4.2) 17 ( 6.7)
VOMITING 3 ( 3.5) 4 ( 4.2) 6 ( 8.3) 13 ( 5.1)
NAUSEA 3 ( 3.5) 3 ( 3.1) 6 ( 8.3) 12 ( 4.7)
ABDOMINAL PAIN 1 ( 1.2) 3 ( 3.1) 1 ( 1.4)  5 ( 2.0)
SALIVARY HYPERSECRETION 0        0        4 ( 5.6)  4 ( 1.6)
NERVOUS SYSTEM DISORDERS 6 ( 7.0)18 (18.8)17 (23.6) 41 (16.1)
DIZZINESS 2 ( 2.3) 9 ( 9.4)10 (13.9) 21 ( 8.3)
HEADACHE 3 ( 3.5) 3 ( 3.1) 5 ( 6.9) 11 ( 4.3)
SYNCOPE 0        5 ( 5.2) 2 ( 2.8)  7 ( 2.8)
SOMNOLENCE 2 ( 2.3) 3 ( 3.1) 1 ( 1.4)  6 ( 2.4)
TRANSIENT ISCHAEMIC ATTACK 0        2 ( 2.1) 1 ( 1.4)  3 ( 1.2)
CARDIAC DISORDERS 7 ( 8.1)12 (12.5)14 (19.4) 33 (13.0)
SINUS BRADYCARDIA 2 ( 2.3) 7 ( 7.3) 8 (11.1) 17 ( 6.7)
MYOCARDIAL INFARCTION 4 ( 4.7) 2 ( 2.1) 4 ( 5.6) 10 ( 3.9)
ATRIAL FIBRILLATION 1 ( 1.2) 2 ( 2.1) 2 ( 2.8)  5 ( 2.0)
SUPRAVENTRICULAR EXTRASYSTOLES 1 ( 1.2) 1 ( 1.0) 1 ( 1.4)  3 ( 1.2)
VENTRICULAR EXTRASYSTOLES 0        2 ( 2.1) 1 ( 1.4)  3 ( 1.2)
INFECTIONS AND INFESTATIONS12 (14.0) 6 ( 6.2)11 (15.3) 29 (11.4)
NASOPHARYNGITIS 2 ( 2.3) 4 ( 4.2) 6 ( 8.3) 12 ( 4.7)
UPPER RESPIRATORY TRACT INFECTION 6 ( 7.0) 1 ( 1.0) 3 ( 4.2) 10 ( 3.9)
INFLUENZA 1 ( 1.2) 1 ( 1.0) 1 ( 1.4)  3 ( 1.2)
URINARY TRACT INFECTION 2 ( 2.3) 0        1 ( 1.4)  3 ( 1.2)
CYSTITIS 1 ( 1.2) 0        1 ( 1.4)  2 ( 0.8)
RESPIRATORY, THORACIC AND MEDIASTINAL DISORDERS 5 ( 5.8) 8 ( 8.3) 9 (12.5) 22 ( 8.7)
COUGH 1 ( 1.2) 5 ( 5.2) 5 ( 6.9) 11 ( 4.3)
NASAL CONGESTION 3 ( 3.5) 1 ( 1.0) 3 ( 4.2)  7 ( 2.8)
DYSPNOEA 1 ( 1.2) 1 ( 1.0) 1 ( 1.4)  3 ( 1.2)
EPISTAXIS 0        1 ( 1.0) 2 ( 2.8)  3 ( 1.2)
PHARYNGOLARYNGEAL PAIN 0        1 ( 1.0) 1 ( 1.4)  2 ( 0.8)
PSYCHIATRIC DISORDERS 7 ( 8.1) 9 ( 9.4) 3 ( 4.2) 19 ( 7.5)
CONFUSIONAL STATE 2 ( 2.3) 3 ( 3.1) 1 ( 1.4)  6 ( 2.4)
AGITATION 2 ( 2.3) 3 ( 3.1) 0         5 ( 2.0)
INSOMNIA 2 ( 2.3) 0        2 ( 2.8)  4 ( 1.6)
ANXIETY 0        3 ( 3.1) 0         3 ( 1.2)
DELUSION 1 ( 1.2) 0        1 ( 1.4)  2 ( 0.8)
MUSCULOSKELETAL AND CONNECTIVE TISSUE DISORDERS 3 ( 3.5) 6 ( 6.2) 5 ( 6.9) 14 ( 5.5)
BACK PAIN 1 ( 1.2) 1 ( 1.0) 3 ( 4.2)  5 ( 2.0)
ARTHRALGIA 1 ( 1.2) 2 ( 2.1) 1 ( 1.4)  4 ( 1.6)
SHOULDER PAIN 1 ( 1.2) 2 ( 2.1) 0         3 ( 1.2)
MUSCLE SPASMS 0        1 ( 1.0) 1 ( 1.4)  2 ( 0.8)
ARTHRITIS 0        0        1 ( 1.4)  1 ( 0.4)
INVESTIGATIONS 5 ( 5.8) 4 ( 4.2) 3 ( 4.2) 12 ( 4.7)
ELECTROCARDIOGRAM ST SEGMENT DEPRESSION 4 ( 4.7) 1 ( 1.0) 0         5 ( 2.0)
ELECTROCARDIOGRAM T WAVE INVERSION 2 ( 2.3) 1 ( 1.0) 1 ( 1.4)  4 ( 1.6)
BLOOD GLUCOSE INCREASED 0        1 ( 1.0) 1 ( 1.4)  2 ( 0.8)
ELECTROCARDIOGRAM T WAVE AMPLITUDE DECREASED 1 ( 1.2) 1 ( 1.0) 0         2 ( 0.8)
BIOPSY 0        0        1 ( 1.4)  1 ( 0.4)

# ---- Chrome styling ---- # Each layer changes the surface VISIBLY from its default: a coloured # rule under the header band, a dark-blue header text, a left-aligned # title (default is centred), and a blank line above + below the title. tabular(cdisc_saf_demo, titles = "Demographic Characteristics") |> style(color = "#1a5276", .at = cells_headers()) |> style(border_bottom = brdr("thick", "double", "#1a5276"), .at = cells_headers()) |> style(halign = "left", .at = cells_title()) |> style(blank_above = 1, blank_below = 1, .at = cells_title())

 

Demographic Characteristics

 

variablestat_labelplacebodrug_50drug_100Total
Age (years)n869672254
Age (years)Mean (SD)75.2 (8.59)76.0 (8.11)73.8 (7.94)75.1 (8.25)
Age (years)Median76.078.075.577.0
Age (years)Q1, Q369.2, 81.871.0, 82.070.5, 79.070.0, 81.0
Age (years)Min, Max52, 8951, 8856, 8851, 89
Sex, n (%)F53 (61.6)55 (57.3)35 (48.6)143 (56.3)
Sex, n (%)M33 (38.4)41 (42.7)37 (51.4)111 (43.7)
Race, n (%)WHITE78 (90.7)90 (93.8)62 (86.1)230 (90.6)
Race, n (%)BLACK OR AFRICAN AMERICAN8 (9.3)6 (6.2)9 (12.5)23 (9.1)
Race, n (%)ASIAN0 (0.0)0 (0.0)0 (0.0)0 (0.0)
Race, n (%)AMERICAN INDIAN OR ALASKA NATIVE0 (0.0)0 (0.0)1 (1.4)1 (0.4)
# ---- Table-wide borders ---- tabular(cdisc_saf_demo) |> style(border = brdr("medium"), .at = cells_table(side = "outer")) |> style(border_top = brdr("hairline", "dotted"), .at = cells_table(side = "rows"))
variablestat_labelplacebodrug_50drug_100Total
Age (years)n869672254
Age (years)Mean (SD)75.2 (8.59)76.0 (8.11)73.8 (7.94)75.1 (8.25)
Age (years)Median76.078.075.577.0
Age (years)Q1, Q369.2, 81.871.0, 82.070.5, 79.070.0, 81.0
Age (years)Min, Max52, 8951, 8856, 8851, 89
Sex, n (%)F53 (61.6)55 (57.3)35 (48.6)143 (56.3)
Sex, n (%)M33 (38.4)41 (42.7)37 (51.4)111 (43.7)
Race, n (%)WHITE78 (90.7)90 (93.8)62 (86.1)230 (90.6)
Race, n (%)BLACK OR AFRICAN AMERICAN8 (9.3)6 (6.2)9 (12.5)23 (9.1)
Race, n (%)ASIAN0 (0.0)0 (0.0)0 (0.0)0 (0.0)
Race, n (%)AMERICAN INDIAN OR ALASKA NATIVE0 (0.0)0 (0.0)1 (1.4)1 (0.4)
# ---- House style via style_template() ---- house <- style_template() |> style(color = "#1F3B5C", background = "#DBE4F0", .at = cells_headers()) |> style(border_top = brdr("thick"), .at = cells_headers()) |> style(border_bottom = brdr("thick"), .at = cells_headers()) |> style(border_bottom = brdr("medium"), .at = cells_table(side = "outer_bottom")) # Attach once via set_preset(); every tabular() chain then inherits it. set_preset(.style = house, font_size = 9) set_preset(.reset = TRUE) # restore the default for later examples