web-dev-qa-db-ja.com

Flexbox "overflow:hidden"オーバーフローの祖父母マージンを持つ子

サイドマージンを指定するラッパーに2つの子要素を入れ子にしようとしています。これにより、ディスプレイが狭く、max-widthディスプレイが広い場合。

2番目の子にはオーバーフローがありますが、最初の子はラッパーのコンテンツボックス内に厳密にとどまる必要があります。最初の子が削除されると、2番目の子は必要に応じて動作します。ただし、最初の子を追加すると、ラッパーのマージンが完全に無視され、ラッパーのコンテンツボックスが引き伸ばされ、2番目の子がそれに沿って分割されます。

申請中 overflow: hiddenをラッパーに追加すると、マージンの問題は修正されますが、2番目の子がクリップされます。最初の子にマージンを適用しても、新しいブロックのフォーマットコンテキストにあるため、親とともに折りたたまれませんでした。

これまでに見つけた唯一の回避策は、次のようにすることです。

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

ラッパーの最大幅を3rem増やしますが、ラッパーからその子にマージンをシフトする必要のない解決策があることを望んでいました。

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>
16
HybridCore

主に2つの問題があります。

  1. width:100%をラッパーに設定していて、これはマージンを考慮しないため、論理的にオーバーフローが発生します。本体はjustify-content:centerのフレックスコンテナーであるため、マージンは両側から等しくオーバーフローします。適用されていないと思う。
  2. あなたは直面しています flexboxのmin-width制約 これは、width:100%を設定することを強いられています。この同じ制約により、要素が指定した100%未満に縮小することも防止されます(関連: フレックスアイテムが親のサイズに制限されているのはなぜですか?

これを修正するには、ラッパーからwidth:100%を削除し、代わりにmin-width:0を検討する必要があります。 min-widthに適用された.Lを削除することもできます。flex-shrink:0.Rを検討する必要があります(またはその幅を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を追加します。

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)をわかりやすく説明するために、マージンがオーバーフローしている別の例を示します。

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

要素が縮小しないように強制する長いテキスト(最小幅の制約)があり、要素が全幅を取り、コンテンツを中央に配置していることがわかります。これにより、マージンがないかのようにマージンがオーバーフローします。

1つのルールを破ると、マージンの効果がわかります。

長いテキストを削除します。

.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は、要素の縮小を妨げる最小幅制約を作成しています。

以下に例を示します。

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

トリックは、要素を中央に配置し、両側に同じマージンを適用することです。これにより、折りたたまれたマージンの錯覚が作成されますが、それは、両側からのマージンの単純なオーバーフローです。

片側のマージンを少し変更して、反対側への少しのオフセットを見てみましょう。

.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>
6
Temani Afif

問題の原因はwhite-space: nowrapで、最初の子アイテム(.L)内のコンテンツ要素(.fit_content_box)に適用されているようです。

.L {
    border: solid 1px #FF0000;
    min-width: 0;
    flex: 1 0;
    overflow: hidden;
    white-space: nowrap;    <--- trouble maker
    text-overflow: Ellipsis;
}

そのコード行を削除すると、.wrapperのサイドマージンは期待どおりに機能します。

したがって、重要な質問は次のとおりです。

  • 孫(white-space)の.Lプロパティが祖父母(.wrapper)の横マージンを折りたたむのはなぜですか?
  • どうしてwhite-spaceプロパティが親(.fit_content_box)に適用されたときに側マージンを縮小しないのですか?
  • overflowプロパティが祖父母(.wrapper)に適用されたときに、visible以外の値を使用すると、マージンが孫( .L)?

あなたが書いた:

最初の子にマージンを適用しても、新しいブロックフォーマットコンテキストにあるため、親と共に折りたたまれませんでした。

実際、次の理由により、これは従来のマージン縮小の問題ではありません。

  1. 水平マージンについて話している 水平マージンは決して崩壊しない 、そして

  2. 私たちはフレックスコンテナー内で作業しており、 フレックスコンテナー内のマージンは折りたたまれません .

そのため、問題の完全な理解はブロック(またはフレックス)の書式設定コンテキストにあるかもしれませんが、親のマージンが崩れない理由はわかりません。

これは私がこの問題について得た限りです。時間があれば、もっと研究します。または、他の誰かがここから受け取ることができます。

4
Michael_B