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

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

问题描述

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

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

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

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

  .wrapper {>* {左边距:1.5rem;右边距:1.5rem;}} 

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

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

  body {背景颜色:#000;颜色:#FFF;显示:flex;证明内容:中心;}.wrapper {利润:0 1.5rem;最大宽度:40rem;宽度:100%;}.fit_content_box {显示:flex;align-items:居中;}.L {最小宽度:0;flex:1 0;溢出:隐藏;空白:nowrap;文字溢出:省略号;}.R {左边距:1rem;高度:1rem;宽度:1rem;背景颜色:#FFF;}.overflow {显示:flex;证明内容:间隔;}.overflow> div {宽度:0;显示:flex;证明内容:中心;}  

 < body>< div class ="wrapper">< div class ="fit_content_box">< p class ="L"& Lorem ipsum dolor就座,奉献了上等的礼遇,sius do了eiusmod tempor indicidunt ut laboure et dolore magna aliqua.尽量不要抽烟,不要因抽烟而锻炼.Duis aute iruredore in reprehenderit in voltate velit esse cillum dolore eu fugiat nulla pariatur.

p

p

p

p

p

p

和pp,pf,fp,fp,fp,fp,pb,pb,pb,p3,p3,p3,p3,p3,p3,p3,p3,p3,p3和p3的数量均不相同.< 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的flex容器:中心边距将从两侧均等地溢出,这就是为什么您认为未应用边距的原因.
  2. 您正面临 flexbox的 min-width 约束,这迫使您进行设置 width:100%认为这是一个很好的解决方案.相同的约束还可以防止元素缩小到您指定的100%以下(相关:为什么弹性商品仅限于父尺寸?)

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

  body {背景颜色:#000;颜色:#FFF;显示:flex;证明内容:中心;}.wrapper {利润:0 1.5rem;最大宽度:40rem;最小宽度:0;}.fit_content_box {显示:flex;align-items:居中;}.L {溢出:隐藏;空白:nowrap;文字溢出:省略号;}.R {左边距:1rem;flex-shrink:0;高度:1rem;宽度:1rem;背景颜色:#FFF;}.overflow {显示:flex;证明内容:间隔;}.overflow> div {宽度:0;显示:flex;证明内容:中心;}  

 < body>< div class ="wrapper">< div class ="fit_content_box">< p class ="L"& Lorem ipsum dolor就座,奉献了上等的礼遇,sius do了eiusmod tempor indicidunt ut laboure et dolore magna aliqua.尽量不要抽烟,不要因抽烟而锻炼.Duis aute irure革命性的假想中的多洛尔(Dolor in reprehenderit).

p

p

p

p

p

p

和pp,pf,fp,fp,fp,fp,pb,pb,pb,p3,p3,p3,p3,p3,p3,p3,p3,p3,p3和p3的数量均不相同.< 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>

如果您希望元素在文本量较少时至少保持等于最大宽度,请添加 flex-grow:1 :

  body {背景颜色:#000;颜色:#FFF;显示:flex;证明内容:中心;}.wrapper {利润:0 1.5rem;最大宽度:40rem;最小宽度:0;flex-grow:1;}.fit_content_box {显示:flex;align-items:居中;}.L {flex-grow:1;溢出:隐藏;空白:nowrap;文字溢出:省略号;}.R {左边距:1rem;flex-shrink:0;高度:1rem;宽度:1rem;背景颜色:#FFF;}.overflow {显示:flex;证明内容:间隔;}.overflow> div {宽度:0;显示:flex;证明内容:中心;}  

 < 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),这是另一个几乎没有引起注意的边距溢出示例:

  .container {宽度:200像素;保证金:自动;显示:flex;证明内容:中心;}.盒子 {高度:50px;宽度:100%;背景:红色;}  

 < 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 {宽度:200像素;保证金:自动;显示:flex;证明内容:中心;}.盒子 {宽度:100%;高度:50px;背景:红色;}  

 < div class ="container">< div class ="box" style ="margin:0 5966px">避免收缩的长文本</div></div>< div class ="container">< div class ="box">长文本,以避免缩小</div></div>  

删除中心点:

  .container {宽度:200像素;保证金:自动;显示:flex;}.盒子 {宽度:100%;高度:50px;背景:红色;}  

 < 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 {宽度:200像素;保证金:自动;显示:flex;证明内容:中心;}.盒子 {宽度:100%;高度:50px;背景:红色;}  

 < 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)空白正在创建最小宽度约束,以防止元素收缩.

这里有一个例子来说明:

  .body {显示:flex;证明内容:中心;边距:10px 100px;边框:2px纯红色;}.wrapper {边框:1px实线;边距:0 20px;}.盒子 {显示:flex;}  

 以下是符合逻辑的行为,其中文本将自动换行并遵守边距< div class ="body">< div class ="wrapper">< div class ="box">< div>这里一些长文本这里一些长文本这里一些长文本这里一些长文本</div></div></div></div>让我们添加空白:nowrap.我们添加了一个最小宽度的约束,因为我们对文本说过不要包裹,因此我们的flex元素不会收缩和溢出.< div class ="body">< div class ="wrapper">< div class ="box">< div style ="white-space:nowrap">这里的一些长文本这里的一些长文本这里的一些长文本这里的一些长文本</div></div></div></div>如果我们添加width:100%,我们将其宽度设置为与容器相同,但不包括边距,并且将其保留在外部(逻辑上文本将溢出)< div class ="body">< div class ="wrapper" style ="width:100%">< div class ="box">< div style ="white-space:nowrap">这里的一些长文本这里的一些长文本这里的一些长文本这里的一些长文本</div></div></div></div>现在,如果我们添加min-width:0,则消除了最小尺寸的约束,即使我们保持width:100%,我们也可以再次看到边距,因为元素默认情况下会缩小< div class ="body">< div class ="wrapper" style ="width:100%; min-width:0">< div class ="box">< div style ="white-space:nowrap">这里的一些长文本这里的一些长文本这里的一些长文本这里的一些长文本</div></div></div></div>  

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

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

  .body {显示:flex;证明内容:中心;边距:10px 100px;边框:2px纯红色;}.wrapper {边框:1px实线;边距:0 20px 0 40px;}.盒子 {显示:flex;}  

 以下是符合逻辑的行为,其中文本将自动换行并遵守边距< div class ="body">< div class ="wrapper">< div class ="box">< div>这里一些长文本这里一些长文本这里一些长文本这里一些长文本</div></div></div></div>让我们添加空白:nowrap.我们添加了一个最小宽度的约束,因为我们对文本说过不要包裹,因此我们的flex元素不会收缩和溢出.< div class ="body">< div class ="wrapper">< div class ="box">< div style ="white-space:nowrap">这里的一些长文本这里的一些长文本这里的一些长文本这里的一些长文本</div></div></div></div>如果我们添加width:100%,则我们将其宽度与容器相同,但不包括边距并且将其保留在外部(逻辑上文本将溢出)< div class ="body">< div class ="wrapper" style ="width:100%">< div class ="box">< div style ="white-space:nowrap">这里的一些长文本这里的一些长文本这里的一些长文本这里的一些长文本</div></div></div></div>现在,如果我们添加min-width:0,则消除了最小尺寸的约束,即使我们保持width:100%,我们也可以再次看到边距,因为元素默认情况下会缩小< div class ="body">< div class ="wrapper" style ="width:100%; min-width:0">< div class ="box">< div style ="white-space:nowrap">这里的一些长文本这里的一些长文本这里的一些长文本这里的一些长文本</div></div></div></div>  

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.

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;
    }
}

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>

解决方案

You mainly have two issues:

  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?)

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>

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>


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.

Remove the long text:

.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>

Remove the centring:

.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>

Make a different margin on each side

.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) 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子级具有&amp; quot;溢出:隐藏&amp; quot;祖父母边际溢溢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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