rguides

Theming HTML Reports with R Markdown

R Markdown creates professional HTML reports by default, but the default appearance may not match your brand or preferences. You can customize HTML reports using built-in themes, additional theme packages, or custom CSS. This tutorial shows you how to make your reports look exactly how you want them.

What you’ll learn

This tutorial covers the key concepts and practical techniques for working with Theming HTML Reports with R Markdown. By the end, you will know how to apply the core functions in real data analysis workflows.

Using built-in themes

R Markdown includes several built-in themes for HTML documents. These themes control fonts, colors, and overall styling. You specify a theme in the YAML header using the theme option:

---
output:
  html_document:
    theme: united
---

The available built-in themes are: default, bootstrap, cerulean, journal, flatly, readable, spacelab, united, and lumen.

Each theme has a distinct look. cerulean gives a clean, blue-toned appearance similar to Bootstrap. journal mimics the style of academic journals with a serif font. flatly provides a modern, flat design with good contrast. readable creates a dark-mode report. lumen is an expansive, modern theme with generous whitespace.

Here is how to apply the cosmo theme:

---
output:
  html_document:
    theme: cosmo
---

When you knit this document, R Markdown applies the selected theme to the entire HTML output. The theme affects headings, body text, code blocks, tables, and navigation elements.

Highlighting code with highlight styles

Along with the page theme, you can specify a code highlighting style. This controls how R code chunks and their syntax appear in the rendered document:

---
output:
  html_document:
    theme: flatly
    highlight: tango
---

Available highlight styles include: default, tango, pygments, kate, monochrome, espresso, zenburn, and haddock. The tango style uses orange and blue syntax coloring. pygments is the classic Pygments scheme. zenburn provides a dark, low-contrast theme popular in the R community.

The rmdformats package

The rmdformats package provides additional HTML output formats with pre-built styling. It includes themes like html_clean, docco, and readthedown that offer different layouts and visual styles.

Install the package first:

install.packages("rmdformats")

Then use one of its output formats in your YAML:

---
output: rmdformats::html_clean
---

The html_clean format produces a clean, minimalist design with automatic table of contents. The docco format resembles the Docco documentation style with code on the left and comments on the right. The readthedown format provides a responsive design optimized for mobile viewing.

The rmdformats package also includes the html_docco format, which creates beautiful documentation-style pages:

---
output: rmdformats::html_docco
---

This format adds a navigation sidebar, supports image lightboxes, and includes syntax highlighting. It works well for package documentation, long-form reports, and tutorials.

Customizing with CSS

For complete control, you can add custom CSS to override any theme styling. Create a CSS file or include CSS directly in your document:

---
output:
  html_document:
    theme: flatly
    css: styles.css
---

Alternatively, include CSS inline using the includes option:

---
output:
  html_document:
    includes:
      in_header: header.html
---

A simple custom stylesheet might look like this:

body {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 16px;
  line-height: 1.6;
}

h1, h2, h3 {
  color: #2c3e50;
  border-bottom: 1px solid #eee;
  padding-bottom: 10px;
}

.navbar {
  background-color: #3498db !important;
}

pre {
  background-color: #f8f8f8;
  border: 1px solid #ddd;
  border-radius: 4px;
}

This CSS changes the body font, adds colored borders under headings, customizes the navigation bar, and modifies code block background colors.

Changing fonts

You can change fonts by adding CSS rules. First, include the Google Fonts stylesheet in your document header:

---
output:
  html_document:
    includes:
      in_header: google_fonts.html
    theme: flatly
---

Create the google_fonts.html file:

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Lato:wght@400;700&family=Merriweather:wght@400;700&display=swap">
<style>
  body {
    font-family: 'Lato', sans-serif;
  }
  h1, h2, h3, h4, h5, h6 {
    font-family: 'Merriweather', serif;
  }
</style>

This loads Lato and Merriweather from Google Fonts and applies them to your document. The combination of a sans-serif body font with serif headings creates a readable, professional appearance.

Adding a logo and custom navigation

You can add a company logo to the navigation bar using the navbar option in your YAML:

---
output:
  html_document:
    theme: flatly
    include:
      navbar:
        left:
          - text: "My Company"
            href: "https://example.com"
        right:
          - text: "Documentation"
            href: "/docs"
---

This adds your logo to the top-left of the navigation bar and custom links on both sides. The navigation bar adapts to the theme colors automatically.

Complete example: branded report

Here is a complete example bringing together several customizations:

---
title: "Sales Report Q4 2025"
author: "Data Team"
date: "`r Sys.Date()`"
output:
  html_document:
    theme: cosmo
    highlight: tango
    code_folding: show
    toc: true
    toc_float: true
    css: custom.css
    includes:
      in_header: google_fonts.html
---
library(ggplot2)
library(dplyr)
library(rmdformats)

# Set knitr options
knitr::opts_chunk$set(echo = TRUE, fig.align = "center")

The code_folding: show option adds buttons to hide or show R code chunks. The toc: true creates a table of contents, and toc_float: true makes it float as you scroll.

Built-In themes

R Markdown HTML documents support Bootstrap themes via the theme parameter: theme: flatly, theme: cosmo, theme: journal, theme: lumen, theme: paper, theme: simplex, theme: spacelab, theme: united, theme: yeti. These are Bootswatch themes that change fonts, colors, and component styling. theme: null disables Bootstrap for a minimal bare HTML output.

