Martin
Martin

Reputation: 1538

CSS flexbox max column number?

I'd like my css flexboxes to have a maximum of 3 columns when the user extends their browser window. With my current code, it flexes correctly inwards, with no minimum number of columns, but when extending outwards it will always automatically extend all the flexboxes out into a single line. http://jsfiddle.net/oq6prk1p/581/

In this case, I'm trying to only use the css file to achieve this, and am not editing the html file at all. So far this is the closest I've gotten:

html file:

<main class="twit-container">

  <article class="twit">
    <div class="twit-icon">
      <i class="fa fa-bullhorn"></i>
    </div>
    <div class="twit-content">
      <p class="twit-text">
        Sitting in web dev... This class is so awesome!
      </p>
      <p class="twit-attribution">
        <a href="#">CSMajor2017</a>
      </p>
    </div>
  </article>

  <article class="twit">
    <div class="twit-icon">
      <i class="fa fa-bullhorn"></i>
    </div>
    <div class="twit-content">
      <p class="twit-text">
        text
      </p>
      <p class="twit-attribution">
        <a href="#">BeaverBeliever</a>
      </p>
    </div>
  </article>

  <article class="twit">
    <div class="twit-icon">
      <i class="fa fa-bullhorn"></i>
    </div>
    <div class="twit-content">
      <p class="twit-text">
         text
      </p>
      <p class="twit-attribution">
        <a href="#">NewtonRulez</a>
      </p>
    </div>
  </article>

  <article class="twit">
    <div class="twit-icon">
      <i class="fa fa-bullhorn"></i>
    </div>
    <div class="twit-content">
      <p class="twit-text">
        Huh?
      </p>
      <p class="twit-attribution">
        <a href="#">ConfusedTweeterer</a>
      </p>
    </div>
  </article>

  <article class="twit">
    <div class="twit-icon">
      <i class="fa fa-bullhorn"></i>
    </div>
    <div class="twit-content">
      <p class="twit-text">
        text
      </p>
      <p class="twit-attribution">
        <a href="#">Setup</a>
      </p>
    </div>
  </article>

  <article class="twit">
    <div class="twit-icon">
      <i class="fa fa-bullhorn"></i>
    </div>
    <div class="twit-content">
      <p class="twit-text">
        text
      </p>
      <p class="twit-attribution">
        <a href="#">Punchline</a>
      </p>
    </div>
  </article>

  <article class="twit">
    <div class="twit-icon">
      <i class="fa fa-bullhorn"></i>
    </div>
    <div class="twit-content">
      <p class="twit-text">
        text
      </p>
      <p class="twit-attribution">
        <a href="#">Hess</a>
      </p>
    </div>
  </article>

  <article class="twit">
    <div class="twit-icon">
      <i class="fa fa-bullhorn"></i>
    </div>
    <div class="twit-content">
      <p class="twit-text">
        text
      </p>
      <p class="twit-attribution">
        <a href="#">TheIRS</a>
      </p>
    </div>
  </article>

</main>

<button type="button" id="create-twit-button"><i class="fa fa-bullhorn"></i></button>

css file:

.twit-container {
  display: flex;
  flex-wrap: wrap;
  padding: 5%;
  margin:-10px 0 0 -10px;
  position: relative;
}

.twit {
  display: inline-block;
  padding: 20px;
  width: 150px;
  height: 200px;
  margin: 10px 0 0 1%;
  background-color: #fff;
  border: 1px solid #ccc;
  flex-grow: 1;
  outline: 2px solid blue;
}

Upvotes: 47

Views: 124070

Answers (3)

Param Aggarwal
Param Aggarwal

Reputation: 2729

We want the items to expand to take up the full width equally, but we also want these items to wrap into a new row when there are too many of them. Hence we know that we need flex-direction: row here to specify that the items should flow horizontally. We also know that we need flex-wrap: wrap so that these items flow into a new row once they fill the width.

But we also want these items to resize to fill the width that is available to them after reflowing. This is where flex-basis comes in. The following screenshot shows how the example works:

div.container {
  margin: 10px;
  width: 200px;
  height: 100px;
  padding: 2px;
  background-color: black;
}

.container {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}

.child {
  flex: 1;
  flex-basis: 30%;
  background-color: red;
  margin: 2px;
}

enter image description here

