Skip to main content
Vue Print It allows you to add custom CSS specifically for printed output, giving you full control over how your documents appear on paper.

Adding print styles

Pass custom styles via the styles option:
<script setup>
import { usePrint } from 'vue-print-it'

const { print } = usePrint()

function handlePrint() {
  print('content', {
    styles: [
      'body { font-family: Arial, sans-serif; }',
      'h1 { color: #000; }',
      'p { line-height: 1.6; }'
    ]
  })
}
</script>

Using @media print rules

Add print-specific styles with @media print:
<script setup>
import { usePrint } from 'vue-print-it'

const { print } = usePrint()

function handlePrint() {
  print('content', {
    styles: [
      '@media print {',
      '  .no-print { display: none !important; }',
      '  .page-break { page-break-after: always; }',
      '  a { text-decoration: none; color: #000; }',
      '}'
    ]
  })
}
</script>
Join styles into a single string or use an array for better readability.

Hiding elements from print

Method 1: CSS class

Use a .no-print class:
<template>
  <div id="document">
    <h1>Document Title</h1>
    <p>This will be printed</p>
    
    <div class="no-print">
      <button @click="$print('document')">Print</button>
      <p>This won't be printed</p>
    </div>
  </div>
</template>

<style>
@media print {
  .no-print {
    display: none !important;
  }
}
</style>

Method 2: Inline with styles option

<script setup>
import { usePrint } from 'vue-print-it'

const { print } = usePrint()

function handlePrint() {
  print('content', {
    styles: [
      '@media print { .no-print, .hide-on-print { display: none !important; } }'
    ]
  })
}
</script>

Page breaks

Control where page breaks occur:
<template>
  <div id="report">
    <section>
      <h1>Section 1</h1>
      <p>Content for section 1...</p>
    </section>
    
    <div class="page-break"></div>
    
    <section>
      <h1>Section 2</h1>
      <p>Content for section 2...</p>
    </section>
  </div>
</template>

<script setup>
import { usePrint } from 'vue-print-it'

const { print } = usePrint()

function handlePrint() {
  print('report', {
    styles: [
      '.page-break { page-break-after: always; }',
      'section { page-break-inside: avoid; }'
    ]
  })
}
</script>

Page break properties

.page-break { 
  page-break-after: always; 
}
Forces a page break after the element.

Page margins

Set margins for printed pages:
<script setup>
import { usePrint } from 'vue-print-it'

const { print } = usePrint()

function handlePrint() {
  print('content', {
    styles: [
      '@page { margin: 1in; }',
      '@page { size: A4; }'
    ]
  })
}
</script>

Custom page sizes

<script setup>
import { usePrint } from 'vue-print-it'

const { print } = usePrint()

function printLetter() {
  print('content', {
    styles: ['@page { size: letter; margin: 0.5in; }']
  })
}

function printA4() {
  print('content', {
    styles: ['@page { size: A4; margin: 2cm; }']
  })
}

function printLandscape() {
  print('content', {
    styles: ['@page { size: A4 landscape; margin: 1cm; }']
  })
}
</script>

Typography for print

Optimize typography for printed output:
<script setup>
import { usePrint } from 'vue-print-it'

const { print } = usePrint()

function handlePrint() {
  print('document', {
    styles: [
      'body {',
      '  font-family: Georgia, serif;',
      '  font-size: 12pt;',
      '  line-height: 1.6;',
      '  color: #000;',
      '}',
      'h1 { font-size: 24pt; margin-bottom: 12pt; }',
      'h2 { font-size: 18pt; margin-bottom: 10pt; }',
      'h3 { font-size: 14pt; margin-bottom: 8pt; }',
      'p { margin-bottom: 12pt; text-align: justify; }'
    ]
  })
}
</script>

Colors and backgrounds

<script setup>
import { usePrint } from 'vue-print-it'

const { print } = usePrint()

