CSS Flexbox - 根据屏幕大小组织弹性项目

Posted

技术标签:

【中文标题】CSS Flexbox - 根据屏幕大小组织弹性项目【英文标题】:CSS Flexbox - Organizing flex items based on screen size 【发布时间】:2018-04-24 11:45:23 【问题描述】:

我有一个 flex 项目容器,我试图根据屏幕大小以不同的布局组织具有不同数量的 flex 项目。例如,在桌面上,我想要 4 个容器,每个容器有 2 个项目,布置在 2x4 网格中,每个单元格是 1x2。我似乎无法理解的是纯粹使用 flexbox 在平板电脑上获取布局。任何指向正确方向的指针都会很棒。

div 
  box-sizing: border-box;
  width: 100%;


.container 
  display: flex;
  border: 1px solid red;
  flex-wrap: wrap;
  flex-direction: row;
  padding: 10px;


.cell 
  display: flex;
  flex: 50%;
  padding: 10px;
  border: 1px solid blue;
  height: 100px;


.data 
  width: 100%;
  justify-content: middle;
  flex: 1;
  border: 1px solid green;


@media only screen and (max-width: 1024px) 
  .container 
    display: inline-block;
    position: relative;
  

  
  #cell1  
    width: 66%; 
    float: left;
  
  
  #cell2 
    flex-direction: column;
    right: 10px;
    position: absolute;
    width: 33%;
    height: 100%;
  
  
  #cell3  
    width: 66%; 
    float: left;
  
  
  #cell4  display: none;


@media only screen and (max-width: 640px) 
  
  #cell2 
    flex-direction: row;
    position: static;
    height: 100px;
  
  
  #cell4  display: none; 
  
  .container  
    flex-direction: row;
    flex-wrap: wrap;
    display: flex;
  
  
  .cell  
    flex: 100%; 
  
<div class="container">
  <div class="cell" id="cell1">
    <span class="data">Image1</span>
    <span class="data">Info1</span>
  </div>
  <div class="cell" id="cell2">
    <span class="data">Image2</span>
    <span class="data">Info2</span>
  </div>
  <div class="cell" id="cell3">
    <span class="data">Image3</span>
    <span class="data">Info3</span>
  </div>
  <div class="cell" id="cell4">
    <span class="data">Image4</span>
    <span class="data">Info4</span>
  </div>
</div>

这是一个密码笔here。

可以通过调整窗口大小来测试响应能力。通过删除第 4 个容器并更改 flex-direction 属性,我能够正确获得桌面和移动设备所需的布局。努力为平板电脑做同样的事情,以允许像在网格布局中一样跨越多个行/列。

桌面 - 容器:2x4 |单元格:1x2

|---------------------------------|
| --------------- --------------- |
| | Cell | Cell | | Cell | Cell | |
| --------------- --------------- |
| --------------- --------------- |
| | Cell | Cell | | Cell | Cell | |
| --------------- --------------- | 
|---------------------------------|

平板电脑 - 容器:2x3 |单元格:1x2/2x1

|--------------------------|
| --------------- -------- |
| | Cell | Cell | | Cell | |
| --------------- |______| |
| --------------- |      | |
| | Cell | Cell | | Cell | |
| --------------- -------- |
|--------------------------|

移动 - 容器:3x2 |单元格:1x2

|-----------------|
| --------------- |
| | Cell | Cell | |
| --------------- |
| --------------- |
| | Cell | Cell | |
| --------------- |
| --------------- |
| | Cell | Cell | | 
| --------------- |
|-----------------|

【问题讨论】:

另外,对于桌面,您有 8 个项目,其他 6 个,那么缺少 2 个是怎么回事? @LGSon 这是故意的。随着屏幕尺寸的减小,我想显示更少的项目。更多用于 UX/UI 目的。 好吧,即使是有意的东西也需要与代码示例一起发布,否则我们只会猜测,您可能会开始说我不是那个意思单元格包含在...... 中,因此为避免所有这些,请更新您的问题。 @LGSon 我根据您的建议创建了一个带有代码的 codepen,并在获得移动和桌面屏幕上所需的布局方面取得了一些进展。问题出在平板电脑上,并且当您调整浏览器窗口大小时,您会看到一个容器跨越多个列。 答案在您自己的问题描述中,一个容器跨越多个列。要让它在平板模式下工作,您需要将container 设为弹性列容器,或者使用绝对或浮动来定位第二个单元格。它们在响应性方面都有局限性,即弹性列容器解决方案需要固定高度。那么你想用哪一个呢? 【参考方案1】:

