具有“溢出:隐藏"的Flexbox子级;祖父母边际溢溢 [英] Flexbox child with "overflow: hidden" overflowing grandparent margins

查看:92
本文介绍了具有“溢出:隐藏"的Flexbox子级;祖父母边际溢溢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在包装器中嵌套两个子元素,该包装器指定侧边距,以便在显示器狭窄时其内容和屏幕侧面之间有空间,而在显示器宽时则为max-width.

I'm trying to nest two child elements in a wrapper which specifies side margins so there's space between its contents and the sides of the screen when the display is narrow and a max-width for when the display is wide.

第二个孩子会有一些溢出,这应该是可见的,而第一个孩子应严格位于包装器的内容框中.在删除第一个孩子的情况下,第二个孩子的行为符合预期.但是,当我添加第一个孩子时,它似乎完全忽略了包装器的边距,拉伸了包装器的内容框,并破坏了第二个孩子.

The second child has some overflow which should be visible while the first child should stay strictly within the wrapper's content box. With the first child removed, the second child behaves as desired. When I add in the first child though, it seems to completely ignore the wrapper's margins, stretching the wrapper's content box and breaking the second child along with it.

对包装程序应用overflow: hidden可以解决边距问题,但可以裁剪第二个孩子.将边界应用于第一个孩子并不会使其与父对象一起折叠,因为它处于新的块格式上下文中.

Applying overflow: hidden to the wrapper fixes the margin problem but clips the second child. Applying the margins to the first child didn't make it collapse with the parent since it's in a new block formatting context.

到目前为止,我发现的唯一解决方法是:

The only workaround I've found so far would be to do:

.wrapper {
    > * {
        margin-left: 1.5rem;
        margin-right: 1.5rem;
    }
}

并将包装器的最大宽度增加3rem,但我希望有一些解决方案不需要我将包装器的边距转移到其子级.

and increase the max-width of the wrapper by 3rem but I was hoping there was some solution that didn't require me to shift the margin from the wrapper to its children.

https://codepen.io/HybridCore/pen/jjoWmd

body {
  background-color: #000;
  color: #FFF;
  display: flex;
  justify-content: center;
}

.wrapper {
  margin: 0 1.5rem;
  max-width: 40rem;
  width: 100%;
}

.fit_content_box {
  display: flex;
  align-items: center;
}

