Preparando páginas para impressão com CSS, Paged.js ou outras ferramentas

Existem algumas estilizações do CSS que são especialmente úteis em impressões ou para gerar PDFs, mas pouca gente conhece porque é incomum precisar se preocupar com esse tipo de cenário. Encontrei uma publicação no Hacker News onde as pessoas compartilharam várias coisas úteis nos comentários e achei legal trazer para cá, assim quando alguém precisar estilizar um conteúdo para impressão pode usar esta publicação como referência.

Um caso de uso que parece mais comum aqui no TabNews é que isso pode ser útil para um site que é o seu currículo, já que o recrutador pode querer salvar em PDF, ou você mesmo pode criar um botão para isso.

Visão geral

A documentação do MDN é sempre uma boa referência para entender melhor como as coisas funcionam, mas a publicação do Hacker News foi sobre um artigo chamado CSS for printing to paper.

Nesse artigo, o autor coloca alguns exemplos de códigos e mostra imagens de como fica a impressão com diferentes estilizações, explicando como funciona o size e margin na regra @page, e também a media query @media print, onde você pode definir estilizações específicas para a impressão.

Estilizações úteis

Como eu disse, na publicação do Hacker News compartilharam algumas estilizações que eu considerei bastante úteis, então trago um resumo aqui:

  • h1,h2,h3,h4,h5,h6 {break-after: avoid-page;}: Evita imprimir cabeçalhos de seção na parte inferior de uma página, deixando o conteúdo da seção sem cabeçalho na parte superior da página seguinte.
  • img, svg, table, canvas {break-inside: avoid;}: Dá preferência à imprimir gráficos e figuras em páginas inteiras em vez de dividi-las em páginas.
  • a::after {content: " (" attr(href) ")";}: Imprime a URL de cada link em vez de ter links apenas como texto sublinhado.
  • footer {page-break-inside: avoid;}: Não quebrar o footer em páginas separadas.
  • summary {page-break-after: avoid;}: Não quebrar após o elemento summary (para o elemento details). Se os elementos de details nunca forem maiores que a página, details {break-inside: prevent;} pode ser útil.
  • body {min-width: 992px;}: Evita renderizar a versão mobile de uma página.

Paged.js

O usuário didgeoridoo criou um comentário falando sobre sua experiência ao escrever um livro usando o Paged.js:

Acabei de publicar um livro usando o Pagedjs.org. Embora tenha havido alguns bugs na experiência de visualização, o resultado final foi perfeito e provavelmente levou um quarto do tempo que levaria no InDesign (no qual sou bastante competente).

O verdadeiro poder está em ser capaz de conectar todos os modelos, APIs CMS e tudo o mais que você desejar em seu pipeline de conteúdo. É apenas HyperText™.

Eu diria que se você se sente igualmente confortável com HTML/CSS e InDesign, o Pagedjs é uma escolha superior para layouts longos.

Como o nome deixa a entender, o Paged.js é uma biblioteca JavaScript, que tem seu código disponível no GitHub e no GitLab (apesar do site deles ter um link apenas para o GitLab, o repositório do GitHub está mais atualizado).

O Paged.js segue os padrões de Paged Media publicados pelo W3C (o Paged Media Module e o Generated Content for Paged Media Module), atuando como um polyfill para os módulos CSS imprimirem conteúdo usando recursos que ainda não são suportados nativamente pelos navegadores.

No site do projeto tem alguns exemplos de resultados bem interessantes, que eu nem imaginaria que esses livros foram feitos com HTML + CSS + JS:

Um livro aberto com o título da página dividido em duas páginas, e o texto normal.

Um livro aberto com a imagem de uma escultura na página esquerda, e texto na página direita.

Um livro aberto com texto na página esquerda, e código na página direita, sendo que a página direita tem uma cor diferente.

Outros comentários também falaram bem do Paged.js, principalmente por conta dos polyfills que ele disponibiliza, como por exemplo notas de rodapé. Eu nunca precisei usar essa biblioteca, mas acredito que vale a pena experimentar caso você pretenda escrever um livro ou e-book. Para casos mais simples, o CSS básico deve resolver.

Outras ferramentas que mencionaram nos comentários foram:

Se você já precisou usar alguma ferramenta ou tem um conjunto de estilos que considera útil para essa situação, compartilhe nos comentários.