What is the best way to make a display:flex container grow horizontally along with its wrapped items?

When working with css flexbox, the behavior of the main browsers can vary significantly in certain aspects.

For example, I am attempting to build a grid of images:

<div class="container">
     <div class="photo"></div>
     <div class="photo"></div>
     <div class="photo"></div>
     <div class="photo"></div>
     <div class="photo"></div>
     <div class="photo"></div>
</div>


.container {
    display:inline-flex;
    flex-flow : column wrap;
    align-content : flex-start;
    height : 100%;
}

In this scenario, I require a container with multiple div elements that flow vertically and wrap when needed to create columns of photos.

The challenge is to ensure the container expands horizontally to fit the wrapped elements:

For a visual representation, check out this jsFiddle.

Here's how each browser behaves:

  • IE 11 - The container expands horizontally to wrap each column of elements effectively.
  • Firefox - The container only wraps the first column with the remaining overflowing out.
  • Chrome - The container always stretches to fill the width of its parent element.

In this case, I aim to achieve IE11's behavior in Firefox and Chrome. So, the question remains: How can I make a flexbox container expand horizontally to match its column wrap elements?

Appreciate your insights.

Answer №1

It is interesting how many web browsers have not correctly implemented column flex containers, yet the support for writing modes is quite satisfactory.

As a solution, you can utilize a row flex container with a vertical writing mode. By doing so, the block direction will be swapped with the inline direction, causing the flex items to flow vertically. Afterwards, you simply need to restore the horizontal writing mode within the flex items.

.container {
  display: inline-flex;
  writing-mode: vertical-lr;
  flex-wrap: wrap;
  align-content: flex-start;
  height: 350px;
  background: blue;
}
.photo {
  writing-mode: horizontal-tb;
  width: 150px;
  height: 100px;
  background: red;
  margin: 2px;
}
<div class="container">
  <div class="photo">1</div>
  <div class="photo">2</div>
  <div class="photo">3</div>
  <div class="photo">4</div>
  <div class="photo">5</div>
  <div class="photo">6</div>
  <div class="photo">7</div>
  <div class="photo">8</div>
  <div class="photo">9</div>
</div>

Keep in mind that this method may encounter some bugs in specific scenarios, particularly when combining advanced layout techniques like floats and nested flexboxes. However, it generally performs well in common situations.

Answer №2

According to the specifications, the code you're using should function properly, but unfortunately, it is not implemented correctly in most major browsers besides Internet Explorer and Edge. This issue renders multi-line layouts using inline-flex and column useless for the majority of developers at this time. A bug report on Chromium showcases a similar example to yours, demonstrating the incorrect rendering in Chrome, Safari, and Firefox.

The technical aspects of the specification may be complex to grasp, but the crucial point is that the Flexible Box Layout Module Level 1 defines the intrinsic cross-size of a flex container, specifically for flex-direction: row and flex-direction: column in the Flex Container Intrinsic Cross Size section. The specification states:

For a multi-line flex container, the min-content/max-content cross size is the sum of the flex line cross sizes

Essentially, the width of a flex-direction: column flex container should be the total width of its columns. However, Chrome, Firefox, and Safari inaccurately calculate this width, resulting in it being set to the width of the widest single element when using width: min-content or width: max-content on a wrapped column flex box in Chrome.

While there is a Chrome-specific workaround available, it is advisable to avoid it. Until this bug is resolved, this particular aspect of the Flexbox model does not function as intended, leaving developers without a clear solution.

Answer №3

It appears that this issue may require a JQuery solution rather than just CSS.

Calculate the container width by subtracting the position of the last child from the position of the container and adding the width of the last child (including margin).

Sample Code :

$(document).ready(function() {
 $('.container').each(function( index ) {
     var lastChild = $(this).children().last();
     var newWidth = lastChild.position().left - $(this).position().left + lastChild.outerWidth(true);
     $(this).width(newWidth);
    })
});

See Demo :

http://jsfiddle.net/qzea320L/

Answer №4

Your design features a column layout distribution within a fixed height container.

By setting the flex-direction to column, you establish the Vertical axis as the primary axis.

This means, in flexbox, it will first fill up the available height before creating a new column.

Check out this example where javascript is used to adjust the container's height, causing the child items to move accordingly.

Note: It's advisable not to depend on IE for flex support as their implementation is relatively new.

Answer №5

Here is an alternative solution to consider:

.container {
  column-count: 2; /*or any desired number */
}
.container > div {
  display: inline-block;
}

Learn more about CSS column-count

If the elements do not align properly at the top, you may need to adjust the margin-top of .container > div:first-child.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Label text will not be wrapped in front of the label (bootstrap)

I'm struggling with some css coding. I want the text to wrap so the label is positioned on the middle right of the box, similar to this example: https://i.sstatic.net/RBIOS.png. However, currently it looks like this: http://jsfiddle.net/yuvemL1z/ and ...

