Programação Por Equipe DevBras

Capa do artigo: CSS de impressão: a página que sai no papel sem menu, anúncio e fundo preto

CSS de impressão: a página que sai no papel sem menu, anúncio e fundo preto

Monte uma folha de estilo de impressão que esconde o que é só de tela, mantém o texto legível e mostra o endereço dos links. E saiba quando o certo é gerar PDF.

O cliente da loja clica em "imprimir comprovante" e a impressora entrega três folhas: o menu inteiro na primeira, um banner de frete grátis na segunda e, na terceira, o número do pedido espremido ao lado de um retângulo cinza que era o rodapé. A resposta curta: quem imprime é o navegador, não o PHP. O servidor só entrega HTML, e o que vai para o papel é decidido por uma folha de estilo com @media print. Você esconde o que é de tela, ajusta cor e largura e chama window.print().

Quando o documento precisa sair idêntico em qualquer máquina, como nota, boleto ou contrato, a resposta muda: gere PDF no servidor. O resto deste guia mostra as duas coisas usando o mesmo exemplo, a página de comprovante de pedido de uma loja pequena.

Por que a tela vira um papel tão ruim

O navegador, na hora de imprimir, pega a mesma página que você vê e a pagina em folhas A4 ou Carta. Ele aplica todas as regras de CSS que valem para "todas as mídias", o que inclui menu fixo, barra lateral, botão de compartilhar e banner de cookies. Nada disso some sozinho, porque o navegador não sabe o que é decoração e o que é conteúdo.

Ao mesmo tempo, ele toma decisões por conta própria. Por padrão, a maioria dos navegadores não imprime cores e imagens de fundo, para economizar tinta. Se o seu tema é escuro com texto branco, o fundo some e o texto branco fica invisível no papel branco. Larguras fixas em pixels, pensadas para monitor, também podem cortar a coluna direita.

Por fim, link no papel não se clica. "Veja a política de trocas" impresso, sem o endereço, é uma instrução que ninguém consegue seguir.

Como montar a folha de impressão

  1. Abra o comprovante e ative a simulação de impressão. No Chrome e no Edge, isso fica nas DevTools, na aba Rendering, em "Emulate CSS media type". No Firefox, há um botão de simular impressão no painel de regras do Inspetor. Assim você ajusta sem gastar folha.
  2. Liste o que é só de tela: navegação, rodapé, botões, banner, chat de atendimento, campo de busca.
  3. Escreva um bloco @media print no fim do CSS principal, ou um arquivo separado ligado com media="print" na tag link.
  4. Esconda o que é de tela, force fundo branco e texto preto e solte as larguras fixas.
  5. Peça para não quebrar página no meio de blocos que precisam ficar juntos, como a tabela de itens e o total.
  6. Abra a pré-visualização real de impressão do navegador num pedido grande, com muitos itens, e confira a segunda folha.

O CSS do comprovante

@media print {
  .topo, .menu, .rodape, .banner-frete, .chat, .acoes {
    display: none !important;
  }

  body {
    background: #fff;
    color: #000;
    font: 11pt/1.4 Georgia, "Times New Roman", serif;
  }

  .conteudo {
    width: auto;
    max-width: none;
    margin: 0;
    padding: 0;
  }

  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 9pt;
  }

  h2, h3 {
    break-after: avoid;
  }

  .itens-do-pedido, .total, blockquote, img {
    break-inside: avoid;
  }

  .selo-pago {
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }
}

@page {
  margin: 15mm;
}

Algumas decisões aí merecem explicação. O !important no bloco de esconder existe porque menu e chat costumam vir de componentes com CSS próprio e mais específico. O seletor a[href^="http"]::after só imprime o endereço de links externos completos, para não poluir a folha com âncoras internas. E print-color-adjust: exact fica restrito ao selo "PAGO", que precisa sair com a cor; aplicar isso na página toda traz de volta o fundo que gasta tinta.

As regras de quebra (break-after e break-inside) são pedidos, não ordens. Se a tabela de itens tiver três folhas de altura, o navegador vai quebrar de qualquer jeito. Para tabela larga que corta coluna, o problema é outro, e está em relatório impresso que corta a última coluna.

O botão de imprimir

<button type="button" class="acoes" id="imprimir">Imprimir comprovante</button>

<script>
  document.getElementById('imprimir').addEventListener('click', function () {
    window.print();
  });
</script>

O botão abre o diálogo nativo, em que a pessoa escolhe impressora, PDF ou número de cópias. Não abra uma janela extra com uma "versão para impressão" separada: duas páginas para manter significam duas páginas que divergem. Repare também que o próprio botão tem a classe acoes, então ele some do papel.

Se a página usa blocos recolhidos, como details fechado ou abas, o conteúdo escondido não sai na folha. O navegador dispara os eventos beforeprint e afterprint; use o primeiro para abrir os blocos e o segundo para fechar de novo.

Quando o certo é PDF no servidor

CSS de impressão é ótimo para artigo, receita, comprovante simples e página de pedido. Ele falha quando o documento tem valor formal: margens, quebra de página e fonte mudam entre Chrome, Firefox e Safari, e entre impressoras. Se o papel tem que ser igual para todo mundo, gere o arquivo você mesmo.

Em PHP, bibliotecas como Dompdf e mPDF convertem HTML em PDF, com suporte de CSS mais limitado que o de um navegador moderno (layout com flex e grid costuma dar trabalho). Outra saída é renderizar com um Chrome sem interface, via Puppeteer ou Playwright, que imprimem a página com o mesmo motor do navegador e devolvem o PDF. No comprovante da loja, a regra ficou assim: a página de pedido usa CSS de impressão; a segunda via de boleto e a nota vêm em PDF pronto, gerado no servidor e guardado.

Erros comuns

  • Esconder com visibility: hidden. O elemento some, mas o espaço continua reservado, e o papel ganha um buraco do tamanho do menu. Use display: none.
  • Tema escuro sem regra de impressão. O navegador tira o fundo e o texto claro some no papel branco. Force color: #000 no bloco de impressão.
  • Largura fixa em pixels no contêiner. A folha tem menos espaço útil que o monitor, e a coluna da direita é cortada. Solte para width: auto.
  • Imprimir o endereço de todos os links. Âncoras, links de menu e URLs de rastreamento transformam a folha em lista de endereços. Restrinja o ::after aos links que importam.
  • Confiar no CSS para documento oficial. Cada navegador pagina de um jeito, e o boleto sai com a linha digitável quebrada numa máquina. Documento formal pede PDF gerado no servidor.
  • Abrir o diálogo de impressão sozinho ao carregar a página. A pessoa só queria ver o pedido e ganha um diálogo que não pediu. Imprima só no clique.

Checklist

  • Existe um bloco @media print ou um CSS com media="print".
  • Menu, rodapé, botões, banner e chat não aparecem na pré-visualização.
  • O texto sai preto em fundo branco, mesmo com tema escuro.
  • Nenhuma coluna é cortada na lateral da folha A4.
  • Links externos importantes mostram o endereço ao lado do texto.
  • Título de seção não fica sozinho no pé da folha num pedido longo.
  • O botão de imprimir chama window.print() só no clique e some do papel.
  • Documentos formais saem em PDF gerado no servidor, não pela impressão do navegador.

Abra agora a pré-visualização de impressão da página mais longa do seu site, a que as pessoas mais imprimem. Qual bloco ali existe só para a tela e continua gastando tinta?

Avalie este artigo

Referência: http://forum.wmonline.com.br/topic/63087-como-imprimir-com-php/