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.
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.htmlAnd force-copy images not referenced in QMD content:
resources:
- images/my-image.pngThe resources: key goes at the YAML top level, not under format:.