Search code examples
htmlcssfirefoxmultiple-columnscss-multicolumn-layout

How do I tell to Firefox that it's fine for a div to span multiple columns?


On a page, I use a layout where the text is positioned in two columns when the page is large enough. This works well in Chromium, but not in Firefox.

The content is structured like this:

<main style="columns: 2;">
    <h1>Title goes here</h1>
    <div>Date, author, and other stuff.</div>
    <div>
        <p>...</p>
        <p>...</p>
        <p>...</p>
         ⋮
        <p>...</p>
    </div>
</main>

As the last <div> contains most of the content, Chromium puts the <h1>, the first <div>, and the beginning of the last <div> on the first column, and the remaining part of the last <div> on the second column (Fig. 1). Firefox 90.0.2, however, moves the entire last <div> to a second column (Fig. 2).

I noticed that if I remove the last <div>, putting all the paragraphs as direct children of <main>, Firefox starts showing the content similarly to Chromium. However, I would prefer keeping the DOM as it is now, and rather understand why Firefox is behaving the way it does.

  • What's the reason for this behavior in Firefox?

  • How should I change the CSS in order to have in Firefox a similar behavior to what I get in Chromium, while keeping the actual structure of the nodes?

enter image description here

Fig­ure 1 Chromium showing the columns as I expect them to be shown.

enter image description here

Fig­ure 2 Firefox moving the whole article body to the second column.


Solution

  • The problem is that p elements are nested inside of the div. You can use display: contents for the div.content to force browser to ignore its hierarchy.

    contents
    The element itself does not generate any boxes, but its children and pseudo-elements still generate boxes and text runs as normal.

    Source: 2.5. Box Generation: the none and contents keywords | w3.org

    Example based on your website:

    main {
       columns: 2;
    }
    
    .content {
       display: contents;
    }
    <main>
        <h1>Title goes here</h1>
        <div>Date, author, and other stuff.</div>
        <div class="content">
            <p>text</p>
            <p>text</p>
            <p>text</p>
            <p>text</p>
            <p>text</p>
        </div>
    </main>