Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allow inline block elements to stretch fluidly and collapse and stack as viewports shrink

Given the following code, I would like to find a way to have a series of inline-block elements stretch the full width of the parent element while stacking on top of each other as the line wraps.

<div id="parent">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>

Example

If all children have the same min-width, I want this to create a grid effect. For example, on larger screens, the children may stack 5 across until they wrap onto a second line. I would like those all to be 20% (1/5) of the available width. As the screen shrinks, the fifth and 10th items wrap leaving two rows of 4 items and a third row of 2 items. Now I would like to have the children all stretch 25% (1/4) of the available width except for the last row of two children. Those should be 50% each.

Attempts

I've tried floating the children, making them inline-blocks and I've experimented with flex-box, but none of them are giving me the result I desire. Inline-blocks have come the closest, allowing them to stack as with parent width shrinks, but I can't achieve the stretching.

Restrictions

I'd prefer not to use media queries as I would then need to write in the exact breakpoints for this example then alter all of them if anything changes in the site layout. I'd like to find a more organic way to solve this problem.

Javascript is out. I want to find a way to do this with just CSS.

like image 992
KeyboardCowboy Avatar asked Feb 28 '14 15:02

KeyboardCowboy


People also ask

What does display inline do?

display: inlineAn element with a display property set to inline will not start on a new line and it will take up the remaining/available screen width. It just takes up the space such an element would normally take.

What is the use of inline-block in CSS?

“display: inline-block” Property: This property is used to display an element as an inline-level block container. The element itself is formatted as an inline element, but it can apply height and width values. It is placed as an inline element (on the same line as adjacent content).

What are inline-block elements?

Inline-block elements are similar to inline elements, except they can have padding and margins added on all four sides. You'll have to declare display: inline-block in your CSS code. One common use for using inline-block is for creating navigation links horizontally, as shown below.

What is the difference between inline inline-block and block?

The display: inline-block Value Compared to display: block , the major difference is that display: inline-block does not add a line-break after the element, so the element can sit next to other elements.


1 Answers

Many thanks to Chris Coyier and CSS Tricks. Flexbox is indeed the answer. Rather than copy and paste his solution, here's the link to his Pen: http://codepen.io/chriscoyier/pen/yCeax. If you are interested in his whole thought about it, here is the blog post to it: http://css-tricks.com/filling-space-last-row-flexbox/

Here's the actual solution, just in case the CodePen goes away.

HTML

<button id="add">Add Child</button>

<div id="parent">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>

CSS

* {
  box-sizing: border-box;  
}

#parent {
  display: flex;
  flex-wrap: wrap;
}

.child {
  height: 50px;
  background: red;
  flex: 1;
  min-width: 25%;
  border: 5px solid white;
}

@media (max-width: 700px) {
  .child {
    min-width: 33.33%; 
  }
}

@media (max-width: 400px) {
  .child {
    min-width: 50%; 
  }
}

jQuery

$("#add").on("click", function() {
  $("#parent").append("<div class='child' />");
});
like image 126
KeyboardCowboy Avatar answered Sep 17 '22 12:09

KeyboardCowboy