ChatGPT解决这个技术问题 Extra ChatGPT

Flexbox:每行 4 个项目

我正在使用弹性框来显示 8 个项目,这些项目将随我的页面动态调整大小。我如何强制它将项目分成两行? (每行 4 个)?

这是一个相关的片段:

(或者,如果您更喜欢 jsfiddle - http://jsfiddle.net/vivmaha/oq6prk1p/2/

.parent-wrapper { 高度:100%;宽度:100%;边框:1px纯黑色; } .parent { 显示:弹性;字体大小:0;弹性包装:换行;边距:-10px 0 0 -10px; } .child { 显示:内联块;背景:蓝色;边距:10px 0 0 10px;弹性增长:1;高度:100px; }

[更新] 这个问题是基于一个糟糕的无响应设计。如果您发现自己使用以下答案之一,请小心。在一个好的设计中,你会在更宽的屏幕上拥有更多的项目,而在更小的屏幕上则更少。对所有屏幕尺寸强制使用 4 个项目只会在狭窄的屏幕宽度范围内看起来有吸引力。

M
Michael Benjamin

容器上有 flex-wrap: wrap。这很好,因为它会覆盖默认值 nowrap (source)。这就是项目在 some cases 中不换行形成网格的原因。

在这种情况下,主要问题是弹性项目上的 flex-grow: 1

flex-grow 属性实际上并不调整弹性项目的大小。它的任务是在容器 (source) 中分配可用空间。所以无论屏幕尺寸多小,每个项目都会收到成比例的部分可用空间就行了。

更具体地说,您的容器中有八个弹性项目。使用 flex-grow: 1,每个人都会获得 1/8 的可用空间。由于您的项目中没有内容,它们可以缩小到零宽度并且永远不会换行。

解决方案是在项目上定义宽度。尝试这个:

.parent { 显示:弹性;弹性包装:换行; } .child { 弹性:1 0 21%; /* 下面解释 */ margin: 5px;高度:100px;背景颜色:蓝色; }

flex 简写中定义 flex-grow: 1 后,flex-basis 无需为 25%,由于边距,这实际上会导致每行三个项目。

由于 flex-grow 将占用行上的可用空间,因此 flex-basis 只需大到足以强制执行换行即可。在这种情况下,使用 flex-basis: 21%,边距有足够的空间,但没有足够的空间容纳第五个项目。


我喜欢这个,因为它对我有用,但是“充足的空间”让我感到有点不安。是否存在一些微小的窗口或情况,这种“估计”可能会让我失望?
“如果你设置了非常大的边距,布局可能会中断” 这是我想要避免的一个场景示例。我不关心实用性;满足我对完美的崇拜。有没有更准确的方法?
您也可以使用 flex: 1 0 calc(25% - 10px);
很好的答案!我使用的一个小改进是 margin: 2%; 而不是固定的像素数,以防止框在小型设备/分辨率上跳到新行。对于不同的盒子宽度,一般公式是 (100 - (4 * box-width-percent)) / 8%
万一有人忘记了,这里的 flex 属性是 flex-grow: 1; 的简写。弹性收缩:0;弹性基础:21%;
I
Iharob Al Asimi

.child 元素添加宽度。如果您希望每行总是 4 个,我个人会在 margin-left 上使用百分比。

DEMO

.child {
    display: inline-block;
    background: blue;
    margin: 10px 0 0 2%;
    flex-grow: 1;
    height: 100px;
    width: calc(100% * (1/4) - 10px - 1px);
}

好主意。我用这个想法做了一些小的修改。 jsfiddle.net/vivmaha/oq6prk1p/6
啊。这实际上并不能解决我的问题。有关示例,请参见此处:jsfiddle.net/vivmaha/oq6prk1p/7。我没有使用百分比作为保证金的自由。它们必须是固定宽度。这意味着我们选择的神奇的 23% 将不起作用,因为它没有考虑固定保证金。
是的,calc 解决了它! '计算(100% * (1/4) - 10px - 1px)'。请参阅jsfiddle.net/vivmaha/oq6prk1p/9
那么 flex 在这还有什么用呢?
那么响应式设计呢?我们不想给孩子一个固定的宽度
C
Capy

这是另一种方法。

您也可以通过这种方式完成它:

.parent{
  display: flex;
  flex-wrap: wrap;
}

.child{
  width: 25%;
  box-sizing: border-box;
}

示例:https://codepen.io/capynet/pen/WOPBBm

还有一个更完整的示例:https://codepen.io/capynet/pen/JyYaba


如果我的孩子少于 4 个怎么办?我不喜欢那个空白的地方,孩子没有反应......
Muddasir Abbas 的另一个答案仅使用弹性设置,所以我认为这是一个更清洁的解决方案。
s
shanomurphy

我会这样做,使用负边距和计算排水沟:

.parent {
  display: flex;
  flex-wrap: wrap;
  margin-top: -10px;
  margin-left: -10px;
}

.child {
  width: calc(25% - 10px);
  margin-left: 10px;
  margin-top: 10px;
}

演示: https://jsfiddle.net/9j2rvom4/

替代 CSS 网格方法:

.parent {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}

演示: https://jsfiddle.net/jc2utfs3/


这不仅有效,而且也使 div 居中。比 flexbox 更适合我的情况
我相信 CSS 网格现在得到了足够好的支持,可以安全地使用它
t
timthedev07

有关更多详细信息,您可以关注此Link

.parent{ 显示:弹性;弹性包装:换行; } .parent .child{ 弹性:1 1 25%; /*开始运行代码片段输出CSS*/ padding: 5px; box-sizing:边框框;文本对齐:居中;边框:1px 实心#000; /*End Run Code Snippet output CSS*/ }

1
2
3
4
5
6
7
8


谢谢,要轻松控制列的数量,您可以flex: 1 1 calc(100% / 6)
J
Joseph Cho

我相信这个例子比@dowomenfart 更简单,更容易理解。

.child {
    display: inline-block;
    margin: 0 1em;
    flex-grow: 1;
    width: calc(25% - 2em);
}

这在直接切肉的同时完成了相同的宽度计算。由于其可扩展性和移动友好性,数学计算要容易得多,em 就是 new standard


em 并不是真正的新标准。这可能会让人头疼,而且设计师在设计时不会考虑到 EM。
M
Mateus Manosso Barszcz

.parent-wrapper { 高度:100%;宽度:100%;边框:1px纯黑色; } .parent { 显示:弹性;字体大小:0;弹性包装:换行;右边距:-10px;边距底部:-10px; } .child { 背景:蓝色;高度:100px;弹性增长:1;弹性收缩:0;弹性基础:计算(25% - 10px); } .child:nth-child(even) { 边距:0 10px 10px 10px;背景颜色:石灰; } .child:nth-child(odd) { 背景色:橙色; } Document < /head>

;)


如果可以,请添加一些上下文,说明为什么这会回答 OP 问题,而不仅仅是发布代码。
如果您将 justify-content: space-evenly; 添加到 prent,那么它们会很好地对齐,您不必对孩子执行 calc。不过,谢谢你的例子!
z
zurfyx

Flex wrap + 负边距

为什么选择 flex 与 display: inline-block

Flex 为元素大小提供了更大的灵活性

内置白色间距折叠(请参阅 3 个宽度正好为 33% 的内联块 div 不适合父级)

为什么是负边距?

要么使用 SCSS 或 CSS-in-JS 处理边缘情况(即列中的第一个元素),要么设置默认边距并稍后去掉外边距。

执行

https://codepen.io/zurfyx/pen/BaBWpja

<div class="outerContainer">
    <div class="container">
        <div class="elementContainer">
            <div class="element">
            </div>
        </div>
        ...
    </div>
</div>
:root {
  --columns: 2;
  --betweenColumns: 20px; /* This value is doubled when no margin collapsing */
}

.outerContainer {
    overflow: hidden; /* Hide the negative margin */
}

.container {
    background-color: grey;
    display: flex;
    flex-wrap: wrap;
    margin: calc(-1 * var(--betweenColumns));
}

.elementContainer {
    display: flex; /* To prevent margin collapsing */
    width: calc(1/var(--columns) * 100% - 2 * var(--betweenColumns));
    margin: var(--betweenColumns);
}

.element {
    display: flex;
    border: 1px solid red;
    background-color: yellow;
    width: 100%;
    height: 42px;
}

S
Samet Akpınar

你可以试试这个

.parent-wrapper { 高度:100%;宽度:100%;边框:1px纯黑色; } .parent { 显示:网格;字体大小:0;网格模板列:25% 25% 25% 25%; } .child { 背景:蓝色;弹性增长:1;高度:100px;边距:10px;边距底部:0; } .child:last-child { margin-bottom: 10px; }

https://jsfiddle.net/samet19/gdntwLhb/


提问者要求弹性,但你回答网格。
J
Jef

这是不使用 calc() 的另一种方法。

// 4 PER ROW
// 100 divided by 4 is 25. Let's use 21% for width, and the remainder 4% for left & right margins...
.child {
  margin: 0 2% 0 2%;
  width: 21%;
}

// 3 PER ROW
// 100 divided by 3 is 33.3333... Let's use 30% for width, and remaining 3.3333% for sides (hint: 3.3333 / 2 = 1.66666)
.child {
  margin: 0 1.66666% 0 1.66666%;
  width: 30%;
}

// and so on!

这里的所有都是它的。您可以花哨的尺寸来获得更美观的尺寸,但这就是我们的想法。


我还没有对此进行测试,但是 CSS 语法是错误的(CSS 值没有被引用,并且声明应该以分号结尾)所以它肯定不会以当前的形式工作。