При печати из Chrome я хотел бы избежать разрыва страницы между заголовком и следующим абзацем.
Я достиг этого для большинства документов с помощью:
h1 {
page-break-inside: avoid;
page-break-after: avoid;
}
... и это перемещает кучу разрывов страниц, заставляя разрыв происходить перед заголовком, когда это необходимо.
Однако это кажется неудачным, когда разрыв происходит в пределах поля заголовка.
Я могу воспроизвести так:
<html>
<head>
<style>
h1 {
border-style: solid;
margin: 30px;
page-break-inside: avoid;
page-break-after: avoid;
}
p {
background-color: grey;
}
</style>
</head>
<body>
<h1>Lorem ipsum dolor sit amet</h1>
<p>... consectetur adipiscing elit (etc)...</p>
(Repeat to fill a page)
</html>
... сокращать/удлинять текст абзаца до тех пор, пока предварительный просмотр печати не покажет нежелательный разрыв страницы:
Спецификация CSS, кажется, говорит, что этого не должно происходить:
In the normal flow, page breaks can occur at the following places:
1) In the vertical margin between block-level boxes. When an unforced page break occurs here, the used values of the relevant 'margin-top' and 'margin-bottom' properties are set to '0'. When a forced page break occurs here, the used value of the relevant 'margin-bottom' property is set to '0'; the relevant 'margin-top' used value may either be set to '0' or retained.
...
- Rule A: Breaking at (1) is allowed only if the 'page-break-after' and 'page-break-before' properties of all the elements generating boxes that meet at this margin allow it, which is when at least one of them has the value 'always', 'left', or 'right', or when all of them are 'auto'.
Это работает как надо? Или ошибка в CSS Chrome? Или недоразумение с моей стороны?
Могу ли я как-то обойти это?
Возможно, этот вопрос также может дать некоторые ответы.
Проверьте эту ссылку, надеюсь, вам помогут. здесь
Первое (простое и безопасное) решение:
Добавьте элемент section/div вокруг h1 и первого абзаца и установите на нем page-break-inside: avoid
. В примере:
<body>
<div class = "headline">
<h1>A sample title</h1>
<p>First paragraph bla bla blac....</p>
</div>
<p>Second paragraph...</p>
</body>
с CSS:
.headline {
page-break-inside: avoid;
}
Второе решение: с небольшими изменениями в html и семантике section
можно сделать что-то вроде:
<body>
<div class = "page">
<section>
<h1>
A Simple Title
</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
</p>
...
<h1>Second title</h1>
<p>Lorem....</p>
</section>
</body>
С CSS:
body {
font: sans-serif;
}
.page {
padding: 1em;
}
section {
page-break-before: always;
}
section > p + h1 {
page-break-before: always;
page-break-after: avoid;
}
section > h1* + p {
page-break-before: avoid;
}
Вы можете увидеть пример здесь: https://codesandbox.io/s/test-print-avoid-page-break-after-title-l4kbq
Итак, в этом ответе подразумевается, что обработка разрыва страницы после разрыва страницы в Chrome нарушена?
Вероятно, да. Я думаю, что происходит что-то вроде этого: Chrome пытается напечатать каждый элемент отдельно, а когда пытается напечатать H1, места достаточно. и так следующий элемент. Но это подразумевает множество других проверок: если следующий элемент НЕ МОЖЕТ быть напечатан без разрыва (большой, как страница), это еще один особый случай, который следует учитывать, и так далее...
Что, если вы обернете оба тега
h1
иp
в div и добавите в этот div элементыpage-break-..
?