如何在弹性项目及其容器周围创建“折叠”边框?
Posted
技术标签:
【中文标题】如何在弹性项目及其容器周围创建“折叠”边框?【英文标题】:How to create "collapsed" borders around flex items and their container? 【发布时间】:2016-06-11 05:46:48 【问题描述】:我有以下布局:
#limited-width
width: 100%;
max-width: 200px;
margin: 0 auto;
font-size: 18px;
ul
display: flex;
flex-flow: row wrap;
list-style: none;
padding: 0;
margin: 20px;
ul > li
display: block;
text-align: center;
flex: 1 0 auto;
max-width: 100%;
box-sizing: border-box;
margin: 0;
padding: 4px 7px;
border: 2px solid rgba(0,0,0,.3);
background-color: rgba(0,0,0,.03);
<div id="limited-width">
<ul>
<li>Apple</li>
<li>Orange</li>
<li>Pineapple</li>
<li>Banana</li>
<li>Tomato</li>
<li>Pear</li>
<li>Lemon</li>
</ul>
</div>
如您所见,ul
内的列表项有一个宽度为2px
的边框,但正因为如此,元素之间的边框加倍了。我正在寻找一种方法来使元素之间的边框宽度相同,同时使用 flexbox 保持外部边框相同(类似于border-collapse
在表格上的工作方式)。这可能吗?如果可以,怎么做?
【问题讨论】:
【参考方案1】:有两种主要方法可以实现这一目标。在每种方法下,您都会找到一个工作演示,您可以展开它来查看它的行为方式。将鼠标悬停在元素上会给它们一个红色边框,以便您更轻松地选择最适合您的方法。
父子边框对齐
你需要像这样定义边框:
ul, ul > li
border-style: solid;
border-color: rgba(0,0,0,.3);
ul border-width: 2px 0 0 2px
ul > li border-width: 0 2px 2px 0
这里的关键在border-width
属性中:
top
和 left
的值设置为所需大小,而 right
和 bottom
设置为 0
在项目上,right
和 bottom
的值设置为所需大小,而 top
和 left
设置为 0
通过这样做,边框将以某种方式叠加起来,从而在元素和容器周围形成一个折叠良好、一致的边框。
:hover border-color: red
#limited-width
width: 100%;
max-width: 200px;
margin: 0 auto;
font-size: 18px;
ul, ul > li
border-style: solid;
border-color: rgba(0,0,0,.3);
ul
display: flex;
flex-flow: row wrap;
list-style: none;
padding: 0;
margin: 20px;
border-width: 2px 0 0 2px;
ul > li
display: block;
text-align: center;
flex: 1 0 auto;
max-width: 100%;
box-sizing: border-box;
margin: 0;
padding: 4px 7px;
border-width: 0 2px 2px 0;
background-color: rgba(0,0,0,.03);
<div id="limited-width">
<ul>
<li>Apple</li>
<li>Orange</li>
<li>Pineapple</li>
<li>Banana</li>
<li>Tomato</li>
<li>Pear</li>
<li>Lemon</li>
</ul>
</div>
边框减半
如果您出于任何目的想要为每个元素设置不同的边框,这可能是一种适合您需求的折衷方案。给定所需的border-width
或2px
,CSS 如下:
ul, ul > li
border: 1px solid rgba(0,0,0,.3);
此方法在父项及其子项上设置所需边框宽度的一半,使最终边框2px
变粗。小心使用这种带有小数像素的方法(例如1.5px
),你可以使用run into issues。
使用border-color
-更改规则时,半角会很明显,但如果您想要更好看的边框,这比第一种方法要好得多。
:hover border-color: red
#limited-width
width: 100%;
max-width: 200px;
margin: 0 auto;
font-size: 18px;
ul, ul > li
border: 1px solid rgba(0,0,0,.3);
ul
display: flex;
flex-flow: row wrap;
list-style: none;
padding: 0;
margin: 20px;
ul > li
display: block;
text-align: center;
flex: 1 0 auto;
max-width: 100%;
box-sizing: border-box;
margin: 0;
padding: 4px 7px;
background-color: rgba(0,0,0,.03);
<div id="limited-width">
<ul>
<li>Apple</li>
<li>Orange</li>
<li>Pineapple</li>
<li>Banana</li>
<li>Tomato</li>
<li>Pear</li>
<li>Lemon</li>
</ul>
</div>
【讨论】:
如果您希望其中一项具有不同的背景和边框颜色,例如处于活动状态?这个模型在这里不足。我的解决方法:jsbin.com/kageqe/5/edit?html,css,output【参考方案2】:我有同样的问题,但我做了这个(见下面的演示)。 我向每个块添加负'margin-left'和负'margin-top'等于边框的宽度。然后我在容器中添加相同但正的“padding-left”和“padding-top”,以补偿偏移量。哇啦啦!现在我们在 flex 项和它们的容器周围得到了“折叠”的边框。
.catalog-list
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding-top: 1px;
padding-left: 1px;
box-sizing: border-box;
max-width: 800px;
margin: auto;
box-shadow: inset 0 0 0 1px #8c8c8c;
.catalog-item
width: calc(25% + 1px);
margin-top: -1px;
margin-left: -1px;
padding: 20px;
border: 1px solid #8c8c8c;
box-sizing: border-box;
transition: all 0.2s;
box-sizing: border-box;
.catalog-item:hover
border-color: transparent;
box-shadow: 0 0 15px -2px #8c8c8c;
<div class="catalog-list">
<div class="catalog-item"></div>
<div class="catalog-item"></div>
<div class="catalog-item"></div>
<div class="catalog-item"></div>
<div class="catalog-item"></div>
<div class="catalog-item"></div>
</div>
【讨论】:
【参考方案3】:在我的例子中,边框需要为 1px,这使得它更加困难。我在https://codepen.io/Hawkun/pen/rsIEp/ 找到了一个解决方案,它使用阴影来模拟边框,实际上效果很好。
下面是实际代码。它不使用 flexbox,但如果你将阴影应用到你的 flex 内容,你就可以开始了。
body
font-family: sans-serif;
background-color: #eee;
padding: 20px;
.info
color: darkred;
font-weight: bolder;
.container
background-color: white;
float: left; /* Makes the container height the same as its children. */
padding: 10px;
margin-bottom: 40px;
.container div
padding: 20px;
float: left;
background-color: #def;
/* And here comed the trick: */
box-shadow:
1px 0 0 0 #888,
0 1px 0 0 #888,
1px 1px 0 0 #888, /* Just to fix the corner */
1px 0 0 0 #888 inset,
0 1px 0 0 #888 inset;
#container1
width: 100%;
#container2
width: 50%;
#container2 div
width: 70%;
<p>The first container:</p>
<div id="container1" class="container">
<div>Hello, this is the first floated div</div>
<div>And this is the second</div>
<div>And finally the third one</div>
</div>
<p>The second container:</p>
<div id="container2" class="container">
<div>Hello, this is the first floated div</div>
<div>And this is the second</div>
<div>And finally the third one</div>
</div>
【讨论】:
这个答案与Flexbox无关。 ...然而正如 Jon Onstott 所说,它适用于 flexbox。 我试图对此做出回应,但我做不到(限制太短)。所以我对主要问题做出回应:***.com/a/68074775/4832358【参考方案4】:这是我的解决方案:
window.addEventListener('load', function()
var containsFlex = document.getElementsByClassName('containsFlex');
var i = containsEdit.length;
while (i--) containsEdit[i].style.borderWidth = "1px 0 0 0";
问题在于 FLEX 的编程代码出现在 CSS 中设置宽度的代码之后,因此任何通过 CSS 设置这些项目的尝试都会失败。但是,使用上面的代码(或变体),可以创建可接受的结果。
[我在工作,所以我不能写一个完整的帖子。向所有人道歉]
【讨论】:
【参考方案5】:这是我的另一个想法,它可以在 flex box 换行时保持边框“折叠”。它使用顶部和左侧的背景颜色以及右侧和底部的边框。可能很难让它在背景图像上工作。
.container
display: flex;
flex-flow: row wrap;
border-style: solid;
border-width: 0 2px 2px 0;
border-color: black;
background-color: black;
.container>div
flex: 1 0 auto;
margin: 2px 0 0 2px;
background-color: white;
<div class="container">
<div>Eh?</div>
<div>Bee.</div>
<div>This div contains a whole bunch of stuff.</div>
<div>This div contains a whole bunch of stuff.</div>
<div>This div contains a whole bunch of stuff.</div>
<div>Sea!</div>
<div>This div contains a whole bunch of stuff.</div>
<div>This div contains a whole bunch of stuff.</div>
<div>This div contains a whole bunch of stuff.</div>
</div>
【讨论】:
【参考方案6】:我刚刚遇到了这个问题,这是我的解决方案。我的情况是我需要连续渲染每 4 个项目。
.container
display: flex;
flex-wrap: wrap;
.item
flex: 0 0 25%;
border-right: 1px solid black;
.item:nth-child(4n)
border-right: none;
.item:nth-child(n+5)
border-top: 1px solid black;
这样,border-right 只显示在同一行的前 1-3 个项目上。从第 5 项(第 2 行)开始,它们都有一个边框顶部。
它产生与 Ivan 的答案相似的结果。但我认为这种方法要简单得多。
【讨论】:
【参考方案7】:我希望此评论可能会有所帮助,但我的意愿是对 @jon-onstott 做出回应
您的回答帮助我解决了一个类似的案例。我注意到您使用了嵌入阴影(我想知道这是否就是您不需要修复其余角落(左上角、右上角和左下角)的原因,但我很确定如果您的所有阴影都是一开始。
我必须解决的另一点(就我而言)是我用于阴影的颜色使用了透明度(不是 100% 不透明),因此同级框弄乱了颜色。如果需要显示阴影,我使用带有负值的插入剪辑路径修复了它。
我没有显示任何代码,因为它解决了问题中没有提到的情况*,但我仍然认为这可以帮助任何错误地结束这里的人(起初)寻找一些类似的解决方案问题。
*:我的案例是一组格式良好的盒子,它们具有确定的列和行的大小。这就是为什么我知道哪些盒子需要显示阴影。尝试在 flexbox 中解决我的问题没有任何意义,因为 flexbox 的形状取决于容纳它的可用空间。
【讨论】:
【参考方案8】:使用:last-of-type
,您可以“折叠”最后一个边框。也许添加一个box-sizing:border-box;
【讨论】:
以上是关于如何在弹性项目及其容器周围创建“折叠”边框?的主要内容,如果未能解决你的问题,请参考以下文章