Say Goodbye to 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 element with id printed-image outside of root-container where the image generated by jsPDF will be stored. 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 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 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.

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
element with id printed-image outside of root-container where the image generated by jsPDF will be stored.
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
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
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.