Solution 1 :

This is what i’ve made from your coded. See if it helps you

<html>
  <head>
    <title>Responsive Radio Button</title>
    <style type="text/css">
      .flexContainer {
        display: flex;
        flex-wrap: wrap;
        justify-content:stretch;
        /** border so I can see what is going on */
        border: 1px dotted lightblue;
      }
      .flexItem {
        /** white-space and min-width stop text wrapping */
        white-space: nowrap; 
        min-width: max-content;
        /** next three lines could be shortened to flex: 1 0 0px; (grow shrink basis) */
        flex-basis: 0;
        flex-grow: 1;
        flex-shrink: 0;
        /** border and margin so I can see what is going on */
        border: 1px solid black;
        margin: 2px;
      }
      @media only screen and (max-width: 600px) {
        .flexContainer {
          flex-flow: column;
        }
      }

      </style>
  </head>
  <body>
    <div class='flexContainer'>
      <div class='flexItem'>Medium Length div</div>
      <div class='flexItem'>Short div</div>
      <div class='flexItem'>Short div</div>
      <div class='flexItem'>Short div</div>
      <div class='flexItem'>Longest div in this entire html page!</div>
      </div>
    </div>
  </body>
</html>

Solution 2 :

I think that the CSS grid can achieve the closest answer to your needs

.flexContainer {
  display: grid;
  grid-template-columns: repeat(auto-fit,minmax(600px,1fr))
}
<div class='flexContainer'>
      <div>Medium Length div</div>
      <div>Short div</div>
      <div>Longest div in this entire html page!</div>
  </div>

Auto sizing columns in CSS grid

You can read more about it here and tweak it to fit your needs

Solution 3 :

The key insights here are:

1) This problem is a two dimensional problem.

Two dimension problems: solve with display: grid;

One dimension problems: solve with display: flex;

I was thinking as this problem as a single dimension problem because I wanted my radio buttons to be in one case horozontal, and in the other case vertical – both refer to a single dimension. I was wrong because it involves a transition between being vertical and being horozontal, so it is a two dimension problem.

2) grid-auto-flow: column;

I also had to pick an arbitrary view port width to flick from vertical to horozontal, and use a @media statement.

This answer is not perfect, it does not equally size the options when they are not in one horozontal line, but it achieves what I was looking for:

<html>
  <head>
    <title>Responsive Radio Button</title>
    <style type="text/css">
      @media(max-width: 600px) {
        .resize {
          grid-template-columns: 600px;
        }
      }
      @media(min-width: 600px) {
        .resize {
          grid-auto-flow: column;
          grid-auto-columns: 1fr;
        }
      }
      .gridContainer {
        display: grid;

        /** border so I can see what is going on */
        border: 1px dotted lightblue;
      }
      .gridItem {
        /** white-space and min-width stop text wrapping **/
        white-space: nowrap; 
        min-width: max-content;
        /** border and margin so I can see what is going on */
        border: 1px solid black;
        margin: 2px;

      }
      </style>
  </head>
  <body>
    <div class='gridContainer resize'>
      <div class='gridItem'>Medium Length div</div>
      <div class='gridItem'>Short div</div>
      <div class='gridItem'>Short div</div>
      <div class='gridItem'>Short div</div>
      <div class='gridItem'>Longest div in this entire html page!</div>
      </div>
    </div>
  </body>
</html>

Problem :

The use case for this is a responsive form with radio buttons. When on a big PC screen, all radio buttons normally fit in one line on the screen (like flex items in a non-wrapping flex container with flex-direction: row). On a phone, not all radio buttons normally fit on one line. If any one radio button won’t fit, I want them all to display one per line (like flex items in a flex container with flex-direction: column).

This would be easy if I knew how long my radio button labels were going to be, but I don’t (they come from a client configurable database).
enter image description here

So what I want is like this:

<html>
  <head>
    <title>Responsive Radio Button</title>
    <style type="text/css">
      @media (min-width: 652px) {
        .flexContainer {
          display:flex;
          flex-direction: row;
        }
      }
      @media (max-width: 652px) {
        .flexContainer {
          display:flex;
          flex-direction: column;
        }
      }
      </style>
  </head>
  <body>
    <div class='flexContainer'>
      <div>Medium Length div</div>
      <div>Short div</div>
      <div>Longest div in this entire html page!</div>
      </div>
    </div>
  </body>
</html>

where I don’t know before hand what the @media (min-width: /max-width:) breakpoint is.

What I tried

This is my work in progress code

<html>
  <head>
    <title>Responsive Radio Button</title>
    <style type="text/css">
      .flexContainer {
        display: flex;
        flex-wrap: wrap;
        justify-content:stretch;
        /** border so I can see what is going on */
        border: 1px dotted lightblue;
      }
      .flexItem {
        /** white-space and min-width stop text wrapping */
        white-space: nowrap; 
        min-width: max-content;
        /** next three lines could be shortened to flex: 1 0 0px; (grow shrink basis) */
        flex-basis: 0;
        flex-grow: 1;
        flex-shrink: 0;
        /** border and margin so I can see what is going on */
        border: 1px solid black;
        margin: 2px;
      }
      </style>
  </head>
  <body>
    <div class='flexContainer'>
      <div class='flexItem'>Medium Length div</div>
      <div class='flexItem'>Short div</div>
      <div class='flexItem'>Short div</div>
      <div class='flexItem'>Short div</div>
      <div class='flexItem'>Longest div in this entire html page!</div>
      </div>
    </div>
  </body>
</html>

flex: 1 0 0
This is used to make all flex items equal in main axis size. But when the wrapping kicks in, the equality of main axis size drops off. If the flex-items all remained the same size, they would all be too long for the parent flex-container at the same time, so would all wrap.
This does NOT happen, though, as the minimum size of each flex-item is different, so although the flex items never shrink, they all start growing to fill the left over space from starting from a different size.

It’s like I want a flex-basis: largest-sibling, by which I mean the smallest flex-item would start at the same size as the largest flex item, and never get smaller than that largest flex-item.

Comments

Comment posted by Paulie_D

Not possible with flexbox or any other layout method. Javascript is required

Comment posted by developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/…

Thanks m_sultan – you made me re-read the doco on grid vs flex and as

Comment posted by Micah Zoltu

If you are willing to use

By