Search code examples
htmlcssflexboxcss-grid

CSS Flexbox (or Grid): 2 columns, row-wrapping, no growth, inner margins


I'm trying to get results like this image (mocked up):

Example

This is what I've tried so far, but it's clearly not working right.

.flex-container {
	width: 50%;
	border: 2px dashed blue;
	margin-bottom: 40px;
}
.flex-container > .wrapper {
	display: flex;
	flex-wrap: wrap;
	margin: -5px;
}
.flex-container > .wrapper > input {
	flex-basis: 45%;
	flex-shrink: 1;
	flex-grow: 1;
	margin: 5px;
}

.wrapper.alt1 > input {
	flex-basis: 50%;
	flex-grow: 0;
}

.wrapper.alt2 > input {
	flex-basis: 45%;
	flex-grow: 0;
}
<div class="flex-container">
	<div class="wrapper">
		<input type="button" value="Example">
		<input type="button" value="Example">
		<input type="button" value="Example">
		<input type="button" value="Example">
		<input type="button" value="Example">
	</div>
</div>

<div class="flex-container">
	<div class="wrapper alt1">
		<input type="button" value="Example">
		<input type="button" value="Example">
		<input type="button" value="Example">
		<input type="button" value="Example">
		<input type="button" value="Example">
	</div>
</div>

<div class="flex-container">
	<div class="wrapper alt2">
		<input type="button" value="Example">
		<input type="button" value="Example">
		<input type="button" value="Example">
		<input type="button" value="Example">
		<input type="button" value="Example">
	</div>
</div>

I'm getting a dynamic list of buttons and I'd prefer to set the width to a specific % instead of rounding it down to something less specific just to make the flexbox work. Or if there's an alternative way to set the number of columns to a specific number that would be fine.

Edit: I'm editing to specify that the amount of buttons is dynamic, so it may be an odd amount or an even amount. This doesn't matter in regards to the left-aligned example, but for the centered-final-item example this could be problematic.


Solution

  • Consider CSS grid for this:

    .container {
      width: 50%;
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      grid-gap: 5px;
      border: 2px dashed blue;
      margin-bottom: 40px;
    }
    
    input {
      grid-column: span 2;
    }
    
    .alt :nth-child(odd):last-child {
      grid-column: 2/span 2;
    }
    <div class="container">
      <input type="button" value="Example">
      <input type="button" value="Example">
      <input type="button" value="Example">
      <input type="button" value="Example">
      <input type="button" value="Example">
    </div>
    
    
    <div class="container alt">
      <input type="button" value="Example">
      <input type="button" value="Example">
      <input type="button" value="Example">
      <input type="button" value="Example">
      <input type="button" value="Example">
    </div>
    
    <div class="container alt">
      <input type="button" value="Example">
      <input type="button" value="Example">
      <input type="button" value="Example">
      <input type="button" value="Example">
      <input type="button" value="Example">
      <input type="button" value="Example">
    </div>