npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

htmlasitis

v0.1.0

Published

A4 print-safe CSS library for HTML books. One .hai-page section becomes exactly one printed A4 page.

Readme

htmlasitis

A4 print-safe CSS library for HTML books.

Guarantee: one .hai-page section becomes exactly one printed A4 page. No overflow. No empty pages. No widow page numbers.

Tested against the Chromium print engine (Chrome, Edge, Brave, Opera).

Why this library exists

Browsers were not built for books. They were built for documents that scroll forever. When you try to print HTML to A4 sheets, the browser makes its own decisions about how to break content across pages, and those decisions are usually wrong:

  • Headings get orphaned at the bottom of pages
  • Tables split across page boundaries
  • Page numbers jump to the next page alone
  • Content overflows silently and creates extra pages

This library enforces a simple rule that solves all of these problems: each .hai-page section is exactly one printed page. If your content does not fit, it gets clipped, and you find out immediately when you run the validation script.

This trades flexibility for predictability. That is the right trade for books.

Quick start

# 1. Set up the environment (run once)
./run/init.sh

# 2. Edit example.html or copy template.html to start a new book

# 3. Preview in a browser
./run/dev.sh
# Open http://localhost:8000/example.html

# 4. Validate that page counts match
./run/test.sh example.html

If the test passes, your book prints exactly. If it fails, the script tells you how many extra pages were created and where to look.

How to use the library

Minimum HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="htmlasitis.css">
</head>
<body>

  <section class="hai-page">
    <h1>Your Chapter Title</h1>
    <p>Your content...</p>
    <div class="hai-page-number">— 1 —</div>
  </section>

</body>
</html>

That is it. Wrap each printed page in <section class="hai-page">. The library handles the rest.

Components

All components are documented with a content budget — roughly how much text fits when you use that component on a page.

.hai-page (required)

The fundamental unit. Each one is exactly 210mm × 297mm with 18mm horizontal and 20mm vertical padding. Content area: 174mm × 257mm.

Content budget: about 1800 characters of body text alone, less when you add other components.

.hai-cover

Combine with .hai-page to make a book cover. Centers content vertically with flexbox.

<section class="hai-page hai-cover">
  <div class="hai-cover-volume">Volume 1</div>
  <h1>Book Title</h1>
  <div class="hai-cover-subtitle">Subtitle here</div>
  <div class="hai-cover-author">Author · Year</div>
</section>

.hai-divider

A part divider page. Like cover, but for sections within a book.

<section class="hai-page hai-divider">
  <h1>Part Two</h1>
  <div class="hai-divider-subtitle">The subtitle of this part</div>
</section>

.hai-page-number

A page number pinned to the bottom of the page. Uses absolute positioning, so it always sits 12mm from the bottom regardless of content above it.

<div class="hai-page-number">— 42 —</div>

.hai-callout

A bordered box for emphasizing one key insight per page.

<div class="hai-callout">
  The most useful constraint is the one that tells you when you
  have written too much.
</div>

Content budget cost: about 200 characters less of body text.

.hai-example, .hai-example-good, .hai-example-bad

Boxes for showing examples, optionally framed as good or bad.

<div class="hai-example hai-example-bad">
  <div class="hai-example-label">BEFORE</div>
  An example of what not to do.
</div>

<div class="hai-example hai-example-good">
  <div class="hai-example-label">AFTER</div>
  An example of what to do instead.
</div>

Content budget cost: about 150 characters per example.

.hai-annotation

A side note. Like a callout but with a left border instead of a full border. Less prominent.

<div class="hai-annotation">
  <div class="hai-annotation-label">NOTE</div>
  An aside that supplements the main text.
</div>

Content guidelines

The library enforces page boundaries. It cannot enforce content density. That is your job. Here are the budgets:

| Page composition | Body text budget | | --- | --- | | H1 + body text only | ~1500 characters | | H1 + H2 (×2) + body text | ~1300 characters | | H1 + 1 callout + body text | ~1300 characters | | H1 + 1 small table + body text | ~1000 characters | | H1 + 1 code block + body text | ~1100 characters | | H1 + 2 example boxes + body text | ~1200 characters | | Pure body text (no H1) | ~1800 characters |

These are at the default font size (11pt) and line height (1.55). If you change those, the budgets change.

How to write to budget:

  1. Draft your chapter in plain text first
  2. Count characters: wc -m chapter.txt (or use word count in your editor)
  3. Divide by your budget to estimate page count
  4. Split your text into sections of roughly that size
  5. Each section becomes one .hai-page

When in doubt, run the test. If the validation passes, you are within budget.

