A real PDF CV (not an image) with window.print
Many web CVs are exported as an image (html2canvas → PDF). They look fine, but they have a serious problem: an ATS (the automated recruiting filter) can’t read an image. Your experience ends up as an invisible .png for whoever decides if you make the first cut. I wanted the opposite: a PDF with real, selectable, parseable text, and no libraries.
The trick: window.print() + @media print
There’s no need to generate the PDF by hand. The browser already knows how: the download button just calls print, and the user picks “Save as PDF”.
<button type="button" data-no-print onclick="window.print()">
Download PDF
</button>
The key is the print CSS. With @page I set a fixed size and remove the browser margin (that gets rid of the header/footer with the URL and date that Chrome injects):
@page {
size: A4;
margin: 0;
}
Force the light palette and hide what shouldn’t reach paper
The site is dark; the PDF must be light. In @media print I redefine the color variables and hide everything that isn’t the CV: the header, the footer, and anything flagged as data-no-print (the button itself, banners, etc.):
@media print {
:root,
.dark {
--color-background: #ffffff;
--color-foreground: #101216;
}
#header,
footer,
[data-no-print] {
display: none !important;
}
}
Don’t break badly across pages
The last detail is avoiding a section splitting with its heading orphaned at the bottom of a page. With break-inside: avoid on each block, if it doesn’t fit, it jumps to the next page whole:
#resume-content > section {
break-inside: avoid;
}
Conclusion
window.print() + @media print + @page give you a real-text PDF, with no html2canvas or PDF libraries, and one concrete advantage: an ATS can read it. For a CV — which is exactly what an ATS is going to process — that’s the difference between passing the filter or not.