Why I prefer making HTML from Rmarkdown

Rmarkdown

I love the type faces of PDF output but …

Chris Evans https://www.psyctc.org/R_blog/ (PSYCTC.org)https://www.psyctc.org/psyctc/
2026-07-13
Show code
# png(file = "noPDF3.png", type = "cairo", width = 1920, height = 1920, res = 300)
as_tibble(list(x = 1,
               y = 1)) -> tmpDat


ggplot(data = tmpDat,
       aes(x = x, y = y)) +
  geom_text(label = "No PDF please!",
            size = 45,
            colour = "black",
            angle = 30) +
  xlab("") +
  ylab("") +
  theme_bw() +
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.border = element_blank(),
        panel.background = element_blank(),
        axis.line = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank())
Show code
# dev.off()

### I gave up on trying to superimpose a no entry sign on "PDF"!

# png(file = "noPDF.png", type = "cairo", width = 1920, height = 1920, res = 300)
# ggplot(data = tmpDat,
#        aes(x = x, y = y)) +
#   geom_text(label = "PDF",
#             size = 55,
#             colour = "black",
#             angle = 30) +
#   xlab("") +
#   ylab("") +
#   theme_bw() +
#   theme(panel.grid.major = element_blank(),
#         panel.grid.minor = element_blank(),
#         panel.border = element_blank(),
#         panel.background = element_blank(),
#         axis.line = element_blank(),
#         axis.text = element_blank(),
#         axis.ticks = element_blank()) 
# # dev.off()
# 
# ggplot(data = tibble(x = 0, y = 0),
#        aes(x = x, y = y)) +
#   # ggimage::geom_image(data = tibble(x = 0, y = 0),
#   #                     aes(image = "noPDF.png")) #+
#   ggimage::geom_image(data = tibble(x = 0, y = 0),
#                       aes(image = "no_entry_1920.png")) +
#     xlab("") +
#   ylab("") +
#   theme_bw() +
#   theme(panel.grid.major = element_blank(),
#         panel.grid.minor = element_blank(),
#         panel.border = element_blank(),
#         panel.background = element_blank(),
#         axis.line = element_blank(),
#         axis.text = element_blank(),
#         axis.ticks = element_blank()) 

# png(file = "noPDF2.png", type = "cairo", width = 19200, height = 19200, res = 300)
# as_tibble(list(x = 0,
#                y = 0)) -> tmpDat
# 
# ggplot(data = tmpDat,
#        aes(x = x, y = y)) +
#   geom_text(label = "PDF",
#             size = 7,
#             colour = "black",
#             angle = 30) +
#   ggimage::geom_image(data = tibble(x = 0, y = 0),
#                       aes(image = "no_entry_1920.png")) +
#   xlab("") +
#   ylab("") +
#   theme_bw() +
#   theme(panel.grid.major = element_blank(),
#         panel.grid.minor = element_blank(),
#         panel.border = element_blank(),
#         panel.background = element_blank(),
#         axis.line = element_blank(),
#         axis.text = element_blank(),
#         axis.ticks = element_blank()) 
# dev.off()

### thanks to https://pixabay.com/users/thehalaldesign-19718486/ for the no entry graphic
Show code
### this is just the code that creates the "copy to clipboard" function in the code blocks
htmltools::tagList(
  xaringanExtra::use_clipboard(
    button_text = "<i class=\"fa fa-clone fa-2x\" style=\"color: #301e64\"></i>",
    success_text = "<i class=\"fa fa-check fa-2x\" style=\"color: #90BE6D\"></i>",
    error_text = "<i class=\"fa fa-times fa-2x\" style=\"color: #F94144\"></i>"
  ),
  rmarkdown::html_dependency_font_awesome()
)

Introduction

Having just spent some hours bullying some PDF output from a large Rmarkdown script so that all its tables were readable and not amputated where they went off the right hand margin of the page this is to remind myself why I prefer not to output to PDF and to help myself if I ever find that I absolutely have to knit to PDF again.

