soy Kseso y esto EsCSS

Estilos Css para imprimir: La regla @page en los medios paginados

Un repaso a los documentos, reglas y propiedades Css para una correcta impresión de los documentos web.

Estilos Css para imprimir: La regla @page en los medios paginados

·Por Kseso ✎ 33

Estar en una página y decidir imprimir un artículo y ver que entre sidebar, baners publicitarios, menús y otra basura te comen 4 páginas y que el contenido queda cortado dice mucho de esa página. Pero qué malo todo lo que dice.
Y todo por no tomarse un momento para hacer que la impresión de su web se realice correctamente.

Con Css se puede controlar también el qué y cómo se imprimen las webs. Para ello tiene todo un capítulo. Son los estilos para los medios paginados (Nota 1 ↓).

Actualización: El documento actual, en desarrollo, es CSS Paged Media Module Level 3. Lamentablemente su desarrollo e implementación de sus novedades en los navegadores no está siendo tan rápida como sería de desear.

Estilos Css para imprimir: La regla @page en los medios paginados
Crédito imagen: [1]

Css para imprimir

La llamada a los estilos de impresión se puede hacer de la misma manera que el de los de visión en pantalla. Si es mediante el <link... > sólo se necesita indicar el tipo de media:

<link href="impresion.css" type="text/css" media="print" />

También se pueden incluir en el head usando el elemento <style> y la manera de indicar que son estilos para la impresión es:

<style type="text/css"> @media print { /* Todas las reglas Css */ } <style>

El modelo de caja (boxmodel) de Page

Los media print generan una caja general donde alojar todos los contenidos. Esta caja se conoce como page.

El boxmodel por defecto en los medios impresos es el mismo que en el media="screen". El tamaño final de la caja generada page es la suma de sus (margin + border + padding) laterales + su width o height.

Además de este área general el nuevo docuento define 16 áreas o cajas de márgenes donde poder colocar contenido generado con CSS. Si estas cajas de márgenes quedan fuera del área de impresión generan una nueva página.

DPage-Margin Boxes y sus valore por defecto
Page-margin box text-align vertical-align
top-left-corner right middle
top-left left middle
top-center center middle
top-right right middle
top-right-corner left middle
left-top center top
left-middle center middle
left-bottom center bottom
right-top center top
right-middle center middle
right-bottom center bottom
bottom-left-corner right middle
bottom-left left middle
bottom-center center middle
bottom-right right middle
bottom-right-corner left middle

La regla @page

Se debe definir al inicio del CSS y es la que definirá los estilos de esta caja de contención. Para ellos se utiliza el selector @page.

En ella se pueden definir las propiedades específicas para el medio impreso. Entre otras:

  • Tamaños y orientación
  • los márgenes
  • las líneas viudas y huérfanas
  • los saltos de página

@page { /* declaraciones Css */ }

Esta regla admite también añadirle clases y según el último documento admite otras at-rules dentro de ella:

@page {size: portrait;} @page rotada {size: landscape;} table {page: rotada; page-break-before: right;} @page { /*declaraciones*/ @top-left { content: "Título"; } @top-right { content: "Pág. " counter(page); } }

Ten presente el área no imprimible: Es el área de una hoja en la que un dispositivo físico, como una impresora, no es capaz de imprimir, por lo general debido al mecanismo de la impresora. Este valor depende de la impresora y es generalmente una pequeña región a lo largo de cada borde de la hoja de papel.

Propiedades propias de @page

ilustración ornamental
Size:
Define el tamaño de la caja generada page. Se le pueden declarar valores absolutos: numéricos con su unidad correspondiente (20cm | 190mm etc) o con page-size (nombres estándares)
También podemos hacerlo con valores relativos (escalables, es decir, que se ajuste al tamaño de hoja disponibles): con el valor auto (que es el valor por defecto) o indicar su orientación: portrait | landscape
size: portrait;
Especifica que el contenido de la página se imprime en orientación vertical. Los lados más cortos de la caja de página son horizontales. Si page-size no se especifica, el tamaño de la hoja de la página es elegido por la impresora.
size: landscape;
Especifica que el contenido de la página se va a imprimir en orientación horizontal. Lo mismo para page-size omitido.
page-size
son nombres claves de tamaños de papel estándar como A3, A0, B5, legal, letter... en combinación con la orientación:

