javascripthtmlcssmasonry

CSS masonry isn't working; all flex elements end up in one line


My CSS masonry isn't working at all. I've seen hundreds of sites telling how to do this by now and not one of them works at all. I've been trying to fix this for about a week now and I'd really appreciate help.

Info

Using HTML and CSS. Loading content for the items in the masonry via Django (in Python).

Constraints

Though this isn't really a constraint, no-JS solutions are preferred. But if there is no other way than tweaking something with Javascript, it's ok.

Description

So, here's the problem: flex-wrap isn't wrapping the flex elements to the next line at all. It all goes in a straight line and overflows the page on the x axis. If it's all in a straight line, there's no need for masonry.
Here's the CSS I'm using from here:

.container {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  height: 600px; 
}

.item {
  width: 32%;
  margin-bottom: 2%;
}

.item:nth-child(3n+1) { order: 1; }
.item:nth-child(3n+2) { order: 2; }
.item:nth-child(3n)   { order: 3; }

/* Force new columns */
.container::before,
.container::after {
  content: "";
  flex-basis: 100%;
  width: 0;
  order: 2;
}

HTML:

{% for book in books %}
<div class="item" style="width: {{ size.width }}px; height: min-content;">
                <img src="{{ book.thumbnail.url }}" style="width: {{ size.width }}px; height: {{ size.height }}px;">
        <div class="titlebox"><h3>{{ book }}</h3></div>
        <div class="authorbox">{{ book.author }}</div>
            <div class="clickbtndiv">
                {% if book.status == 1 %}
                    <a href="/main/rent/{{ book.code }}"><button class="clickbtn">Rent</button></a>
                {% else %}
                    <button class="clickbtn" style="width: auto !important;" onclick="Alert.render('')">Not available</button>
                {% endif %}
                <a href="/main/books/{{ book.code }}/" style="margin-left: 10px;"><button class="clickbtn">Know more</button></a>
            </div>
        </div>
{% endfor %}

You're probably a frontend developer if you're reading this question, and maybe you wouldn't know Django. The {{}}s get replaced with actual values which are sent from the backend.

I've got no idea what's going on and nothing I've done since 7 AM here could fix it because I'm more of a backend developer though I know HTML, CSS, and JS, and this is a kind of project only I'm working on so there are no frontend devs to help me out.

Thanks!


Solution

  • It will not works with flex. You should use grids. https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/

    flex works only for x or y axis.