In my previous post, I showed how to ditch media queries entirely and print beautifully styled HTML content using an image-based trick. It simplified printing by converting the content into an image and setting it into a hidden image element to be printed on a button click.

Take a look at how to print HTML content without Media Queries.

 Raheel Shan | Say Goodbye to Media Queries: Print Fully Styled HTML Content
Raheel Shan | Say Goodbye to Media Queries: Print Fully Styled HTML Content
Print HTML Content with Full Styles Applied, Without Media Queries, Printing Styled HTML Content, Excluding Media Queries, Say Goodbye to Media Queries: Print Fully Styled HTML Content, Print HTML Content with Styles, Media Queries No Longer Needed, Simplified Printing: HTML Styles Without Media Queries
raheelshan.com

That same technique can be reused with a slight twist — this time, to generate a downloadable PDF.

No backend. No media queries. No complex rendering pipeline.

Setup

                                <!-- HTML structure -->
<body>
    <div id="root-container">
        <!-- html content -->
        <div id="content-to-print">
            <!-- add your content here -->
        </div>
        <!-- other content -->
    </div>  
     <!-- empty image element to hold converted image from DOM -->
    <img src="" alt="" id="printed-image" />
</body>
                            

Then in JavaScript include files.

                                <script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.4.0/jspdf.umd.min.js"></script>
                            

And here is a Javascript function to convert HTML to PDF.

                                // function to be called on button click
function printImage() {
  generateImage()
}

// logic to convert content to image
function generateImage() {

  const style = document.createElement('style');
  document.head.appendChild(style);
  style.sheet?.insertRule('body > div:last-child img { display: inline-block; }');

  html2canvas(document.getElementById('content-to-print'), {
	  useCORS: true, // To handle cross-origin images
	  scale: 3,
	  backgroundColor: '#FFF', // Do not force a background color in html2canvas
	  scrollX: 0,
	  scrollY: 0,
	  windowWidth: document.documentElement.scrollWidth,
	  windowHeight: document.documentElement.scrollHeight
  }).then(function(canvas) {
	  const {
		  jsPDF
	  } = window.jspdf;
	  const imgData = canvas.toDataURL('image/png');
	  const pdf = new jsPDF('p', 'mm', 'a4'); // 'p' for portrait, 'mm' for millimeters, 'a4' for A4 size
	  const imgWidth = 210; // A4 width in mm (210mm)
	  const pageHeight = 285; // A4 height in mm (297mm)
	  const imgHeight = canvas.height * imgWidth / canvas.width;
	  const heightLeft = imgHeight;
	  let position = -7;

	  // Add a white background to the PDF page
	  pdf.setFillColor(255, 255, 255); // RGB for white
	  pdf.rect(0, 0, imgWidth, pageHeight, 'F'); // Fill the background

	  pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);

	  pdf.save('sample-file.pdf');
  });
}

                            

And finally, call the function on button click.

                                <div style="text-align: center; margin-top: 20px;">
    <h2>Download HTML as PDF</h2>
    <button 
        id="print-without-media" 
        onclick="printImage()" 
        style="padding: 10px 20px; background-color: #007bff; color: white; border: none; border-radius: 5px; margin: 5px; cursor: pointer;"
    >
        Download PDF
    </button>
</div>
                            

What’s Happening Here?

  • HTML2Canvas grabs a pixel-perfect snapshot of your HTML.
  • jsPDF takes that image and turns it into a downloadable PDF.
  • One button click, one function call.

Why This Approach?

  • You don’t need to struggle with PDF layout APIs.
  • It respects your existing CSS styles (including fonts and spacing).
  • No server-side rendering.
  • You can still apply the same technique for printing, emailing, or previewing content.

When to Use This

  • Invoices
  • Certificates
  • Reports
  • Styled documentation

If you’re after simplicity, this method is enough in 90% of the cases. And if you already followed the trick I shared in the last post, this is basically the same idea, just with a download instead of print.

A Quick Note on File Size

Keep in mind, if your content is large or has many images, the resulting PDF could be several MBs in size. It’s something to consider if you’re working with long documents or detailed graphics.

Demo

media-print-example/html-to-pdf.html at main · raheelshan/media-print-example · GitHub
media-print-example/html-to-pdf.html at main · raheelshan/media-print-example · GitHub
Contribute to raheelshan/media-print-example development by creating an account on GitHub.
github.com

If you found this post helpful, consider supporting my work — it means a lot.

 Raheel Shan | Support my work
Raheel Shan | Support my work
Support my work
raheelshan.com
Comments


Comment created and will be displayed once approved.