I have a following requirement to design the print layout to generate a pdf and I've tried various options including CSS flex and grid but not much success.
The requirement is:
I'm able to achieve the first requirement. However, I couldn't find a way to break the 3rd column in CSS based on the div width (or page width).
I'm trying the below code:
.newspaper {
max-height: 500px;
column-count: 3;
}
.article {
break-inside: avoid;
page-break-after: always;
}
.chart {
background: #ccc;
height: 200px;
}
<div class="newspaper">
<div class="article">
<h1>Article 1</h1>
<div class="chart">Chart 1</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
<p>xxxxxxxxxx</p>
</div>
<div class="article">
<h1>Article 2</h1>
<div class="chart">Chart 2</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
<p>xxxxxxxxxx</p>
</div>
<div class="article">
<h1>Article 3</h1>
<div class="chart">Chart 3</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
</div>
<div class="article">
<h1>Article 4</h1>
<div class="chart">Chart 4</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
</div>
<div class="article">
<h1>Article 5</h1>
<div class="chart">Chart 5</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
</div>
<div class="article">
<h1>Article 6</h1>
<div class="chart">Chart 6</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
</div>
<div class="article">
<h1>Article 7</h1>
<div class="chart">Chart 7</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
</div>
</div>
Expected Output:
I'm happy with any CSS approach as long as it works on Chrome.
Thanks.
The basic idea of multicol, is that you can take a chunk of content and flow it into multiple columns, as in a newspaper. You do this by using one of two properties. The column-count property specifies the number of columns that you would like the content to break into.
The break-inside property specifies whether or not a page break, column break, or region break should occur inside the specified element. The break-inside property extends then CSS2 page-break-inside property. With break-inside , you can tell the browser to avoid breaks inside images, code snippets, tables, and listst.
Beware: this is a quick and dirty hack that isn't recommended for use in web development, as it makes a copy of the entire document for every page it creates. The scope of the question however seems to be a private tool that creates PDFs out of HTML. For that use case I deem this trick suitable. It meets al your criteria, even across pages and is responsive.
As mentioned by others, CSS does currently not provide for an automated way to break columns up in rows and flow the text across them. display: grid
does something related but keeps boxes intact meaning that elements cannot flow in one uninterrupted stream across the page. flow-into
and flow-from
seem promising but are not implemented in your preferred environment (Chrome) yet.
This setup breaks your entire content up in columns using the columns
property, but only displays three of them using a container with overflow: hidden
. When the page is loaded a piece of javascript then measures the container size, compares that to the scroll overflow to determine how many pages of content are hidden and creates copies accordingly, each having an offset to only display the next three items. So although every pages contains the entire document, the result is the illusion of articles freely flowing along pages.
The dimensions are configurable using the variables in the .pages
ruleset. Further stylistic customization might need some tinkering given the hacky nature of this approach.
window.addEventListener("load", reflowPages);
window.addEventListener("resize", reflowPages);
function reflowPages() {
const pages = document.querySelector(".pages");
const template = document.querySelector(".page");
if (pages == null || template == null) return;
const viewportWidth = template.clientWidth;
const totalWidth = template.scrollWidth;
const pageCount = Math.ceil(totalWidth / viewportWidth);
cleanPages();
for (let n = 1; n < pageCount; n++) {
const page = createPage(template, n);
pages.appendChild(page);
}
}
function cleanPages() {
const [, ...rest] = document.querySelectorAll(".page");
rest.forEach((v) => v.remove());
}
function createPage(template, n) {
const element = template.cloneNode(true);
element.style.setProperty("--page", n);
return element;
}
.pages {
--page-width: 100%;
--page-height: 500px;
--columns: 3;
}
.page {
width: var(--page-width);
height: var(--page-height);
overflow: hidden;
border-bottom: 1px solid black;
padding: 1em 0;
}
.scroller {
position: relative;
max-height: 100%;
column-count: var(--columns);
column-gap: 0;
left: calc(var(--page, 0) * -100%);
}
.article {
padding: 0 0.5em;
/* Instead of column-gap */
}
.chart {
background: #ccc;
height: 200px;
break-inside: avoid;
}
<div class="pages">
<div class="page">
<div class="scroller">
<div class="article">
<h1>Article 1</h1>
<div class="chart">Chart 1</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex
ea commodo consequat.
</p>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex
ea commodo consequat.
</p>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex
ea commodo consequat.
</p>
<p>xxxxxxxxxx</p>
</div>
<div class="article">
<h1>Article 2</h1>
<div class="chart">Chart 2</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex
ea commodo consequat.
</p>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex
ea commodo consequat.
</p>
<p>xxxxxxxxxx</p>
</div>
<div class="article">
<h1>Article 3</h1>
<div class="chart">Chart 3</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex
ea commodo consequat.
</p>
</div>
<div class="article">
<h1>Article 4</h1>
<div class="chart">Chart 4</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex
ea commodo consequat.
</p>
</div>
<div class="article">
<h1>Article 5</h1>
<div class="chart">Chart 5</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex
ea commodo consequat.
</p>
</div>
<div class="article">
<h1>Article 6</h1>
<div class="chart">Chart 6</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex
ea commodo consequat.
</p>
</div>
<div class="article">
<h1>Article 7</h1>
<div class="chart">Chart 7</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex
ea commodo consequat.
</p>
</div>
</div>
</div>
</div>
column-gap
messes with the calculations and you should therefore use padding
on the child elements instead (as in the example).page
will always be stretched to the max height by the invisible overflowing elements.For PDFs (i.e. print) you almost have it. You just need to change the height
property to 100vh
(as opposed to max-height: 500px
) and then unset it in an @media print
media query.
.newspaper {
height: 100vh;
}
@media print {
.newspaper {
height: unset;
}
}
Note that that screens still have the horizontal scroll keeping the multi-column layout. So you might want to consider abandoning the multi-column layout for screens (that is move column-count
inside the print media query as well), or use one of the other answers to keep this behavior for screens.
.newspaper {
height: 100vh;
column-count: 3;
}
.article {
break-inside: avoid;
page-break-after: always;
}
.chart {
background: #ccc;
height: 200px;
}
@media print {
.newspaper {
height: unset;
}
}
<div class="newspaper">
<div class="article">
<h1>Article 1</h1>
<div class="chart">Chart 1</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
<p>xxxxxxxxxx</p>
</div>
<div class="article">
<h1>Article 2</h1>
<div class="chart">Chart 2</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
<p>xxxxxxxxxx</p>
</div>
<div class="article">
<h1>Article 3</h1>
<div class="chart">Chart 3</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
</div>
<div class="article">
<h1>Article 4</h1>
<div class="chart">Chart 4</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
</div>
<div class="article">
<h1>Article 5</h1>
<div class="chart">Chart 5</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
</div>
<div class="article">
<h1>Article 6</h1>
<div class="chart">Chart 6</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
</div>
<div class="article">
<h1>Article 7</h1>
<div class="chart">Chart 7</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
</div>
</div>
Here is a printed preview
I used Grid
to achieve this.
If you want to break inside a column, I think that you need to use JavaScript. This is the maximum result you can get from CSS.
.newspaper {
display: grid;
grid-template-columns: auto auto auto;
grid-gap: 10px;
}
.article {
break-inside: avoid;
page-break-after: always;
}
.chart {
background: #ccc;
height: 200px;
}
<div class="newspaper">
<div class="article">
<h1>Article 1</h1>
<div class="chart">Chart 1</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
<p>xxxxxxxxxx</p>
</div>
<div class="article">
<h1>Article 2</h1>
<div class="chart">Chart 2</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
<p>xxxxxxxxxx</p>
</div>
<div class="article">
<h1>Article 3</h1>
<div class="chart">Chart 3</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
</div>
<div class="article">
<h1>Article 4</h1>
<div class="chart">Chart 4</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
</div>
<div class="article">
<h1>Article 5</h1>
<div class="chart">Chart 5</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
</div>
<div class="article">
<h1>Article 6</h1>
<div class="chart">Chart 6</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
</div>
<div class="article">
<h1>Article 7</h1>
<div class="chart">Chart 7</div>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</p>
</div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With