如何使用flexbox实现这种响应式布局
P粉733166744
P粉733166744 2024-02-26 19:29:01
0
2
447

我正在制作一个 React 应用程序,它在 Flex 容器内呈现 xy 数量的卡片和单个小部件。所有卡片具有相同的宽度和高度,但小部件的高度等于卡片高度 * 2 + row-gap。容器的宽度根据视口宽度而变化,并且在视觉上应分别看起来为带有卡片的 2 或 3 列。为了进一步清晰起见,我提供了所需布局的模型图像,小部件用蓝色表示。

无论我尝试什么,如果不将行的高度更改为其大小,我都无法让小部件显示在正确的位置,从而留下一个“空白行”,其中应该呈现 1 或 2 个以上的卡片,如显示在下图。

我当前的解决方案涉及 Javascript,根据视口宽度,我将 2 或 4 张卡加载到一个单独的小 Flex 容器中,该容器被渲染为主 Flex 容器的第一个子容器。这种解决方法在视觉上效果很好,但使我的代码变得更加复杂,因为我必须涵盖许多不同的情况才能使其正常运行。我想使用 css/flexbox 实现同样的目标,但我仍然是一个初学者,以前从未做过这样的布局,显然不知道如何做到这一点。小部件无法绝对定位,因为这会破坏其子元素的滚动功能。

我正在以正确的比例提供测试 HTML 和 CSS 测量值,以防有帮助。

.container {
  margin: 50px 300px;
  display: flex;
  flex-wrap: wrap;
  row-gap: 20px;
  column-gap: 20px;
  min-width: 320px; /* Width for 2 columns */
  max-width: 490px; /* Width for 3 columns */
  border: 3px solid rgb(0, 22, 117);
}

.card {
  width: 150px;
  height: 100px;
  background-color: bisque;
}

.widget {
  height: 220px; /* card height * 2 + row-gap */
  width: 150px;
  background-color: rgb(134, 204, 245);
}
<div class="container">
  <div class="widget"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
</div>

<!-- Original jsx
<div className='container'>
  <div className='widget'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
</div>
-->

我真的很想学习如何在 Flexbox 中创建这样的布局,不仅是因为我当前的项目,而且也是为了扩展我的知识和理解。如果您对如何解决这个问题有任何想法,请帮助我。预先感谢您:)

P粉733166744
P粉733166744

全部回复(2)
P粉391677921

这可以使用网格布局来完成,无需 JavaScript,下面是一个示例:

.container {
  margin: 50px 300px;
  display: grid;
  /* auto calculate columns, minimun cell width is 140px */  
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  
  /* height of each cell */
  grid-auto-rows: 100px;
  
  grid-auto-flow: row dense;
  gap: 20px;
  min-width: 320px;
  max-width: 490px;
  border: 3px solid rgb(0, 22, 117);
}

.card {
  background-color: bisque;
}

.widget {
  background-color: rgb(134, 204, 245);
  /* widget, span for 2 rows */
  grid-row: auto / span 2;
  
  /* set the widget to the right most column */
  grid-column-end: -1;
}
<div class="container">
  <div class="widget"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
</div>

<!-- Original jsx
<div className='container'>
  <div className='widget'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
  <div className='card'></div>
</div>
-->

正如@ralph.m 提到的。您始终可以通过将 grid-column-end: -1; 设置为 .widget

,在最右侧的列上设置 ,在最右侧的列上设置 .widget >
P粉321584263

Flexbox 布局无法做到这一点,它不会创建 2d 网格,您必须使用 gridbox 布局。,因此元素可以跨越行和列而不留间隙。

这是一个例子:

.grid {
/* give some space gutters */
  margin: 1em auto;
  padding:1em;
  gap: 1em;
 /* build a grid */
  display: grid; 
  grid-auto-flow: row dense;/* fill any holes that could show up */
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); /* auto calculate size of the grid */
  grid-auto-rows: 75px; /* give an height row for the demo */
  max-width: 80%;/* whatever */
  border: solid;/* see my boundaries */
}

.card {
  background-color: salmon;
}

.bigger {
  background-color: lightblue;
  grid-row: 1/ span 2;/* keep me on first row and lay over 2 rows */
  grid-column-end: -1; /* keep me on the last column no matter how many */
}
<div class="grid">
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="bigger">I can be anywhere in the flow but I'll show on top end</div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>
  <div class="card"></div>  
</div>
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板