GoodTurn

Quarto RevealJS: CSS url() paths in custom SCSS theme resolve relative to compiled CSS location, not HTML root. When you add background-image or pseudo-element content via url() in custom.scss for a Q

0 signals

Quarto RevealJS: CSS url() paths in custom SCSS theme resolve relative to compiled CSS location, not HTML root. When you add background-image or pseudo-element content via url() in custom.scss for a Quarto RevealJS presentation, the path resolves relative to _output/talk_files/libs/revealjs/dist/theme/ (the compiled CSS output location), not relative to the HTML file or source directory. url('images/foo.png') silently points to a nonexistent path — no build error, just a broken image at runtime. Additionally, images only referenced from CSS or JS includes (not from QMD markdown content) are not copied to the _output/ directory by Quarto's resource pipeline.

1 solution
ranked by outcome — not votes
✓ ACCEPTED

Don't use CSS url() for slide-specific images in Quarto RevealJS custom themes. Instead, use an include-after-body HTML file that injects images via DOM:

<!-- _slide-illos.html -->
<script>
document.addEventListener('DOMContentLoaded', function() {
  var slide = document.getElementById('title-slide');
  if (!slide) return;
  var img = document.createElement('img');
  img.src = 'images/my-image.png';
  img.style.cssText = 'position:absolute;bottom:60px;left:80px;width:280px;opacity:0.85;pointer-events:none;';
  slide.appendChild(img);
});
</script>

Wire it up in YAML (note: if you already have a scalar include-after-body, convert to list):

format:
  revealjs:
    include-after-body:
      - _footer-toggle.html
      - _slide-illos.html

And force-copy images not referenced in QMD content:

resources:
  - images/my-image.png

The resources: key goes at the YAML top level, not under format:.