The unpredictable wrapping habits of CSS

筅森魡賤 提交于 2021-01-28 10:11:29

问题


I got this simple setup with 3 elements in a flex-box. They are justified space-between. The middle .center element is set width 100%. For some reason the children elements (links) wrap, no matter how wide the window is.

What is the mechanism behind the result being that the links are being wrapped to the next line? There is enough space. Why isn't the .center div taking 100% of the left over space so they don't wrap. And how do I prevent this wrapping?

PS: I want the .center div to take 100% of the space in between.

<div class="header">
<h1>Title</h1>
<div class="center">
  <h1>
    TEST TEXT
  </h1>
</div>
<div class="nav">
    <a>A Link</a>
    <a>Another Link</a>
    <a>A Third Link</a>
</div>

.header {
    background: #ccc; 
    display: flex;
    justify-content: space-between;
}

.nav{

  width: fit-content;
}

.center{
  width:100%;
  background: lightblue;
  text-align: center;
}

div a{
  background: tomato;
}

See here: http://jsfiddle.net/vsx239v1/


回答1:


To understand why your nav elements are wrapping, you need to understand how flexbox works. I am going to explain this briefly with simple words but below you will find a reference with a complete and precise explanation.

Initially, you have set one item to take 100% of width and you kept everything else as default values. The important values used here are:

  • flex-wrap:nowrap (by default the flex items will not wrap)
  • flex-shrink:1 (by default the flex items will shrink)
  • min-width:auto (by default the flex items will not shrink past their minimum content size)

  • flex-grow:0 (by default the flex items will not grow)

In your case it's clear that we have overflow since one element is set to width:100% and the other to auto BUT the flexbox mechanism will shrink your element and will distribute the negative free space1 to the flex items in order to avoid the overflow.

In your case the first element h1 can no more shrink since its width is equal to its min-content so only your .center element and the nav will shrink and this will happen whataver the size of the browser is because we will always have negative free space since the .center element is set to width:100%.

If for example you set flex-shrink:0 to the nav element you won't have wrapping because you disable the shrink for this one and all the negative free space will be added to the .center element (this can be a fix, but not the best one)

.header {
    background: #ccc; 
    display: flex;
    justify-content: space-between;
}
h1 {
 font-size:11px;
}

.center{
  width:100%;
  background: lightblue;
  text-align: center;
}

.nav {
  flex-shrink:0;
}

div a{
  background: tomato;
}
<div class="header">
    <h1>Title</h1>
    <div class="center">
      <h1>
        TEST TEXT
      </h1>
    </div>
    <div class="nav">
        <a>A Link</a>
        <a>Another Link</a>
        <a>A Third Link</a>
    </div>
</div>

If you disable the shrink factor for all the elements we will have an overflow because the negative free space will not be distributed:

.header {
    background: #ccc; 
    display: flex;
    justify-content: space-between;
}
h1 {
 font-size:11px;
}

.center{
  width:100%;
  background: lightblue;
  text-align: center;
  flex-shrink:0;
}

.nav {
  flex-shrink:0;
}

div a{
  background: tomato;
}
<div class="header">
    <h1>Title</h1>
    <div class="center">
      <h1>
        TEST TEXT
      </h1>
    </div>
    <div class="nav">
        <a>A Link</a>
        <a>Another Link</a>
        <a>A Third Link</a>
    </div>
</div>

If you set flex-wrap:wrap on the container we will no more consider negative free space and shrinking as if there is no enough space the elements will wrap:

.header {
    background: #ccc; 
    display: flex;
    justify-content: space-between;
    flex-wrap:wrap;
}
h1 {
 font-size:11px;
}

.center{
  width:100%;
  background: lightblue;
  text-align: center;
}

div a{
  background: tomato;
}
<div class="header">
    <h1>Title</h1>
    <div class="center">
      <h1>
        TEST TEXT
      </h1>
    </div>
    <div class="nav">
        <a>A Link</a>
        <a>Another Link</a>
        <a>A Third Link</a>
    </div>
</div>

In order to fix all this you need to avoid having negative free space and make the total width to not exceed the container width. Instead of using width:100% you can consider flex-grow property that will allow an item to grow in order to fill the free space.

.header {
    background: #ccc; 
    display: flex;
    justify-content: space-between;
}
h1 {
 font-size:11px;
}

.center{
  flex-grow:1;
  background: lightblue;
  text-align: center;
}
div a{
  background: tomato;
}
<div class="header">
    <h1>Title</h1>
    <div class="center">
      <h1>
        TEST TEXT
      </h1>
    </div>
    <div class="nav">
        <a>A Link</a>
        <a>Another Link</a>
        <a>A Third Link</a>
    </div>
</div>

Here is a good link to better understand the flexbox algorithm considering all the properties : https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Controlling_Ratios_of_Flex_Items_Along_the_Main_Ax


(1) Negative free space: We have negative free space when the natural size of the items adds up to larger than the available space in the flex container.




回答2:


You need to use flex-grow: 1 instead of width: 100%.

Also width: fit-content; is useless here:

.header {
    background: #ccc; 
    display: flex;
    justify-content: space-between;
}

.center{
  flex-grow: 1;
  background: lightblue;
  text-align: center;
}

div a{
  background: tomato;
}
<div class="header">
<h1>Title</h1>
<div class="center">
  <h1>
    TEST TEXT
  </h1>
</div>
<div class="nav">
    <a>A Link</a>
    <a>Another Link</a>
    <a>A Third Link</a>
</div>



回答3:


Change 100% to auto;

.center{
 width:auto;
  background: lightblue;
  text-align: center;
}

CSS will always follow your 100% width, making the title and the link adjust, thus the wrapping.



来源:https://stackoverflow.com/questions/50458282/the-unpredictable-wrapping-habits-of-css

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!