CSS flex align columns as in newspaper
A bit change in your code,
Add flex-direction: column;
to .items
, and flex: 0 1;
to .item
.items { display: flex; flex-flow: wrap; width: 400px; height: 200px; background: yellow; flex-direction: column;}
.item { flex: 0 1;}
<div class="items"> <div class="item"> <span>item 1</span> </div> <div class="item"> <span>item 2</span> </div> <div class="item"> <span>item 3</span> </div> <div class="item"> <span>item 4</span> </div> <div class="item"> <span>item 5</span> </div> <div class="item"> <span>item 6</span> </div> <div class="item"> <span>item 7</span> </div> <div class="item"> <span>item 8</span> </div> <div class="item"> <span>item 9</span> </div> <div class="item"> <span>item 10</span> </div> <div class="item"> <span>item 11</span> </div> <div class="item"> <span>item 12</span> </div> <div class="item"> <span>item 13</span> </div> <div class="item"> <span>item 14</span> </div>
</div>
Newspaper style multiple-column text in html
column-count
is CSS3, so be warned it will not work in some older browsers.
To answer your question, you may need to be more specific with your css:
div{
-moz-column-count: 2;
-webkit-column-count: 2;
column-count: 2;
}
How to break the newspaper style 3 column layout in CSS?
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.
Why a trick?
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.
The trick
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>
Newspaper-column in CSS
I think your needs are best served using an existing CSS framework, rather than coding it yourself from scratch, since it is really tricky business plus apallingly hard to get to work across all browsers (since some of them are not standards compliant)
Anyhow, for newspaper columns, I think there's one out there that fits the bill, 960 Grid System
. It comes with 12 & 16 column "grids", with the gutters and paddings all worked out, and so long as the number of columns you intend to use is a factor of 12 or 16, it can handle it.
Newspaper style grid on pure css with different dynamic height of components
You were on the right track with the columns
property. To solve the problem of an item in the column splitting across columns, you can wrap each column item in another element that has display: inline-block
.
Make sure to also either set the inline-block
element to 100% width or wrap it in yet another element with a block-type display (block
, flex
, grid
) in order to prevent two particularly small children from sitting side-by-side within a column. (Unless that's something you'd want.)
#container { column-count: 2; column-gap: 20px; width: 160px;}.content-outer { width: 100%; display: inline-block;}.content { width: 100%; /* width as related to the column, not the whole container */ border: 1px solid black; padding: 5px;}
<div id="container"> <div class="content-outer"> <div class="content">content</div> </div> <div class="content-outer"> <div class="content">content <br/> big</div> </div> <div class="content-outer"> <div class="content">content</div> </div> <div class="content-outer"> <div class="content">content</div> </div> <div class="content-outer"> <div class="content">content</div> </div> <div class="content-outer"> <div class="content">content</div> </div> <div class="content-outer"> <div class="content">content</div> </div> <div class="content-outer"> <div class="content">content</div> </div></div>
Related Topics
Center Wrapped Items in a Space-Between Flexbox
How to Change Font-Size of a Tag Using Inline CSS
Why Does Firefox Treat Helvetica Differently from Chrome
How to Make Tinymce's Modal Dialogs Responsive
Angularjs: with Ng-Animate & Ng-View, How to Make a 3D Cube Rotation Effect
Efficient and Inefficient CSS Selectors (According to Google, Pagespeed ...)
Child Take Width % from Parents Parent
How to Use CSS3: :Selection Without Changing The Default Color and Background Color
CSS Sprite Techniques, CSS Background or Img's Clip
CSS - Smooth Button Gradient Color Transition on Hover
How to Highlight a Selected Row in *Ngfor
Set Size to Responsive Iframe in Bootstrap
Svg Letter-Spacing Also Applied to Mozilla Firefox
Helvetica Neue' and Helvetica Font