简体   繁体   English

当任何一个 flex-item 对 flex-container 来说太宽时,让所有的 flex-items 换行(如 flex-direction: column)

[英]Make ALL flex-items wrap (like flex-direction: column) when any one flex-item too wide for flex-container

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 ).当在一个大的 PC 屏幕上时,所有的单选按钮通常都在屏幕上的一行中(就像一个非包装的 flex 容器中的 flex 项目,带有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 ).如果任何一个单选按钮不适合,我希望它们每行显示一个(就像 flex 容器中的 flex 项目,带有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).如果我知道单选按钮标签的长度,这将很容易,但我不知道(它们来自客户端可配置的数据库)。 在此处输入图片说明

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.我事先不知道@media (min-width: /max-width:)断点是什么。

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. flex: 1 0 0这用于使所有 flex 项目的主轴大小相等。 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.如果 flex-items 都保持相同的大小,那么它们对于父 flex-container 来说都太长了,所以都会换行。 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.但是,这不会发生,因为每个 flex-item 的最小尺寸是不同的,所以尽管 flex 项目永远不会缩小,但它们都开始增长以从不同的尺寸开始填充剩余空间。

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.这就像我想要一个flex-basis: largest-sibling ,我的意思是最小的 flex-item 与最大的 flex-item 的大小相同,并且永远不会小于那个最大的 flex-item。

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>

I think that the CSS grid can achieve the closest answer to your needs我认为CSS网格可以实现最接近您需求的答案

 .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 CSS 网格中自动调整列大小

You can read more about it here and tweak it to fit your needs您可以在此处阅读有关它的更多信息并对其进行调整以满足您的需求

The key insights here are:这里的关键见解是:

1) This problem is a two dimensional problem . 1) 这个问题是一个二维问题

Two dimension problems: solve with display: grid;二维问题:用display: grid;解决display: grid;

One dimension problems: solve with display: flex;一维问题:用display: flex;解决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 ; 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.我还必须选择一个任意的视口宽度从垂直轻弹到水平,并使用@media 语句。

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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 flex-direction 列弹性容器中弹性项目的高度相同 - Same height for flex items in the flex-direction column flex container 如何在弯曲方向柱容器中制作50%宽且并排的儿童用品? - how to make some child items 50% wide and side by side in flex-direction column container? 容器上的 Flex 方向和 flex wrap 会在 flex-item 中产生额外的空间 - Flex direction and flex wrap on a container results in an extra space in a flex-item 将一个 flex-item 从 flex-container 中移出 - Move one flex-item move out from flex-container Flexbox 项目不包装最新的 Safari 和 Chrome(在 flex-container 上使用 max-width,在 flex-items 上使用 flex-basis) - Flexbox items don't wrap in latest Safari and Chrome (using max-width on flex-container and flex-basis on flex-items) Center Text 相对于 Flex-Container 的垂直轴,而不是它所属的 Flex-Item - Center Text Relative to the Flex-Container's vertical axis, not the Flex-Item it belongs to 将flex项目放置在flex容器的底部 - Positioning a flex item to the bottom of the flex-container 在 flex-direction: column 中显示一行中的 flex 项 - Display flex items in a row in flex-direction: column 弹性项目填充高度但没有弹性方向:列 - Flex item fill height but without flex-direction: column Flexbox:当flex-direction:列,flex-wrap:wrap时,宽度计算错误 - Flexbox: wrong width calculation when flex-direction: column, flex-wrap: wrap
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM