DEV Community

Raheel Shan
Raheel Shan

Posted on • Edited on • Originally published at raheelshan.com

Say Goodbye to CSS Media Queries: Print Fully Styled HTML Content

Printing HTML content with all styles intact has always been a challenging task for me. Media queries often complicate things when trying to achieve a clean and consistent print layout. However, I recently discovered a simple solution that bypasses the need for media queries altogether. Here’s how I did it.

The Solution: Using jsPDF to Print HTML as an Image

I used jsPDF, a JavaScript library, to convert HTML content into an image. This image is then set into a hidden element, which is displayed only during print. The idea is straightforward:

The HTML Structure

The HTML body has two main elements:

  • A containing the main content with id root-container.
  • A hidden <img> element with id printed-image outside of root-container where the image generated by jsPDF will be stored.
<body> <div id="root-container"> <!-- html content --> <div id="content-to-print"></div> <!-- other content --> </div> <img src="" alt="" id="printed-image" /> </body> 

Convert Content to Image

  • Extract the HTML content you want to print and use jsPDF to convert it into an image.
  • Save the generated image into the hidden <img> element (#printed-image).
// generate image on document ready to be saved in image tag $(document).ready(function() { generateImage() }) // function to be called on button click function printImage() { window.print(); } // 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); $('#printed-image').prop('src', imgData) }); } 

CSS for Print

Add print-specific styles to hide the main content and display only the generated image when the print button is pressed.

/* Default styles */ #printed-image { display: none; } /* Print-specific styles */ @media print { #root-container { display: none !important; } #printed-image { display: block !important; /* Force image to display only during print */ margin: auto; /* Optional: center the image */ max-width: 100%; /* Ensure image fits the page */ } } 

Final Workflow

  • When the document is ready html content will be converted to image
  • This image is placed inside the hidden <img> element.
  • During printing, the main content (#root-container) is hidden, and the image (#printed-image) is displayed.

Why This Approach Works

By converting the HTML content into an image

  • Media Queries Become Obsolete: Styles are baked into the image, so there’s no need to tweak styles for different screen sizes or layouts.
  • Consistent Print Output: The image ensures that the print result matches what you see on the screen, regardless of the printer or browser quirks.

Demo

Source Code

Top comments (0)