bslib themes

The bslib package extends theme options. output: html_document: theme: !expr bslib::bs_theme(bootswatch = "darkly", base_font = bslib::font_google("Source Sans Pro")) sets a dark theme with a Google Font. bslib::bs_theme_preview() opens an interactive theme builder in the browser. thematic::thematic_rmd() extends the Bootstrap theme to R plots, making ggplot2 and base R charts match the document’s color scheme.

Custom CSS

css: custom.css in the YAML header injects a CSS file. Inspect the generated HTML to identify class names for components you want to override. Common targets: .section.level2 (H2 headers), .sourceCode (code blocks), .caption (figure captions). Inline CSS can also be applied with the <style> tag in the document body or with the html_document(css = "...") string argument.

Code highlighting

highlight sets the syntax highlighting theme: tango, pygments, kate, monochrome, espresso, zenburn, haddock, breezedark, textmate. highlight: null disables highlighting entirely for a minimal look. For dark-mode compatibility, highlight: espresso or highlight: zenburn pair well with dark themes. Custom highlighters can be specified via a .theme file in the Pandoc highlighting format.

HTML themes in R markdown

R Markdown HTML documents support Bootstrap themes out of the box via the Bootswatch collection. Setting a theme changes the overall visual character of the document — typography, color scheme, navigation style, and component appearances — with a single line in the YAML.

The choice of theme affects readability and professional appearance. The default theme works but looks obviously like a standard R Markdown document, which may not be desirable for client-facing reports. Themes like Flatly, Cosmo, and Lumen look polished and modern. Themes like Darkly, Cyborg, and Superhero produce dark backgrounds suitable for technical audiences.

Each Bootswatch theme has a consistent visual identity. Flatly uses subdued colors and a clean sans-serif font. Journal mimics academic publication styling. Simplex emphasizes typography over decoration. Choosing the right theme depends on the audience and the content — a business report should look professional and conventional, while a technical tutorial can be more casual.

Custom CSS for fine-Grained control

The Bootswatch theme sets the foundation, but custom CSS lets you override specific elements. Adding a CSS file in the YAML applies styles on top of the theme. This approach lets you use a well-designed base theme while customizing the elements that do not match your requirements.

Common customizations: font selection (many organizations have brand fonts), color adjustments (adjusting the primary color to match organizational branding), code block styling (custom background color, different monospace font), and layout tweaks (wider content area, different spacing).

Writing effective CSS for R Markdown documents requires understanding Bootstrap’s grid and component structure. Inspecting the rendered HTML in browser developer tools shows exactly which CSS classes and selectors control each element. Targeting Bootstrap classes directly overrides theme defaults cleanly without affecting other elements.

The limits of custom CSS: you can change colors, fonts, spacing, and decorative elements. You cannot change the underlying HTML structure without writing custom Pandoc templates. For significant structural changes, a custom Pandoc template is necessary.

Sass customization

Bootstrap 4 and 5 (used in newer R Markdown versions and Quarto) support Sass customization through variable files. Defining variables in a Sass file before importing Bootstrap changes all components that use those variables simultaneously.

This is more maintainable than writing individual CSS overrides because changing the primary color in one variable updates buttons, links, navigation, and all other components that derive from that color. CSS variable overrides can leave some components using the old value if not all relevant selectors are updated.

The bslib package provides R-level access to Bootstrap Sass customization. Setting Bootstrap variables in the document YAML or in bslib theme functions applies Sass-level customization without manually writing Sass files.

Organizing multi-Page reports

A single R Markdown HTML document can contain many sections, but very long documents become difficult to navigate even with a floating table of contents. For reports with many sections, consider breaking the content into a Quarto website or bookdown document, which generates separate HTML pages for each chapter or section with proper navigation.

For documents that must remain single-file, the code_folding: show/hide option reduces visual length by collapsing code blocks by default. Readers who need to audit the code can expand sections; readers who need only the results see a cleaner document.

Tabsets create multiple views of the same section using tabs without increasing document length. A data quality section might have tabs for completeness, accuracy, and consistency checks. Each tab shows a subset of results, making the section digestible without requiring separate pages.

Section numbering with number_sections: true in the YAML adds automatic section numbers, enabling unambiguous cross-references in text and easier navigation in long documents. Combined with a table of contents, numbered sections make long reports much more navigable.

Summary

R Markdown provides multiple ways to customize HTML report appearance:

  1. Built-in themes: Add theme: name to change the overall look
  2. Highlight styles: Add highlight: style for code syntax coloring
  3. rmdformats package: Provides additional professionally-designed formats
  4. Custom CSS: Override any styling with your own CSS rules
  5. Google Fonts: Load custom fonts for unique typography
  6. Navigation customization: Add logos and custom links to the navbar

Start with a built-in theme that closely matches your needs, then refine with custom CSS. This approach gives you professional results without spending time on extensive customization.

Continue to the next tutorial in this series to learn about Building Dashboards with Quarto.

Next steps

Now that you understand theming html reports with r markdown, explore these related topics to deepen your knowledge and apply these techniques in more complex scenarios.