@page { size: A4 landscape; }

El tamaño de "page" será el de un A4 (210mmx297mm) puesto en horizontal. Así que si la impresora no puede llegar al borde del papel para imprimir debería salirte el mensaje de si escalar la impresión o no.
Márgenes de @page

@page { size: auto;/* es el valor por defecto */ margin: 10%; }

Recuerda que el % tiene como referente del cálculo a su ancestro, en este caso el folio de papel. Así que si la hoja de la impresora es un A4, por ejemplo, los márgenes serán de 21mm en los lados cortos y 29´7mm en los largos (medidos desde los bordes del papel) y "auto" significa lo mismo que en "media='screen'": todo el espacio restante.

Las pseudoclasses: :left :right :first :blank

Para controlar aspectos de algunas páginas claves como la primera o si son páginas a izquieda o a derecha (al encuadernar o en impresión a doble cara) Css para los medios paginados define estas tres pseudoclases para @page.
:first para la primera página.
:right para las páginas que serán encuadernadas a la derecha.
:left para las páginas que su posición será a la izquierda.
:blank selecciona las páginas sin contenido (en blanco) que se generan por los saltos de página.

@page :left { margin-left: 3cm; margin-right: 4cm; } @page :right { margin-left: 4cm; margin-right: 3cm; } @page :first { margin-top: 4cm; }

Saltos de página

ilustración ornamental

Para evitar que ciertos elementos se corten y repartan en 2 páginas se puede definir los saltos de página antes: page-break-before, después: page-break-after o dentro page-break-inside del elemento. Estos saltos de página sólo se pueden aplicar a elementos de bloque.
page-break-before y page-break-after no se heredan y permiten los valores:
auto: Ni fuerza ni prohibe un salto de página antes (después) de la caja generada.
always: Siempre fuerza un salto de página antes (después) de la caja generada.
avoid: Evita un salto de página antes (después) de la caja generada.
left: Fuerza uno o dos saltos de página antes (después) de la caja generada para que la siguiente página sea compuesta como una página izquierda.
right: Fuerza uno o dos saltos de página antes (después) de la caja generada para que la siguiente página sea compuesta como una página derecha.

page-break-inside: Sí se hereda. Define si se permiten o no saltos de línea dentro de la caja. Los valores permitidos son: auto, avoid, inherit

Las propiedades 'orphans' y 'widows'

La propiedad orphans (huérfanas) especifica el número mínimo de líneas de un párrafo que deben dejarse al final de una página. La propiedad widows (viudas) especifica el número mínimo de líneas de un párrafo que deben dejarse al comienzo de la página.

Supón, por ejemplo, que la hoja de estilo contiene orphans : 4 y widows : 2, y hay 20 líneas disponibles al final de la página actual:

  • Si un párrafo al final de la página actual contiene 20 líneas o menos, deber colocarse en la página actual.
  • Si el párrafo contiene 21 o 22 líneas, la segunda parte del párrafo no debe violar la restricción 'widows', y entonces la segunda parte debe contener exactamente dos líneas.
  • Si el párrafo contiene 23 líneas o más, la primer parte debe contener 20 líneas y la segunda parte las líneas restantes.

Ahora supón que orphans es '10', widows es '20', y hay '8' líneas disponibles al final de la página actual:

  • Si un párrafo al final de la página actual contiene 8 líneas o menos, debe colocarse en la página actual.
  • Si el párrafo contiene 9 líneas o más, no puede ser cortado (esto violaría la restricción impuesta a las líneas huérfanas), así que debe moverse como un bloque a la página siguiente.

Contadores y contenido generado con CSS