由于 cmets 可以被移除,并且为了保持它们的价值,我决定发布一个答案,并以此代码 sn-p 为基础。

div 
  box-sizing: border-box;
  width: 100%;


.container 
  display: flex;
  border: 1px solid red;
  flex-wrap: wrap;
  flex-direction: row;
  padding: 10px;


.cell 
  display: flex;
  flex: 50%;
  padding: 10px;
  border: 1px solid blue;
  height: 100px;


.data 
  width: 100%;
  justify-content: middle;
  flex: 1;
  border: 1px solid green;


@media only screen and (max-width: 1024px) 
  .container 
    display: inline-block;
    position: relative;
  

  
  #cell1  
    width: 66%; 
    float: left;
  
  
  #cell2 
    flex-direction: column;
    right: 10px;
    position: absolute;
    width: 33%;
    height: 100%;
  
  
  #cell3  
    width: 66%; 
    float: left;
  
  
  #cell4  display: none;


@media only screen and (max-width: 640px) 
  
  #cell2 
    flex-direction: row;
    position: static;
    height: 100px;
  
  
  #cell4  display: none; 
  
  .container  
    flex-direction: row;
    flex-wrap: wrap;
    display: flex;
  
  
  .cell  
    flex: 100%; 
  
<div class="container">
  <div class="cell" id="cell1">
    <span class="data">Image1</span>
    <span class="data">Info1</span>
  </div>
  <div class="cell" id="cell2">
    <span class="data">Image2</span>
    <span class="data">Info2</span>
  </div>
  <div class="cell" id="cell3">
    <span class="data">Image3</span>
    <span class="data">Info3</span>
  </div>
  <div class="cell" id="cell4">
    <span class="data">Image4</span>
    <span class="data">Info4</span>
  </div>
</div>

要使其在平板电脑模式下工作,您需要将container 设为弹性列容器,或者使用绝对或浮动来定位第二个单元格。

它们在响应能力方面都有局限性,即弹性列容器解决方案需要固定高度。

我发现最有用的方法是保留默认的 flex 行设置,并将其与第二个单元格上的绝对位置结合起来。

这样,第一个和第三个单元格将继续作为弹性项目,并从其响应能力中受益。

如果第 2 个单元格的内容高于第 1/3 个单元格,则可以允许它滚动,或者添加一个小脚本来调整其父级的高度。

Updated codepen

堆栈sn-p

div 
  box-sizing: border-box;
  width: 100%;


.container 
  display: flex;
  border: 1px solid red;
  flex-wrap: wrap;
  flex-direction: row;
  padding: 10px;


.cell 
  display: flex;
  flex: 50%;
  padding: 10px;
  border: 1px solid blue;
  height: 100px;


.data 
  width: 100%;
  justify-content: middle;
  flex: 1;
  border: 1px solid green;


@media only screen and (max-width: 640px) 
  
  #cell2 
    flex-direction: row;
    position: static;
    height: 100px;
  
  
  #cell4  display: none; 
  
  .container  
    flex-direction: row;
    flex-wrap: wrap;
    display: flex;
  
  
  .cell  
    flex: 100%; 
  


@media only screen and (min-width: 640px) and (max-width: 1024px) 
  .container 
    position: relative;
  
  
  #cell1  
    flex: 0 0 66%; 
  
  
  #cell2 
    flex-direction: column;
    right: 10px;
    position: absolute;
    width: 33%;
    height: calc(100% - 20px);
  
  
  #cell3  
    flex:  0 0 66%; 
  
  
  #cell4  display: none;
<div class="container">
  <div class="cell" id="cell1">
    <span class="data">Image1</span>
    <span class="data">Info1</span>
  </div>
  <div class="cell" id="cell2">
    <span class="data">Image2</span>
    <span class="data">Info2</span>
  </div>
  <div class="cell" id="cell3">
    <span class="data">Image3</span>
    <span class="data">Info3</span>
  </div>
  <div class="cell" id="cell4">
    <span class="data">Image4</span>
    <span class="data">Info4</span>
  </div>
</div>

【讨论】:

以上是关于CSS Flexbox - 根据屏幕大小组织弹性项目的主要内容,如果未能解决你的问题,请参考以下文章

CSS3之弹性盒子(Flex Box)

弹性盒子

弹性盒布局(Flex Box)

Flexbox布局(转)

CSS3弹性盒布局方式

CSS3弹性盒子多媒体查询