This is how flex-basis is explained:

flexBasis is an axis-independent way of providing the default size of an item along the main axis. Setting the flexBasis of a child is similar to setting the width of that child if its parent is a container with flexDirection: row or setting the height of a child if its parent is a container with flexDirection: column. The flexBasis of an item is the default size of that item, the size of the item before any flexGrow and flexShrink calculations are performed.

You can try the full JSFiddle here: https://jsfiddle.net/paramaggarwal/w37t0epy/1

Upvotes: 31

cg15255
cg15255

Reputation: 399

You can set the flex-basis property of .twit which tells flexbox what base width to give each .twit element, before splitting up the remaining space to all elements.

try adding the following CSS to .twit (I used 30% not 33% to account for margins and padding, but you can play with this number.)

flex-basis: 30%;

Upvotes: 39

Karson Kalt
Karson Kalt

Reputation: 162

Your flexbox contains 8 child elements, so by default flexbox will fit as many elements on one row as possible, because your jsfiddle is only 700px wide, all remaining children are posted on a second row. It just so happens that the minimum width of the first row ended up to be three columns wide.

To get around this, I would separate each successive triplet flex items in their own flexbox, with the remaining two in a two column flexbox. Once the items are collapsed further, they will all stack into one column.

.twit-container {
  display: flex;
  flex-wrap: wrap;
  padding: 5px;
  margin: -10px 0 0 -10px;
  position: relative;
}

.twit {
  display: inline-block;
  padding: 20px;
  width: 150px;
  height: 200px;
  margin: 10px 0 0 1%;
  background-color: #fff;
  border: 1px solid #ccc;
  flex-grow: 1;
  outline: 2px solid blue;
}
<main class="twit-container">
  <article class="twit">
    <div class="twit-icon">
      <i class="fa fa-bullhorn"></i>
    </div>
    <div class="twit-content">
      <p class="twit-text">
        Sitting in web dev... This class is so awesome!
      </p>
      <p class="twit-attribution">
        <a href="#">CSMajor2017</a>
      </p>
    </div>
  </article>
  <article class="twit">
    <div class="twit-icon">
      <i class="fa fa-bullhorn"></i>
    </div>
    <div class="twit-content">
      <p class="twit-text">
        text
      </p>
      <p class="twit-attribution">
        <a href="#">BeaverBeliever</a>
      </p>
    </div>
  </article>
  <article class="twit">
    <div class="twit-icon">
      <i class="fa fa-bullhorn"></i>
    </div>
    <div class="twit-content">
      <p class="twit-text">
        text
      </p>
      <p class="twit-attribution">
        <a href="#">NewtonRulez</a>
      </p>
    </div>
  </article>
</main>

<main class="twit-container">
  <article class="twit">
    <div class="twit-icon">
      <i class="fa fa-bullhorn"></i>
    </div>
    <div class="twit-content">
      <p class="twit-text">
        Huh?
      </p>
      <p class="twit-attribution">
        <a href="#">ConfusedTweeterer</a>
      </p>
    </div>
  </article>
  <article class="twit">
    <div class="twit-icon">
      <i class="fa fa-bullhorn"></i>
    </div>
    <div class="twit-content">
      <p class="twit-text">
        text
      </p>
      <p class="twit-attribution">
        <a href="#">Setup</a>
      </p>
    </div>
  </article>
  <article class="twit">
    <div class="twit-icon">
      <i class="fa fa-bullhorn"></i>
    </div>
    <div class="twit-content">
      <p class="twit-text">
        text
      </p>
      <p class="twit-attribution">
        <a href="#">Punchline</a>
      </p>
    </div>
  </article>
</main>

<main class="twit-container">
  <article class="twit">
    <div class="twit-icon">
      <i class="fa fa-bullhorn"></i>
    </div>
    <div class="twit-content">
      <p class="twit-text">
        text
      </p>
      <p class="twit-attribution">
        <a href="#">Hess</a>
      </p>
    </div>
  </article>
  <article class="twit">
    <div class="twit-icon">
      <i class="fa fa-bullhorn"></i>
    </div>
    <div class="twit-content">
      <p class="twit-text">
        text
      </p>
      <p class="twit-attribution">
        <a href="#">TheIRS</a>
      </p>
    </div>
  </article>
</main>

Upvotes: 7

Related Questions