I love the power of Rmarkdown and all my significant lumps of data analysis within Rmd files (in Rstudio). That gives me, for free, the power to “knit” my mix of text and code to one of three formats:

Why prefer HTML?

You can imagine that my FLOSS leanings mean that I avoid the last except when it’s going to be vital to allow a collaborator to do something with it impossible in the other two formats (occasionally copying and pasting a small table into Wurd or sometimes using track changes to suggest changes to the text). I am also not a fan of Adobe but the PDF export is entirely Adobe free and it does produce lovely typography with nice serif fonts by default and I suppose I can lock the file though I don’t think I’ve ever wanted to do that.

However, adding

<style type="text/css">  #allows right scroll
.main-container {
max-width: 1800px;
margin-left: auto;
margin-right: auto;
}
pre {
overflow-x: auto;
}
pre code {
word-wrap: normal;
white-space: pre;
}
</style>

between the YAML header of the Rmd file and the first text or code block gives the HTML output a horizontal scroll bar so even very wide tables can be scrolled and everything else in HTML output is really very usable.

What’s wrong with the PDF output?

There are two main things:

  1. pagination

  2. chopping off the right hand side of wide tables.

Pagination

I can hardly blame the PDF output for having to be split into pages and this issue is of course an issue for Wurd output but it’s relatively easy to bully page breaks in Wurd. In principle I can do this by using

output:
 pdf_document:
   keep_tex: true

in the YAML header and then opening the saved tex file in a TeX editor but that’s hard work and I don’t know how to shrink graphics in a TeX so my control of pagination is … I don’t!

Wide tables

This is the real challenge. Because PDF output is based on the printed page tables that extend beyond the right margin of the PDF file page settings just get chopped. You can switch to landscape layout by adding

classoption: landscape

after the output block of the YAML Rmarkdown header so it’s like this (give or take your local preferences).

output:
 pdf_document:
   keep_tex: true
   toc: true
   toc_depth: 5
classoption: landscape

However with my latest lump of work that only rescued a few tables from being chopped and then I had to go through table by table trying to fix things. I do pretty much all my table formatting using the flextable package now and I had used it to create all these tables. The solutions were

tmpTib %>%
  flextable() %>%
  colformat_double(digits = 2) %>%
  colformat_double(j = 14 : 18,
                   digits = 1) %>%
  width(width = .45, 
        unit = "in")

That also shows me pruning the number of decimal places to one for some columns. A4 is 210 x 297 millimetres or 8.27 x 11.69 inches so you can work out a width that might work.

tmpTib %>%
  flextable() %>%
  fontsize(j = 1 : 18,
           size = 7, 
           part = "all") %>%
  colformat_double(digits = 2) %>%
  colformat_double(j = 14 : 18,
                   digits = 1) %>%
  width(width = .45, 
        unit = "in")

That shows all three tweaks: font size, decimal places and column widths being tweaked.

Summary

Well I hope that will be useful to me and perhaps to someone else!

Visit count

website counters

Last updated

Show code
cat(paste(format(Sys.time(), "%d/%m/%Y"), "at", format(Sys.time(), "%H:%M")))
13/07/2026 at 17:15

Reuse

Text and figures are licensed under Creative Commons Attribution CC BY-SA 4.0. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: "Figure from ...".

Citation

For attribution, please cite this work as

Evans (2026, July 13). Chris (Evans) R SAFAQ: Why I prefer making HTML from Rmarkdown. Retrieved from https://www.psyctc.org/R_blog/posts/2026-07-13-why-i-prefer-making-html-from-rmarkdown/

BibTeX citation

@misc{evans2026why,
  author = {Evans, Chris},
  title = {Chris (Evans) R SAFAQ: Why I prefer making HTML from Rmarkdown},
  url = {https://www.psyctc.org/R_blog/posts/2026-07-13-why-i-prefer-making-html-from-rmarkdown/},
  year = {2026}
}