How to optimize CSS for print media queries in Laravel Blade
Remove background colors, hide interactive elements, and adjust font sizes for print output using media queries and CSS classes.
Remove interactive elements, hide background images, and adjust font sizes so your web pages look professional when printed. These steps apply to Laravel Blade templates running on Ubuntu 24.04 or any standard Linux server.
Prerequisites
- A Laravel 11.x application installed and running.
- Access to the project's
resources/viewsdirectory. - Basic knowledge of CSS media queries and the
@pushdirective. - A browser that supports
@media printrules.
Step 1: Create a dedicated print stylesheet
Create a new file specifically for print styles to keep your main CSS clean. Place this file in your resources/css directory or create a new one in resources/views if you prefer inline styles for Blade templates.
touch resources/css/print.css
Open the file and add a rule that hides all elements that should not appear on paper. This includes buttons, navigation bars, and social media icons.
@media print {
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
font-size: 12pt;
line-height: 1.5;
color: #000000;
background: #ffffff;
}
a {
text-decoration: underline;
color: #000000;
}
a[href^="http"]::after {
content: " (" attr(href) ")";
}
pre, code {
font-family: monospace;
white-space: pre-wrap;
background-color: #f4f4f4;
border: 1px solid #ccc;
padding: 10px;
}
img {
max-width: 100%;
height: auto;
}
/* Hide interactive elements */
.btn, .button, input[type="submit"], input[type="button"], a.btn, button {
display: none !important;
}
/* Hide navigation and headers */
nav, footer, .sidebar, .header, .top-bar, .bottom-bar {
display: none !important;
}
/* Hide forms */
input, textarea, select {
border: 1px solid #ccc;
padding: 5px;
display: block;
width: 100%;
box-sizing: border-box;
}
/* Hide tables headers if not needed, but usually keep them */
thead {
display: table-header-group;
}
tr {
page-break-inside: avoid;
}
td, th {
border: 1px solid #000;
padding: 4px;
}
}
Step 2: Add the print stylesheet to your layout
Include the new stylesheet in your main layout file so it loads only when the print media query is active. Use the @push directive in your Blade layout to add the CSS link tag conditionally.
-- In resources/views/layouts/app.blade.php --
@push('styles')
<link rel="stylesheet" href="{{ asset('css/print.css') }}" media="print">
@endpush
Alternatively, if you are using Tailwind CSS or a build process, you can use the @mixin or @mixin approach to conditionally inject styles. For standard Laravel Blade, the media="print" attribute on the <link> tag ensures the browser only downloads and applies the styles when the user initiates a print dialog.
Step 3: Create print-specific utility classes
Define utility classes in your CSS to control specific behaviors like hiding elements or forcing page breaks. This makes it easier to apply rules directly in your Blade views without writing complex CSS selectors every time.
@media print {
.no-print {
display: none !important;
}
.break-inside-avoid {
page-break-inside: avoid;
}
.page-break {
page-break-after: always;
}
.hide-on-print {
display: none !important;
}
.show-on-print {
display: block !important;
}
}
Use these classes in your Blade templates to toggle visibility based on the output medium. For example, add the no-print class to any element that should not appear on paper, such as a "Print this page" button or a login form.
Step 4: Apply print classes to your Blade views
Update your existing Blade templates to use the new utility classes. Add the no-print class to interactive elements and the break-inside-avoid class to tables or cards that should stay together.
-- resources/views/articles/show.blade.php --
<div class="card break-inside-avoid">
<h1>{{ $article->title }}</h1>
<p>{{ $article->content }}</p>
</div>
<button class="btn no-print">Print</button>
<form action="/login" method="POST" class="no-print">
<input type="email" name="email" />
<input type="password" name="password" />
<button type="submit" class="no-print">Login</button>
</form>
This ensures that when a user opens the print dialog, the form and button disappear, leaving only the article content. The table or card remains intact because of the break-inside-avoid rule.
Step 5: Optimize images for print
Ensure images are optimized for print by setting their maximum width to 100% and preventing them from stretching. Use the max-width property in your print stylesheet to ensure images fit within the page margins.
@media print {
img {
max-width: 100%;
height: auto;
page-break-inside: avoid;
}
}
Also, consider adding a rule to hide images that are not relevant to the print version, such as ads or decorative icons. This reduces ink usage and improves readability.
Verify the installation
Test your changes by opening a page in your browser and triggering the print dialog. Press Ctrl + P (Windows/Linux) or Cmd + P (Mac) to open the print preview. Check that:
- Background colors are removed or preserved only if
-webkit-print-color-adjust: exactis set. - Interactive elements like buttons and forms are hidden.
- Tables do not break awkwardly across pages.
- Fonts are readable and sized appropriately.
- Images are scaled correctly and do not overflow the page width.
If you see any elements that should be hidden, add the no-print class to them. If tables are breaking, add the break-inside-avoid class to the <table> tag or the <tr> tags.
Troubleshooting
If background colors are still visible on the printed page, add the following rule to your print stylesheet:
@media print {
* {
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
}
If the print preview shows a blank page or missing content, check that your layout file includes the print stylesheet link. Ensure the media="print" attribute is present on the <link> tag. If the browser caches the old CSS, clear the cache or use a private browsing window to test.
If tables are breaking across pages despite using break-inside-avoid, try wrapping the table in a div with the same class. Some browsers require the wrapper to respect the break rule. If the issue persists, consider splitting large tables into multiple smaller tables that fit within a single page.
If images are not scaling correctly, ensure that the img tag does not have a fixed width or height set in HTML. Rely on the CSS max-width property to control the size. If images appear pixelated, ensure they are high-resolution files suitable for print output.