How to write a book that prints cleanly

These are practical rules that emerge from working within the library's constraints:

1. One topic per page

A .hai-page is a unit of attention. Treat it as one idea, one argument, one example. If you find yourself wanting to put two unrelated topics on one page, split them.

2. End on a complete thought

Because pages cannot overflow, your last paragraph must finish within the page. Plan your final sentence as you write — do not let it become a half-thought because you ran out of space.

3. Use page numbers consistently

Every content page should have a .hai-page-number. Cover and divider pages do not. Number from page 2 onward (the page after the cover).

4. Test early, test often

Run ./run/test.sh whenever you finish a draft of a chapter. The test runs in seconds and catches overflow problems before they compound.

5. Treat overflow as a writing prompt

When the validation fails, do not just delete words to fit. Ask what the overflow is telling you about the chapter. Often it means you have two ideas crammed into one page, and they want to be two pages.

6. Keep typography stable

Avoid changing font sizes mid-book. Each typography change shifts your content budget for that page. The CSS variables let you theme the whole book once at the top — use that, do not override in individual pages.

Theming with CSS variables

All visual properties are CSS variables defined in :root. Override them at the top of your HTML to theme your whole book at once:

<style>
  :root {
    --hai-font-body: "Your Font", sans-serif;
    --hai-font-mono: "Your Mono Font", monospace;
    --hai-font-size-body: 12pt;
    --hai-line-height-body: 1.6;
  }
</style>

See htmlasitis.css for the full list of variables.

Note that changing font size or line height changes your content budget per page. Re-run validation after any theming change.

How the library works under the hood

A short tour of the engineering:

@page { margin: 0 }

Browsers add their own margins to printed pages by default (about 9.5mm in Chromium). We disable that and use .hai-page padding to create margins. This gives us per-page control and defeats browser defaults that would shift our layout.

Fixed .hai-page dimensions

Each page is exactly 210mm × 297mm with padding: 20mm 18mm. This is not responsive — it is intentionally rigid. The content area is precisely 174mm × 257mm, every time.

overflow: hidden on .hai-page

This is the core trick. It clips content that exceeds the page. Without this, the browser would helpfully flow content to a new page and create an empty page after each overflow. With this, overflow becomes visible (clipped content) and detectable (failed test).

break-after: page for page boundaries

Each .hai-page ends with a forced page break. The legacy page-break-after: always is included alongside for compatibility.

print-color-adjust: exact

By default, browsers do not print background colors to save ink. We force exact color rendering for callouts, code blocks, and table headers, so the printed book looks like the screen book. Users no longer need to enable "Background graphics" in the print dialog.

Heading cohesion via break-after: avoid

Headings cannot end up alone at the bottom of a page. The browser will pull them onto the next page with their following content if needed. (This rarely matters within a .hai-page because it cannot break, but it matters if you nest content in unusual ways.)

Validation script details

./run/test.sh does three things:

  1. Renders the HTML file to PDF using headless Chromium
  2. Counts <section class="hai-page"> in the source
  3. Compares to the page count of the generated PDF

If the counts match, your book prints predictably. If they do not, some content overflowed and created extra pages.

The script accepts any HTML file as an argument:

./run/test.sh my-book.html
./run/test.sh chapters/chapter-3.html

Browser support

| Browser | Engine | Status | | --- | --- | --- | | Chrome | Chromium | Tested, works | | Edge | Chromium | Tested, works | | Brave | Chromium | Tested, works | | Opera | Chromium | Should work | | Firefox | Gecko | Most features work, some edge cases differ | | Safari | WebKit | print-color-adjust works, otherwise less tested |

The library is primarily targeted at Chromium because of its strong print CSS support and predictable behavior. Validation requires Playwright with Chromium.

Browser print dialog settings

The library is designed to print correctly with default print dialog settings:

  • Paper size: A4 (matches CSS @page size: A4)
  • Margins: any setting works, because we use @page margin: 0 and create margins via .hai-page padding
  • Background graphics: any setting works, because we force background printing with print-color-adjust: exact
  • Headers and footers: should be off — turn this off in the print dialog so the browser does not add its own page numbers on top of yours

The only setting that matters: turn Headers and footers off.

Files in this library

htmlasitis/
├── README.md              This file
├── htmlasitis.css         The CSS library
├── template.html          Minimal starting point for new books
├── example.html           Demonstrates all components
├── overflow-test.html     Verifies clipping behavior
└── run/
    ├── init.sh            Install Playwright + Chromium
    ├── test.sh            Validate page counts
    └── dev.sh             Run local server for preview

License

Use it however you want. Ship books.