Displaying the information from a nested array of objects in an HTML table through iteration

In the code snippet below, there is an input with a nested array of objects. The main array of objects is called summary and within it, there's a nested array called run_type. let input = { "summary": [ { " ...

What could be the reason for an element with a width of 100% not recognizing the width of its parent?

One issue I'm currently experiencing is my inability to match the width of the parent within a flexbox item. Below is the code snippet, where the span element does not have the same width as its parent. .container { display: flex; } .item1 { ...

Troubleshooting issues with Bootstrap Accordion functionality within a React environment

After copying and pasting the Accordion code directly from Bootstrap, I'm facing an issue where the style is not consistent and the functionality isn't working as expected. Snippet from About.js: import React, { useState } from 'react' ...

Pan motion gesture above HTML components

Is it possible to create a hovering effect over elements in a container using a pan gesture? https://i.sstatic.net/E6G56.gif Here's the HTML code: <div class="container"> <div class="item"></div> <div class="item"></div ...

Choosing colors for Font Awesome icons

Is there a way to customize the color of a font awesome icon using CSS? I've tried changing the color of everything except font awesome icons with this code: ::selection{ background: #ffb7b7 !important; /* Safari */ } ::-moz-selection { back ...

Exploring the world of CSS: accessing style attributes using JavaScript

So I created a basic HTML file with a div and linked it to a CSS file for styling: HTML : <html> <head> <title>Simple Movement</title> <meta charset="UTF-8"> <link rel="stylesheet" type=&qu ...

Transferring the values of JavaScript objects to HTML as strings

My goal is to generate HTML elements based on the values of specific JavaScript objects that are not global variables. However, when attempting to execute the code below, I encounter an error stating "params is not defined." What I actually aim to achieve ...

Maintaining image ratio on the entire screen

I am in search of a way to create a webpage that includes the following elements from top to bottom: Full-screen width image/background-image (maintaining aspect ratio) Navigation bar (aligned at the top right of the image) Some text Another full-screen ...

Creating a scroll bar that overlaps a chart within a div

I am currently working on implementing a button that generates a report by plotting some charts. Initially, these charts are hidden until the button is pressed. I am utilizing Bootstrap for the design, and as a result, the scrollbar is also hidden. Upon cl ...

Looking to create a custom loader that adapts to different screen sizes

Can anyone help me make the text in my centered div responsive on my website loader? I'm new to coding and struggling to figure it out. Any assistance would be greatly appreciated! Make sure to view the full page snippet so you can see the text prope ...

Eliminate gaps between lines in a wrapped Flexbox layout

I am trying to eliminate the spaces between rows in a horizontal list flexbox. I am creating an alphabetical list and I want it to flow seamlessly without any gaps. This is what I have so far: #example { display: block; margin-left: auto; margin-r ...

Clicking on a link with JQuery does not fire the action when the href attribute is set to "#open-site"

My navigation setup is as follows: <ul> <li><a href="index.html#open-site">Test</a></li> <li><a href="#open-site">Test</a></li> <li><a href="test.html#open-site"> ...

Elevate Your Design with Bootstrap 4 - Rearrange Rows with Ease

I have been browsing the Bootstrap documentation, but I am unable to locate the specific class needed to achieve a certain effect. Is there a method for shifting or offsetting a div Row if the parent row has a column that pushes down the bottom div? Can th ...

Disabling the scrollbar in Selenium screenshots

When using Chromedriver to capture screenshots of webpages, my code effectively does the job. However, I am now facing an issue with removing the unsightly scrollbars from the image. Is it feasible to inject CSS into the webpage in order to achieve this? W ...

What steps are needed to create a hover box that appears on the right side of my div?

I am attempting to customize the code found at this link so that the box slides to the left side instead of the right. I thought changing right: 0; to right: 100%; in the .overlay class would achieve this, but it is not working as expected. I want it to l ...

Text input field with uneditable text displayed at the end

Click here to view the input field I am looking to create an input field that always displays a "%" at the end of the input. Here is what my react component looks like currently: <StyledBaseInput type="text" ...

Tips for positioning an inline label and input field in an Angular application using CSS and HTML: How to align the label to the left and the input

I'm currently developing an Angular form with multiple label-input field combinations. I have managed to style the labels and input fields with inline block so that they appear on the same row. However, I am facing a challenge in aligning the label to ...

Get a calendar that displays only the month and year

I am looking to incorporate two unique PrimeFaces calendars on a single page. The first calendar will display the date, while the second one will only show the month and year. To achieve this, I have implemented the following JavaScript and CSS specifica ...

What is the best way to determine the variable height of a div in Angular 7?

I'm currently trying to use console.log in order to determine the height of a div based on the size of a table inside it. This information is crucial for me to be able to ascertain whether or not a scrollbar will be present, especially within a dialog ...