function handlePrint() {
  print('invoice', {
    styles: [
      '/* Convert screen colors to print-friendly colors */',
      '.header { background-color: #f5f5f5 !important; }',
      '.total { background-color: #e5e5e5 !important; }',
      '/* Force background printing */',
      '-webkit-print-color-adjust: exact;',
      'print-color-adjust: exact;'
    ]
  })
}
</script>
By default, browsers don’t print background colors. Use -webkit-print-color-adjust: exact to force background printing.

Tables

Style tables for print:
<script setup>
import { usePrint } from 'vue-print-it'

const { print } = usePrint()

function handlePrint() {
  print('report', {
    styles: [
      'table {',
      '  width: 100%;',
      '  border-collapse: collapse;',
      '  page-break-inside: avoid;',
      '}',
      'th, td {',
      '  padding: 8px;',
      '  border: 1px solid #000;',
      '  text-align: left;',
      '}',
      'th {',
      '  background-color: #f0f0f0;',
      '  font-weight: bold;',
      '}',
      'tbody tr {',
      '  page-break-inside: avoid;',
      '}'
    ]
  })
}
</script>

Headers and footers

Add custom headers and footers:
<script setup>
import { usePrint } from 'vue-print-it'

const { print } = usePrint()

function handlePrint() {
  print('content', {
    styles: [
      '@page {',
      '  margin-top: 1.5in;',
      '  margin-bottom: 1in;',
      '  @top-left { content: "Company Name"; }',
      '  @top-right { content: "Page " counter(page); }',
      '  @bottom-center { content: "Confidential"; }',
      '}'
    ]
  })
}
</script>
Header/footer support varies by browser. Test in your target browsers.

Global styles

Set global styles during plugin registration:
// main.ts
import { createApp } from 'vue'
import { createVuePrintIt } from 'vue-print-it'

const app = createApp(App)

app.use(createVuePrintIt({
  styles: [
    '@page { margin: 1in; }',
    'body { font-family: Arial, sans-serif; }',
    '@media print { .no-print { display: none !important; } }'
  ]
}))
Global styles apply to all print operations unless overridden.

Complete invoice example

A comprehensive example with custom print styles:
<template>
  <div>
    <div id="invoice" class="invoice">
      <header class="invoice-header">
        <div class="company-info">
          <h1>Company Name</h1>
          <p>123 Business St</p>
          <p>City, State 12345</p>
        </div>
        <div class="invoice-meta">
          <h2>INVOICE</h2>
          <p><strong>Invoice #:</strong> {{ invoiceNumber }}</p>
          <p><strong>Date:</strong> {{ invoiceDate }}</p>
          <p><strong>Due:</strong> {{ dueDate }}</p>
        </div>
      </header>
      
      <section class="bill-to">
        <h3>Bill To:</h3>
        <p>{{ customer.name }}</p>
        <p>{{ customer.address }}</p>
      </section>
      
      <table class="items">
        <thead>
          <tr>
            <th>Description</th>
            <th>Qty</th>
            <th>Price</th>
            <th>Total</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="item in items" :key="item.id">
            <td>{{ item.description }}</td>
            <td>{{ item.quantity }}</td>
            <td>${{ item.price }}</td>
            <td>${{ item.quantity * item.price }}</td>
          </tr>
        </tbody>
        <tfoot>
          <tr>
            <td colspan="3" class="text-right"><strong>Subtotal:</strong></td>
            <td>${{ subtotal }}</td>
          </tr>
          <tr>
            <td colspan="3" class="text-right"><strong>Tax (8%):</strong></td>
            <td>${{ tax }}</td>
          </tr>
          <tr class="total-row">
            <td colspan="3" class="text-right"><strong>Total:</strong></td>
            <td><strong>${{ total }}</strong></td>
          </tr>
        </tfoot>
      </table>
      
      <footer class="invoice-footer">
        <p>Thank you for your business!</p>
      </footer>
    </div>
    
    <button @click="handlePrint" class="no-print">Print Invoice</button>
  </div>
</template>