En los medios impresos también es posible generar contenido vía CSS además de con los pseudoelementos "tradicionales" con los Page-Margin Boxes mencionados antes. Y en conjunción con las pseudoclases :left :right :first :blank especificar en qué tipo de páginas generarlo.

@page:blank { @top-center { content: 'Esta es una página en blanco'; /*otras declaraciones*/ } }

De la misma forma se puedes usar estos page-margin boxes para mostrar cualquier contador CSS que se necesite utilizar. Como numerar las páginas a izquierdas a la izquierda y las a derechas a la derecha:

@page:left { @bottom-left { content: counter(pagina); } } @page:right { @bottom-right { content: counter(pagina); } }

Notas a pie de página

También es posible que cierto contenido sea movido al pie de la página y que se muestre como las típicas notas a pie de página. Esta particularidad está contemplada en el apartado footnotes del documento CSS Generated Content for Paged Media.

<p>Algo de texto... XXX <span class="nota_al_pie">yyy</span>... </p> @page { @footnote { float: bottom; } } span.nota_al_pie { float: footnote; }

Y por supuesto utilizar un contador específico para cada una de las notas a pie de página. Bien global o por página.

Ten presente

imagen ornamental
  • En los saltos de línea:
    • Los saltos de página no pueden producirse dentro de las cajas que están posicionadas absolutamente
    • Evita los saltos dentro bloques que tengan un borde, dentro de las tablas (table) y dentro de los elementos flotados.
  • Tablas e impresión:
    La gestión de las tablas en los medios impresos siempre ha sido fuente de problemas. En el reciente WD del consorcio "CSS Table Module Level 3" abordan la cuestión.
    Especialente en el punto 5: fragmentation dedicado a la eso, la ruptura de las tablas entre páginas y la repetición de encabezados en cada salto.
  • Los elementos con position: fixed; se repetirán en todas y cada una de las páginas impresas.
  • Es conveniente que en la impresión ocultes display: none; todos los elementos superfluos. Cosas como sidebars, banners publicitarios, menús de navegación...
  • Quien tiene la preferencia a la hora de imprimir o no los fondos (ya sean imágenes o colores) es el usuario en la opción que los navegadores tienen para este propósito.
    No obstante en el documento "CSS Color Module Level 4" se define la propiedad color-adjust y su valor exact con el fin de preservar colores e imágenes (incluso los vía 'background') tanto en media='print' como en dispositivos de baja capacidad.
    Su equivalente no estándar para los webkit es -webkit-print-color-adjust: exact; [ver advertencia de Furoya en comentarios]
  • El destino de los enlaces quedarán inaccesibles. Si deseas que en la impresión se vean esos destinos puedes utilizar el el pseudoelemeto :after (o :before):

    a:after { content: "(link: " atr(href) ")"; }

  • No utilices medidas en píxeles. Recuerda que es algo propio de pantallas. Los textos en puntos (pt), al menos el valor del elemento raíz o en @page. Después ya podrás utilizar las unidades relativas (em, %, rem). Para los tamaños (anchos/altos) lo suyo es que los definas en cm/mm. Recuerda que estás en un medio físico.
  • Chrome tiene la mala costumbre de mostrar el box-shadow como color sólido. No respeta el canal alfa ni la "difuminación" y lo genera en toda la caja, no a partir del borde. Así que si lo declaras en un elemento sin background obtendrás un bonito bloque del color sólido.

Notas finales

Nota 1↑: En puridad los medios paginados (por ejemplo, papel, transparencias, páginas de álbumes de fotografías, simulaciones de salida impresos) son aquellos en los que se divide el contenido de todo el documento en una o más superficies (por ejemplo hojas de papel) a diferencia de los medios continuos.

Artículo publicado originalmente el 11 de mayo de 2012. Corregido y ampliado sucesivamente desde entonces. Puedes ampliar esta información con los artículos:

avatar del Editor del blog

the obCSServer ᛯ Ramajero Argonauta, Enredique Amanuense de CSS.
#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Kseso