.L {
  min-width: 0;
  flex: 1 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.R {
  margin-left: 1rem;
  height: 1rem;
  width: 1rem;
  background-color: #FFF;
}

.overflow {
  display: flex;
  justify-content: space-between;
}

.overflow>div {
  width: 0;
  display: flex;
  justify-content: center;
}

<body>
  <div class="wrapper">
    <div class="fit_content_box">
      <p class="L">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

      <div class="R"></div>
    </div>

    <div class="overflow">
      <div>
        <p>0</p>
      </div>
      <div>
        <p>12</p>
      </div>
      <div>
        <p>24</p>
      </div>
    </div>
  </div>
</body>

推荐答案

您主要遇到两个问题:

  1. 您正在将width:100%设置为包装器,并且这没有考虑边距,因此逻辑上您将发生溢出,并且由于主体是带有justify-content:center的弹性容器,因此边距会从两侧均等地溢出,这就是您认为的原因它不适用.
  2. 您正面临 flexbox的min-width约束,这迫使您设置width:100%认为这是件好事解决方案.相同的约束还可以防止元素缩小到您指定的100%以下(相关:为什么弹性商品仅限于父尺寸? )
  1. You are setting width:100% to the wrapper and this doesn't account for margin so you will logically have overflow and since the body is a flex container with justify-content:center the margin will overflow equally from both sides that's why you think it's not applied.
  2. You are facing the min-width constraint of flexbox which is forcing you to set width:100% thinking it's the good solution. This same constraint is also preventing the element from shrinking lower than the 100% you specified (related: Why is a flex item limited to parent size?)

要解决此问题,您需要从包装器中删除width:100%并考虑使用min-width:0.您还可以删除应用于.Lmin-width,并且需要考虑.R上的flex-shrink:0(或将其宽度替换为min-width)

To fix this you need to remove width:100% from wrapper and consider min-width:0 instead. You can also remove the min-width applied to .L and you need to consider flex-shrink:0 on .R (or replace its width by min-width)

body {
  background-color: #000;
  color: #FFF;
  display: flex;
  justify-content: center;
}

.wrapper {
  margin: 0 1.5rem;
  max-width: 40rem;
  min-width:0;
}

.fit_content_box {
  display: flex;
  align-items: center;
}

.L {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.R {
  margin-left: 1rem;
  flex-shrink:0;
  height: 1rem;
  width: 1rem;
  background-color: #FFF;
}

.overflow {
  display: flex;
  justify-content: space-between;
}

.overflow>div {
  width: 0;
  display: flex;
  justify-content: center;
}

<body>
  <div class="wrapper">
    <div class="fit_content_box">
      <p class="L">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

      <div class="R"></div>
    </div>

    <div class="overflow">
      <div>
        <p>0</p>
      </div>
      <div>
        <p>12</p>
      </div>
      <div>
        <p>24</p>
      </div>
    </div>
  </div>
</body>

如果您希望在文本量较少时使元素至少等于max-width,请添加flex-grow:1:

If you want the element to remain at least equal to max-width when there is a small amount of text add flex-grow:1:

body {
  background-color: #000;
  color: #FFF;
  display: flex;
  justify-content: center;
}

.wrapper {
  margin: 0 1.5rem;
  max-width: 40rem;
  min-width:0;
  flex-grow:1;
}

.fit_content_box {
  display: flex;
  align-items: center;
}

.L {
  flex-grow:1;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.R {
  margin-left: 1rem;
  flex-shrink:0;
  height: 1rem;
  width: 1rem;
  background-color: #FFF;
}

.overflow {
  display: flex;
  justify-content: space-between;
}

.overflow>div {
  width: 0;
  display: flex;
  justify-content: center;
}

<body>
  <div class="wrapper">
    <div class="fit_content_box">
      <p class="L">Lorem ipsum dolor sit e dolor sit e</p>

      <div class="R"></div>
    </div>

    <div class="overflow">
      <div>
        <p>0</p>
      </div>
      <div>
        <p>12</p>
      </div>
      <div>
        <p>24</p>
      </div>
    </div>
  </div>
</body>

为更好地说明(1),这是另一个几乎没有引起注意的边距溢出示例:

To better illustrate the (1) here is another example with overflowing margin that you can hardly notice:

.container {
  width:200px;
  margin:auto;
  display:flex;
  justify-content:center;
}
.box {
  height:50px;
  width:100%;
  background:red;
}

<div class="container">
  <div class="box" style="margin:0 5966px">a_long_text_to_avoid_the_shrink</div>
</div>

<div class="container">
  <div class="box">a_long_text_to_avoid_the_shrink</div>
</div>

您会看到我们有一个长文本,迫使我们的元素不缩小(最小宽度约束),该元素占据了全角,并且我们使内容居中.这将使边距像没有边距一样溢出.

You can see that we have a long text forcing our element to not shrink (the min-width constraint), the element is taking full width and we are centring the content. This will make the margin overflowing like if there is no margin.

如果您违反一条规则,那么您将看到页边距的效果.

If you break one rule then you will see the effect of the margin.

删除长文本:

.container {
  width:200px;
  margin:auto;
  display:flex;
  justify-content:center;
}
.box {
  width:100%;
  height:50px;
  background:red;
}

<div class="container">
  <div class="box" style="margin:0 5966px">a long text to avoid the shrink</div>
</div>

<div class="container">
  <div class="box">a long text to avoid the shrink</div>
</div>

删除中心点:

.container {
  width:200px;
  margin:auto;
  display:flex;
}
.box {
  width:100%;
  height:50px;
  background:red;
}

<div class="container">
  <div class="box" style="margin:0 5966px">a_long_text_to_avoid_the_shrink</div>
</div>

<div class="container">
  <div class="box">a_long_text_to_avoid_the_shrink</div>
</div>

每边留出不同的边距

.container {
  width:200px;
  margin:auto;
  display:flex;
  justify-content:center;
}
.box {
  width:100%;
  height:50px;
  background:red;
}

<div class="container">
  <div class="box" style="margin:0 500px 0 400px">a_long_text_to_avoid_the_shrink</div>
</div>

<div class="container">
  <div class="box">a_long_text_to_avoid_the_shrink</div>
</div>

(2)white-space正在创建最小宽度约束,以防止元素收缩.

(2) The white-space is creating the min-width contraint preventing the element from shrinking.

这里有一个例子来说明:

Here is an exmaple to illustrate:

.body {
  display: flex;
  justify-content: center;
  margin: 10px 100px;
  border: 2px solid red;
}

.wrapper {
  border: 1px solid;
  margin: 0 20px;
}
.box {
 display:flex;
}

The below is a logical behavior where the text will wrap and the margin are respected
<div class="body">
  <div class="wrapper">
    <div class="box">
      <div>some long text here some long text here some long text here some long text here</div>
    </div>
  </div>
</div>
Let's add white-space:nowrap. We add a min-width contraint since we said to the text to never wrap thus our flex element will not shrink and overflow.
<div class="body">
  <div class="wrapper">
    <div class="box">
      <div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
    </div>
  </div>
</div>
If we add width:100% we force its width to be the same as the container BUT the margin aren't included and are kept outside (the text will logically overflow)
<div class="body">
  <div class="wrapper" style="width:100%">
    <div class="box">
      <div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
    </div>
  </div>
</div>
Now if we add min-width:0 we remove the constaint of minimum sizing and we can see the margin again even if we keep width:100% because the element will shrink by default
<div class="body">
  <div class="wrapper" style="width:100%;min-width:0">
    <div class="box">
      <div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
    </div>
  </div>
</div>

诀窍是,我们将元素居中并在两侧应用相同的边距,这会产生边距倒塌的错觉,但这只是边距的均等溢出.

The trick is that we are centring the element and applying the same margin on both side which will create the illusion of a collapsing margin but it's a simple overflow of the margin from both sides equally.

让我们在一侧略微改变边距,以使另一侧略有偏移:

Let's change the margin slightly on one side to see a little offset to the other side:

.body {
  display: flex;
  justify-content: center;
  margin: 10px 100px;
  border: 2px solid red;
}

.wrapper {
  border: 1px solid;
  margin: 0 20px 0 40px;
}
.box {
 display:flex;
}

The below is a logical behavior where the text will wrap and the margin are respected
<div class="body">
  <div class="wrapper">
    <div class="box">
      <div>some long text here some long text here some long text here some long text here</div>
    </div>
  </div>
</div>
Let's add white-space:nowrap. We add a min-width contraint since we said to the text to never wrap thus our flex element will not shrink and overflow.
<div class="body">
  <div class="wrapper">
    <div class="box">
      <div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
    </div>
  </div>
</div>
If we add width:100% we force its width to be the same as the container BUT the margin aren't included and are kept outside (the text will logically overflow)
<div class="body">
  <div class="wrapper" style="width:100%">
    <div class="box">
      <div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
    </div>
  </div>
</div>
Now if we add min-width:0 we remove the constaint of minimum sizing and we can see the margin again even if we keep width:100% because the element will shrink by default
<div class="body">
  <div class="wrapper" style="width:100%;min-width:0">
    <div class="box">
      <div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
    </div>
  </div>
</div>

这篇关于具有“溢出:隐藏"的Flexbox子级;祖父母边际溢溢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