<script setup>
import { computed } from 'vue'
import { usePrint } from 'vue-print-it'

const { print } = usePrint()

const invoiceNumber = 'INV-2024-001'
const invoiceDate = '2024-03-04'
const dueDate = '2024-03-18'
const customer = {
  name: 'John Doe',
  address: '456 Client Ave, City, State 12345'
}
const items = [
  { id: 1, description: 'Web Development', quantity: 40, price: 75 },
  { id: 2, description: 'Design Services', quantity: 10, price: 100 }
]

const subtotal = computed(() => 
  items.reduce((sum, item) => sum + (item.quantity * item.price), 0)
)
const tax = computed(() => subtotal.value * 0.08)
const total = computed(() => subtotal.value + tax.value)

function handlePrint() {
  print('invoice', {
    windowTitle: `Invoice ${invoiceNumber}`,
    styles: [
      '/* Page setup */',
      '@page {',
      '  size: A4;',
      '  margin: 0.75in;',
      '}',
      '',
      '/* Base styles */',
      'body {',
      '  font-family: Arial, sans-serif;',
      '  font-size: 11pt;',
      '  color: #000;',
      '}',
      '',
      '/* Invoice layout */',
      '.invoice {',
      '  max-width: 100%;',
      '  margin: 0;',
      '  padding: 0;',
      '}',
      '',
      '/* Header */',
      '.invoice-header {',
      '  display: flex;',
      '  justify-content: space-between;',
      '  margin-bottom: 30px;',
      '  padding-bottom: 20px;',
      '  border-bottom: 2px solid #000;',
      '}',
      '',
      '.company-info h1 {',
      '  margin: 0 0 10px 0;',
      '  font-size: 20pt;',
      '}',
      '',
      '.invoice-meta {',
      '  text-align: right;',
      '}',
      '',
      '.invoice-meta h2 {',
      '  margin: 0 0 10px 0;',
      '  font-size: 24pt;',
      '}',
      '',
      '/* Bill to section */',
      '.bill-to {',
      '  margin-bottom: 30px;',
      '}',
      '',
      '.bill-to h3 {',
      '  margin: 0 0 10px 0;',
      '  font-size: 12pt;',
      '}',
      '',
      '/* Table */',
      '.items {',
      '  width: 100%;',
      '  border-collapse: collapse;',
      '  margin-bottom: 30px;',
      '}',
      '',
      '.items th,',
      '.items td {',
      '  padding: 10px;',
      '  border: 1px solid #ddd;',
      '  text-align: left;',
      '}',
      '',
      '.items th {',
      '  background-color: #f0f0f0;',
      '  font-weight: bold;',
      '  -webkit-print-color-adjust: exact;',
      '  print-color-adjust: exact;',
      '}',
      '',
      '.items .text-right {',
      '  text-align: right;',
      '}',
      '',
      '.total-row {',
      '  background-color: #f5f5f5;',
      '  -webkit-print-color-adjust: exact;',
      '  print-color-adjust: exact;',
      '}',
      '',
      '/* Footer */',
      '.invoice-footer {',
      '  margin-top: 50px;',
      '  text-align: center;',
      '  font-style: italic;',
      '  color: #666;',
      '}',
      '',
      '/* Hide print button */',
      '.no-print {',
      '  display: none !important;',
      '}'
    ]
  })
}
</script>

Best practices

Stick to common system fonts that will render consistently:
  • Arial, Helvetica
  • Times New Roman, Georgia
  • Courier New
Print preview may differ from actual printed output. Always test on real printers and paper.
Use pt units for font sizes instead of px for better print consistency:
body { font-size: 12pt; }
h1 { font-size: 24pt; }
Absolute positioning can cause layout issues in print. Use relative or static positioning when possible.

Next steps

Style injection

Understand how styles are preserved

Configuration

View all style configuration options

Basic usage

Learn basic printing patterns

Error handling

Handle printing errors

Build docs developers (and LLMs) love