Как использовать HTML для печати заголовка и колонтитула на каждой странице документа?
Заголовок: Возможность добавления пользовательских заголовков и нижних колонтитулов при печати HTML-страниц
Текст проблемы: Здравствуйте!
Я хочу узнать, возможно ли добавить пользовательские заголовки и нижние колонтитулы на каждую напечатанную страницу HTML-документа.
Конкретно, мне нужно, чтобы слово "UNCLASSIFIED" в красном цвете, шрифта Arial, размером 16pt отображалось вверху и внизу каждой напечатанной страницы, независимо от содержимого.
Для примера, если документ будет напечатан на 5 страницах, каждый лист должен содержать указанный заголовок и нижний колонтитул.
Кто-нибудь знает, возможно ли это реализовать с использованием HTML/CSS?
Спасибо!
5 ответ(ов)
Если вы хотите, чтобы элемент, который вы хотите использовать в качестве подвала, отображался на каждой странице при печати, вы можете установить для него свойства position: fixed
и bottom: 0
. Аналогично это можно сделать для элемента заголовка — просто установите для него top: 0
.
Пример:
<div class="divFooter">НЕ КЛАССИФИЦИРОВАНО</div>
CSS:
@media screen {
div.divFooter {
display: none; /* Скрыть элемент на экране */
}
}
@media print {
div.divFooter {
position: fixed; /* Зафиксировать элемент */
bottom: 0; /* Поместить элемент внизу */
}
}
Таким образом, при печати сайт будет выводить ваш элемент подвала внизу каждой страницы.
Я только что потратил половину дня на разработку решения, которое действительно сработало для меня, и решил поделиться своим подходом. Проблема, с которой я столкнулся с решениями, упомянутыми выше, заключалась в том, что все мои элементы абзацев пересекались с подвалом, который я хотел разместить внизу страницы. Чтобы обойти это, я использовал следующий CSS:
footer {
font-size: 9px;
color: #f00;
text-align: center;
}
@page {
size: A4;
margin: 11mm 17mm 17mm 17mm;
}
@media print {
footer {
position: fixed;
bottom: 0;
}
.content-block, p {
page-break-inside: avoid;
}
html, body {
width: 210mm;
height: 297mm;
}
}
Свойство page-break-inside
для p
и content-block
было для меня критически важным. Каждый раз, когда у меня есть p
, следующий за h*
, я оборачиваю их оба в <div class="content-block">
, чтобы они оставались вместе и не ломались.
Надеюсь, что кто-то найдет это полезным, так как мне потребовалось около 3 часов, чтобы разобраться с этим (я также новичок в CSS/HTML, так что вот вам и это...)
ИЗМЕНЕНИЕ
По просьбе в комментариях, я добавляю пример HTML-документа. Вам нужно скопировать это в HTML-файл, открыть его и затем выбрать печать. Предварительный просмотр печати должен показать, как это работает. У меня это сработало в Firefox и IE, но в Chrome шрифт оказался таким маленьким, что всё поместилось на одной странице, поэтому там это не сработало.
<!DOCTYPE html>
<html>
<head></head>
<body>
<h1>
Пример документа
</h1>
<div>
<p>
Это пример документа, который демонстрирует, как разместить подвал внизу каждой страницы, который также не будет покрыт текстом абзаца.
</p>
</div>
<div>
<h3>
Пример раздела I
</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vestibulum metus sit amet urna lobortis sollicitudin. Nulla mattis purus porta lorem tempor, a cursus tellus facilisis. Aliquam pretium nibh vitae elit placerat vestibulum. Duis felis ipsum, consectetur id pellentesque in, porta sit amet sapien. Ut tristique enim sem, laoreet bibendum nisl fermentum vitae. Ut aliquet sem ac lorem malesuada sodales. Fusce iaculis ipsum ex, in mollis dolor dapibus sit amet. In convallis felis in orci fermentum gravida a vel orci. Sed tincidunt porta nibh sit amet varius. Donec et odio eget odio tempus auctor ac eget ex.
Pellentesque vitae augue sed purus dictum ultricies at eu neque. Nullam ut mauris a purus tristique euismod. Sed elementum, leo id placerat congue, leo tellus pharetra orci, eget ultricies odio quam sit amet ipsum. Praesent feugiat, lorem at commodo egestas, felis ligula pharetra sapien, in placerat mauris nisi aliquet tortor. Quisque nibh lectus, laoreet vel mollis a, tincidunt vel ipsum. Sed blandit vehicula sollicitudin. Donec et sapien justo. Ut fermentum ipsum imperdiet diam condimentum, eget varius sapien dictum. Sed sed elit egestas libero maximus finibus eu eget massa.
Duis finibus vestibulum finibus. Nunc lobortis lacus ut libero mattis tempor. Nulla a nunc at nisl elementum congue. Nunc eu consectetur mauris. Etiam non placerat massa. Etiam eu urna in metus tempus molestie sed eget diam. Nunc sem velit, elementum sit amet fringilla in, dictum sit amet sem. Quisque convallis faucibus purus dignissim dictum. Sed semper, mi vel accumsan sollicitudin, massa massa pellentesque justo, eget auctor sapien enim ac elit.
Nullam turpis augue, lacinia ut libero ac, rhoncus bibendum ligula. Mauris ullamcorper maximus turpis, a consequat turpis bibendum sit amet. Nam vitae dui nec velit hendrerит faucibus. Vivamus nunc diam, porta tristique augue nec, dignissim venenatis felis. Proin mattis id risus in feugiat. Etiam cursus faucibus nisi. In in nisi ullamcorper, convallis lectus et, ornare nulla. Cras tristique nulla eros, non maximus odio imperdiet eu. Nullam egestas dignissim est, et fringilla odio pretium eleifend. Nullam tincidunt sapien fermentum, rhoncus risus ac, ullamcorper libero. Vestibulum bibendum molestie dui nec tincidunt. Mauris tempus, orci ut congue vulputate, erat orci aliquam orci, sed eleifend orci dui sed tellus. Pellentesque pellentesque massa vulputate urna pretium, consectetur pulvinar orci pulvinar.
Donec aliquet imperdiet ex, et tincidunt risus convallis eget. Etiam eu fermentum lectus, molestie eleifend nisi. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam dignissim, erat vitae congue molestie, ante urna sagittis est, et sagittis lacus risus vitae est. Sed elementum ipsum et pellentesque dignissim. Sed vehicula feugiat pretium. Donec ex lacus, dictum faucibus lectus sit amet, tempus hendrerit ante. Ut sollicitudin sodales metus, at placerat risus viverra ut.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vestibulum metus sit amet urna lobortis sollicitudin. Nulla mattis purus porta lorem tempor, a cursus tellus facilisis. Aliquam pretium nibh vitae elit placerat vestibulum. Duis felis ipsum, consectetur id pellentesque in, porta sit amet sapien. Ut tristique enim sem, laoreet bibendum nisl fermentum vitae. Ut aliquet sem ac lorem malesuada sodales. Fusce iaculis ipsum ex, in mollis dolor dapibus sit amet. In convallis felis in orci fermentum gravida a vel orci. Sed tincidunt porta nibh sit amet varius. Donec et odio eget odio tempus auctor ac eget ex.
Duis finibus vestibulum finibus. Nunc lobortis lacus ut libero mattis tempor. Nulla a nunc at nisl elementum congue. Nunc eu consectetur mauris. Etiam non placerat massa. Etiam eu urna in metus tempus molestie sed eget diam. Nunc sem velit, elementum sit amet fringilla in, dictum sit amet sem. Quisque convallis faucibus purus dignissim dictum. Sed semper, mi vel accumsan sollicitudin, massa massa pellentesque justo, eget auctor sapien enim ac elit.
Nullam turpis augue, lacinia ut libero ac, rhoncus bibendum ligula. Mauris ullamcorper maximus turpis, a consequat turpis bibendum sit amet. Nam vitae dui nec velit hendrerit faucibus. Vivamus nunc diam, porta tristique augue nec, dignissim venenatis felis. Proin mattis id risus in feugiat. Etiam cursus faucibus nisi. In in nisi ullamcorper, convallis lectus et, ornare nulla. Cras tristique nulla eros, non maximus odio imperdiet eu. Nullam egestas dignissim est, et fringilla odio pretium eleifend. Nullam tincidunt sapien fermentum, rhoncus risus ac, ullamcorper libero.
</p>
</div>
<div class="content-block">
<h3>Пример раздела II</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vestibulum metus sit amet urna lobortis sollicitudin. Nulla mattis purus porta lorem tempor, a cursus tellus facilisis. Aliquam pretium nibh vitae elit placerat vestibulum. Duis felis ipsum, consectetur id pellentesque in, porta sit amet sapien. Ut tristique enim sem, laoreet bibendum nisl fermentum vitae. Ut aliquet sem ac lorem malesuada sodales. Fusce iaculis ipsum ex, in mollis dolor dapibus sit amet. In convallis felis in orci fermentum gravida a vel orci. Sed tincidunt porta nibh sit amet varius. Donec et odio eget odio tempus auctor ac eget ex.
Pellentesque vitae augue sed purus dictum ultricies at eu neque. Nullam ut mauris a purus tristique euismod. Sed elementum, leo id placerat congue, leo tellus pharetra orci, eget ultricies odio quam sit amet ipsum. Praesent feugiat, lorem at commodo egestas, felis ligula pharetra sapien, in placerat mauris nisi aliquet tortor. Quisque nibh lectus, laoreet vel mollis a, tincidunt vel ipsum. Sed blandit vehicula sollicitudin. Donec et sapien justo. Ut fermentum ipsum imperdiet diam condimentum, eget varius sapien dictum. Sed sed elit egestas libero maximus finibus eu eget massa.
</p>
</div>
<footer>
Это текст, который находится внизу каждой страницы.
</footer>
</body>
</html>
В ответ на ваш вопрос, действительно, существует волшебное решение, которое заключается в том, чтобы разместить все в одной таблице.
- thead: для повторяющегося заголовка.
- tfoot: для повторяющегося подвала.
- tbody: для основного содержимого.
Можно использовать одну строку (tr
), одну ячейку (td
) и поместить всё в div
.
КОД::
<table class="report-container">
<thead class="report-header">
<tr>
<th class="report-header-cell">
<div class="header-info">
...
</div>
</th>
</tr>
</thead>
<tfoot class="report-footer">
<tr>
<td class="report-footer-cell">
<div class="footer-info">
...
</div>
</td>
</tr>
</tfoot>
<tbody class="report-content">
<tr>
<td class="report-content-cell">
<div class="main">
...
</div>
</td>
</tr>
</tbody>
</table>
table.report-container {
page-break-after: always;
}
thead.report-header {
display: table-header-group;
}
tfoot.report-footer {
display: table-footer-group;
}
Дополнительно: Чтобы избежать наложения на нескольких страницах, используйте такую структуру:
<div class="main">
<div class="article">
...
</div>
<div class="article">
...
</div>
<div class="article">
...
</div>
...
...
...
</div>
Это может привести к переполнению, которое повлечет за собой наложение заголовка при разрывах страниц.
Поэтому используйте: page-break-inside: avoid !important;
для этого класса article
.
table.report-container div.article {
page-break-inside: avoid;
}
Надеюсь, это поможет вам в оформлении отчётов с правильной структурой и предотвращении проблем с наложением!
Комментарий Мухаммада Мусави является лучшим ответом, поэтому я выделю его как отдельный ответ:
Элементы thead
и tfoot
автоматически повторяются вверху и внизу каждой страницы. Однако tfoot
не закреплён внизу последней страницы.
Использование position: fixed
при печати будет повторяться на каждой странице, и подвал будет прикреплён к низу всех страниц, включая последнюю — но это не создаст пространство для его содержимого.
Скомбинируем оба подхода:
HTML:
<header>(повторяющийся заголовок)</header>
<table class=paging>
<thead>
<tr><td> </td></tr>
</thead>
<tbody>
<tr><td>
(контент здесь)
</td></tr>
</tbody>
<tfoot>
<tr><td> </td></tr>
</tfoot>
</table>
<footer>(повторяющийся подвал)</footer>
CSS:
@page {
size: letter;
margin: .5in;
}
@media print {
table.paging thead td, table.paging tfoot td {
height: .5in;
}
}
header, footer {
width: 100%;
height: .5in;
}
header {
position: absolute;
top: 0;
}
@media print {
header, footer {
position: fixed;
}
footer {
bottom: 0;
}
}
Здесь много мелочей, которые можно было бы добавить, но я намеренно оставил только самый минимум, чтобы получить чистый рендеринг заголовка и подвала, которые будут отображаться один раз на экране и вверху и внизу каждой печатной страницы.
Кажется, вы столкнулись с распространенной проблемой при использовании таблиц и пагинации в сочетании с футерами. Как вы правильно заметили, tfoot
предназначен для использования в элементах таблиц и не идеально подходит для отображения на печатных страницах. Многие браузеры обрабатывают этот элемент по-разному, и, в данной ситуации, результат может отличаться в зависимости от используемого браузера.
В вашем случае, когда вы используете CSS для настройки футера, возникла проблема с тем, что контент таблицы перетекает через футер при выводе на экран, и в печатном виде футер не фиксируется внизу страницы, что вызывает еще большее разочарование.
Вот несколько подходов, которые можно рассмотреть:
Использование фиксированного позиционирования для футера: У вас уже есть часть решения в CSS:
div#footer_wrapper { position: fixed; bottom: 0; }
Это работает для печати, но будьте осторожны с
margin
, так как это может создать неравномерные отступы между футером и содержимым.Модификация структуры HTML: Вместо использования
tfoot
, попробуйте просто добавить содержимое футера вне таблицы. Это позволит вам контролировать его позиционирование легче, и предотвратит проблемы с переполнением.Избегайте использования
tfoot
для печати: Если главным приоритетом является корректный вывод футера только для печати, рассмотрите возможность удаленияtfoot
особенно для печатной версии с помощью медиазапросов.
@media print {
tfoot { display: none; }
}
- Тесты в разных браузерах: Проверьте результат в разных браузерах. Некоторые из старых версий могут не поддерживать определенные стили должным образом, так что актуальные обновления браузеров могут помочь решить некоторые из этих проблем.
К сожалению, с аспектами работы с таблицами и печатью на разных браузерах могут возникать неудобства, и исправление может занять время. Но с помощью указанных выше приемов вы можете значительно улучшить ваш вывод футера.
Как задать cellpadding и cellspacing с помощью CSS?
Как расположить div внизу своего контейнера?
Перенос строки в HTML с использованием '\n'
Как отключить перенос строк в HTML?
Установить фиксированную ширину столбца таблицы независимо от количества текста в ячейках?