Print-Optimized Table View — Real @media print Rules (HTML CSS JS)

Print-Optimized Table View · Tables · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Real @media print rules
A genuine print-scoped stylesheet, not a screenshot-style mockup.
Interactive chrome hidden
The Print button and pagination controls disappear only in print output.
Print-only header block
A title and stamped date exist in the DOM but display only under @media print.
Forced black-on-white
Colored backgrounds and hover tints are overridden for ink-conscious paper output.
No mid-row page breaks
page-break-inside: avoid keeps each table row intact across page boundaries.
Sortable on screen
Click any header to sort; sort indicators hide automatically when printing.
Paginated on screen
Prev/Next paging keeps the live view compact without affecting print output.
No library
Pure CSS media queries and vanilla JS — no print/PDF dependency.

About this UI Snippet

Print-Optimized Table View — Clean Paper Output via Real @media print

Screenshot of the Print-Optimized Table View snippet rendered live

A table styled for a screen almost never looks right on paper — colored backgrounds waste ink, hover states and sort arrows are meaningless on a printed page, and rows can split awkwardly across a page break. This snippet builds a sortable, paginated table with a genuine @media print stylesheet that transforms it into a clean printed report, in plain HTML, CSS, and vanilla JavaScript.

Interactive chrome disappears on paper

The @media print block sets display: none on the header bar's Print button and the pagination controls — elements that mean nothing once ink is on paper. It also removes the header row's pointer cursor and hides the sort-direction arrows, since a printed page can't respond to a click. None of this is done by hiding elements in JavaScript; it's pure CSS scoped to the print media type, so the interactive page is completely unaffected and the transformation only happens inside the browser's print pipeline.

A dedicated print header, invisible on screen

A .tpv-print-head block containing a title and a "Printed [date]" line sits in the HTML the whole time but is display: none by default — the print stylesheet flips it to display: block only under @media print. This is the reverse pattern from hiding controls: an element that exists solely for the printed page, invisible during normal browsing, populated with the current date right before window.print() is called.

Forced black-on-white, ink-conscious styling

Screen styling uses colored header backgrounds and hover tints; the print block overrides all of that to plain black text on white with a simple black rule under the header, and turns off the hover background entirely (tbody tr:hover{background:none}) since a static printout can never be mid-hover. This isn't just aesthetic — colored backgrounds print poorly and waste toner on a report meant to be read, not decorated.

No row splits across a page break

page-break-inside: avoid on each <tr> tells the browser's print engine never to split a single row's content across two physical pages — without it, a taller row can render its top half on one page and the rest on the next, which is illegible. This is a print-specific CSS property with no screen equivalent, and it's the single most common thing missing from a "printable" table that was never actually tested in print preview.

Full data, not just the visible page

The visible UI paginates for on-screen usability (five rows per page with Prev/Next), but printing needs the complete dataset, not whichever page happens to be showing. Because the pager controls are hidden in print but the table itself renders from the full sorted ROWS array up to the current page's slice, a production version of this pattern would render *all* rows into the DOM before calling window.print() (or render an unpaginated print-only table) so the printed report is complete — a detail worth handling explicitly rather than assuming print output matches the last-viewed screen page. Pair this with a table export menu if you also want CSV/JSON alongside the print option.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Instead of discovering print bugs only after actually printing, paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why page-break-inside: avoid is applied to each table row rather than to the table as a whole, and why the print-only header block is kept in the DOM at all times with display: none instead of being injected dynamically only when printing. The same assistant can help extend it — ask it to render the full unpaginated dataset into a hidden print-only table right before window.print() so the printed report is always complete regardless of the on-screen page, add a page-number footer using CSS counters, or generate a real PDF via a headless-browser service instead of relying on the user's own print-to-PDF option. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a sortable, paginated data table with a working Print button and a real print-optimized stylesheet, in plain HTML, CSS, and JavaScript — no libraries.

Requirements:
- An on-screen table that supports click-to-sort column headers (toggling ascending/descending) and Prev/Next pagination over an in-memory array of row records.
- A Print button that, when clicked, populates a hidden print-only header element with the current date and then calls the browser's native window.print() function.
- A print-only header block (a title and a "Printed on [date]" line) that exists in the HTML at all times but is display: none by default, becoming visible only inside an @media print rule — verify it never appears during normal on-screen browsing.
- A real @media print CSS block that: hides the Print button and the pagination controls entirely (display: none); removes the sort-direction indicator icons and the header row's pointer cursor styling, since neither can do anything on paper; overrides any colored header backgrounds, borders, and hover-state backgrounds to plain black text on a white background, since a static printout can never be mid-hover and colored backgrounds waste ink.
- Apply page-break-inside: avoid to each table row specifically (not to the table as a whole) so that no single row's content is ever split across two physical pages when printed on paper with many rows.
- Verify using the browser's print preview that the on-screen sort/pagination controls, sort arrows, and Print button are completely absent from the printed output, while the print-only header with the stamped date is visible only there.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA sortable, paginated asset table renders with a Print button.
  2. 2
    Sort or page through itClick a header to sort; use Prev/Next to page — this is the normal on-screen view.
  3. 3
    Click PrintThe print date is stamped and window.print() opens the browser's print dialog.
  4. 4
    Check print previewThe Print button, pager, sort arrows, and hover states are all absent from the preview.
  5. 5
    Note the print headerA title and "Printed [date]" line appears only in the print output, never on screen.
  6. 6
    Look at row boundariespage-break-inside: avoid keeps each row intact even near a page break.

Real-world uses

Common Use Cases

Asset registers and inventories
Print a clean physical record for audits, alongside a CSV export table for digital copies.
Invoices and statements
Produce paper-ready output next to an invoice line items table.
Compliance and audit reports
Generate dated, chrome-free printouts for filing.
Attendance and roster sheets
Print clean lists for physical sign-in or reference.
Any admin table needing hard copies
Add a Print action beside a data table or sortable table.
Learning print stylesheets
A reference for real @media print CSS — compare with the print action inside a table export menu.

Got questions?

Frequently Asked Questions

The @media print stylesheet sets display: none on the button's container, the .tpv-bar, and on the pagination controls, .tpv-pager. These rules only apply while the browser is rendering for print (print preview or an actual printer) — the on-screen page is completely unaffected, since the same elements have normal display values outside the media query.

It's a print-specific CSS property applied to each table row that instructs the browser's print engine not to split that row's content across two physical pages. Without it, a row that happens to fall near a page boundary can print its top half on one sheet and the remainder on the next, which is illegible — this property forces the whole row onto whichever page it fits on cleanly.

The .tpv-print-head element (a title and a "Printed [date]" line) exists in the DOM at all times but is display: none by default and only flips to display: block inside the @media print rules. This lets the printed page carry context — what the report is and when it was generated — without cluttering the on-screen interactive view, where that header would be redundant.

In this demo the table body reflects whatever page is currently sorted/paged on screen, since the pager is a live on-screen feature. For a production report you'd typically render the full dataset (or an unpaginated print-specific table) into the DOM right before calling window.print(), since a print reader expects the complete report, not just whichever page happened to be open.

Keep the @media print CSS exactly as global or component-scoped styles (print stylesheets aren't framework-specific), call window.print() from your Print button's click handler, and populate the print-only header's date via state right before printing. The sort/pagination logic and the print CSS are independent concerns and port separately.