Изгиб направления и изгиб упаковки на контейнере приводит к дополнительному пространству в flex-элемент - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть следующий код:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <style>
      *,
      *:before,
      *:after {
        box-sizing: border-box;
      }

      .list {
        line-height: 22px;
      }

      .list:before,
      list:after {
        display: table;
        content: "";
      }

      .list:after {
        clear: both;
      }

      .right-item {
        float: left;
        width: 50px;
        height: 50px;
        display: table;
        background-color: blue;
        border: 1px solid green;
        display: table;
        float: left;
        width: 50px;
        height: 50px;
        margin-right: 8px;
        margin-bottom: 8px;
        text-align: center;
        vertical-align: top;
      }

      .wrapper {
        display: inline-block;
        width: 100%;
      }

      .wrapper:before,
      .wrapper:after {
        content: "";
        display: table;
      }

      .wrapper:after {
        clear: both;
      }

      .floated-item {
        float: left;
        width: 50px;
        height: 50px;
        background-color: red;
        border: 1px solid black;
        margin: 0 8px 8px 0;
      }

      .flex-item {
        flex: auto;
        max-width: 100%;
      }

      .flex-container {
        display: flex;
        align-items: center;
        min-height: 15px;
        position: relative;
        align-items: center;
      }

      .flex-column {
        display: flex;
        flex-direction: column;
        flex-grow: 1;
        min-height: 1px;
        position: relative;
        max-width: 100%;
      }

      .outer-wrapper {
        display: flex;
        flex-flow: column wrap;
        margin-bottom: 24px;
        vertical-align: top;
      }

      .label {
        flex-grow: 0;
        overflow: hidden;
        display: inline-block;
        position: relative;
        max-width: 100%;
        min-height: 1px;
      }

      .label-inner {
        height: auto;
        position: relative;
        display: inline-flex;
        align-items: center;
        margin: 0;
      }
    </style>
  </head>
  <body>
    <form>
      <div class="outer-wrapper">
        <div class="label"><label class="label-inner">Label</label></div>
        <div class="flex-column">
          <div class="flex-container">
            <div class="flex-item">
              <span class="wrapper">
                <div class="list">
                  <div class="floated-item">
                    <span><div class="floated-item"></div></span>
                  </div>
                  <div class="floated-item">
                    <span><div class="floated-item"></div></span>
                  </div>
                  <div class="floated-item">
                    <span><div class="floated-item"></div></span>
                  </div>
                  <div class="floated-item">
                    <span><div class="floated-item"></div></span>
                  </div>
                  <div class="floated-item">
                    <span><div class="floated-item"></div></span>
                  </div>
                </div>
                <div class="right-item"></div>
              </span>
            </div>
          </div>
        </div>
      </div>
    </form>
    <div>content</div>
  </body>
</html>

Сначала я понятия не имел, что происходит с добавленным дополнительным пространством. После длительной отладки проблема в том, что (по крайней мере, кажется, что он исправляет дополнительное пространство, но, может быть, что-то еще вызывает его, я не знаю), что flex-wrap: wrap используется на .outer-wrapper. Когда я установил его на flex-wrap: nowrap, он исправляет дополнительное пространство.

Я прошел спецификацию Flexbox, а также модель визуального форматирования CSS spe c, касающуюся использования float, контекстов форматирования. и др. c. но я до сих пор не знаю, в чем может быть проблема.

Ответы [ 3 ]

0 голосов
/ 03 мая 2020

В качестве элемента контейнера <span class="wrapper">, если установлено отображение: flex, он каким-то образом вычисляет его высоту как сумму высот class="list" и class="right-item". Он каким-то образом учитывает, какую высоту взяли бы элементы class="list", если бы в нем не было элементов с плавающей запятой (или на них был бы применен метод clearfix hack). Я уверен в этом, как будто я изменяю высоту синего поля на 20 пикселей, высота внизу также уменьшается (это не всегда вдвое больше, чем фактическая высота содержимого).

Фрагмент кода с элементами float в class='list' div

.right-item {
  animation: myfirst 5s linear infinite alternate;
}

@keyframes myfirst {
  0% {
    height: 50px;
  }
  100% {
    height: 10px;
  }
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <style>
    *,
    *:before,
    *:after {
      box-sizing: border-box;
    }
    
    .list {
      line-height: 22px;
    }
    
    .list:before,
    list:after {
      display: table;
      content: "";
    }
    
    .list:after {
      clear: both;
    }
    
    .right-item {
      float: left;
      width: 50px;
      height: 50px;
      display: table;
      background-color: blue;
      border: 1px solid green;
      display: table;
      float: left;
      width: 50px;
      height: 50px;
      margin-right: 8px;
      margin-bottom: 8px;
      text-align: center;
      vertical-align: top;
    }
    
    .wrapper {
      display: inline-block;
      width: 100%;
    }
    
    .wrapper:before,
    .wrapper:after {
      content: "";
      display: table;
    }
    
    .wrapper:after {
      clear: both;
    }
    
    .floated-item {
      float: left;
      width: 50px;
      height: 50px;
      background-color: red;
      border: 1px solid black;
      margin: 0 8px 8px 0;
    }
    
    .flex-item {
      flex: auto;
      max-width: 100%;
    }
    
    .flex-container {
      display: flex;
      align-items: center;
      min-height: 15px;
      position: relative;
      align-items: center;
    }
    
    .flex-column {
      display: flex;
      flex-direction: column;
      flex-grow: 1;
      min-height: 1px;
      position: relative;
      max-width: 100%;
    }
    
    .outer-wrapper {
      display: flex;
      flex-flow: column wrap;
      margin-bottom: 24px;
      vertical-align: top;
    }
    
    .label {
      flex-grow: 0;
      overflow: hidden;
      display: inline-block;
      position: relative;
      max-width: 100%;
      min-height: 1px;
    }
    
    .label-inner {
      height: auto;
      position: relative;
      display: inline-flex;
      align-items: center;
      margin: 0;
    }
  </style>
</head>

<body>
  <form>
    <div class="outer-wrapper">
      <div class="label"><label class="label-inner">Label</label></div>
      <div class="flex-column">
        <div class="flex-container">
          <div class="flex-item">
            <span class="wrapper">
                <div class="list">
                  <div class="floated-item">
                    <span><div class="floated-item"></div></span>
          </div>
          <div class="floated-item">
            <span><div class="floated-item"></div></span>
          </div>
          <div class="floated-item">
            <span><div class="floated-item"></div></span>
          </div>
          <div class="floated-item">
            <span><div class="floated-item"></div></span>
          </div>
          <div class="floated-item">
            <span><div class="floated-item"></div></span>
          </div>
        </div>
        <div class="right-item"></div>
        </span>
      </div>
    </div>
    </div>
    </div>
  </form>
  <div>content</div>
</body>

</html>

Фрагмент кода с элементами, которые плавают внутри class="list" div, но к ним применен хак clearfix (показать, какая высота это на самом деле должно было занять и, кажется, вызывает дополнительное пространство в приведенном выше фрагменте)

.clearfix::after {
  content: "";
  clear: both;
  display: table;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <style>
    *,
    *:before,
    *:after {
      box-sizing: border-box;
    }
    
    .list {
      line-height: 22px;
    }
    
    .list:before,
    list:after {
      display: table;
      content: "";
    }
    
    .list:after {
      clear: both;
    }
    
    .right-item {
      float: left;
      width: 50px;
      height: 50px;
      display: table;
      background-color: blue;
      border: 1px solid green;
      display: table;
      float: left;
      width: 50px;
      height: 50px;
      margin-right: 8px;
      margin-bottom: 8px;
      text-align: center;
      vertical-align: top;
    }
    
    .wrapper {
      display: inline-block;
      width: 100%;
    }
    
    .wrapper:before,
    .wrapper:after {
      content: "";
      display: table;
    }
    
    .wrapper:after {
      clear: both;
    }
    
    .floated-item {
      float: left;
      width: 50px;
      height: 50px;
      background-color: red;
      border: 1px solid black;
      margin: 0 8px 8px 0;
    }
    
    .flex-item {
      flex: auto;
      max-width: 100%;
    }
    
    .flex-container {
      display: flex;
      align-items: center;
      min-height: 15px;
      position: relative;
      align-items: center;
    }
    
    .flex-column {
      display: flex;
      flex-direction: column;
      flex-grow: 1;
      min-height: 1px;
      position: relative;
      max-width: 100%;
    }
    
    .outer-wrapper {
      display: flex;
      flex-flow: column wrap;
      margin-bottom: 24px;
      vertical-align: top;
    }
    
    .label {
      flex-grow: 0;
      overflow: hidden;
      display: inline-block;
      position: relative;
      max-width: 100%;
      min-height: 1px;
    }
    
    .label-inner {
      height: auto;
      position: relative;
      display: inline-flex;
      align-items: center;
      margin: 0;
    }
  </style>
</head>

<body>
  <form>
    <div class="outer-wrapper">
      <div class="label"><label class="label-inner">Label</label></div>
      <div class="flex-column">
        <div class="flex-container">
          <div class="flex-item">
            <span class="wrapper">
                <div class="list clearfix">
                  <div class="floated-item">
                    <span><div class="floated-item"></div></span>
          </div>
          <div class="floated-item">
            <span><div class="floated-item"></div></span>
          </div>
          <div class="floated-item">
            <span><div class="floated-item"></div></span>
          </div>
          <div class="floated-item">
            <span><div class="floated-item"></div></span>
          </div>
          <div class="floated-item">
            <span><div class="floated-item"></div></span>
          </div>
        </div>
        <div class="right-item"></div>
        </span>
      </div>
    </div>
    </div>
    </div>
  </form>
  <div>content</div>
</body>

</html>

Я постараюсь найти справку о том, почему именно это происходит, и отредактировать этот пост на случай, если я его найду. Но, в моем понимании, flex и float очень противоречат друг другу с точки зрения их поведения. В случае, если вы обязаны использовать их вместе, вы должны знать, почему, что, как и т.д. c. обоих из них в деталях. Или просто воздержитесь от использования их обоих вместе.

Кроме того, одна важная вещь в приведенном выше коде заключается в том, что вы используете display: flex, а затем flex-flow: column wrap; на outer-wrapper div только с одним ребенком элемент в этом. Я не вижу смысла добавлять эти стили. Поскольку внутри outer-wrapper div есть только 1 элемент, он будет вести себя так же, только без этих стилей. Попробуйте использовать дисплей: гибкий только при необходимости.

0 голосов
/ 07 мая 2020

Это сначала связано с flex-column. flex-direction делает следующий div (.flex-item), чтобы занять всю ширину. Если вы удалите flex-direction:column в своем коде, последний div (right-item) автоматически попадет на следующую строку.

Также, если вы укажете width:100% для flex-столбца, пространство исчезнет, ​​так как контейнер уверен, что он может вместить все в одну строку.

Тогда вы дадите свой .flex-item class flex:auto witch является flex-basis свойством и согласно css -трюкам означает, что дополнительное пространство распределяется на основе его значения flex-grow. (если вы удалите это из своего кода, ваш right-item также будет на следующей строке, так как он займет только необходимое место для вашей обертки, и это не изменится).

После этого вы укажете вам обертка * должна иметь ширину 100% (если вы просто удалите width:100% из вашего класса .wrapper, не касаясь flex-direction или flex: auto, произойдет то же самое (right-item будет на следующем line).

Суть в том, что есть много причин для гибкого контейнера думать, что вам нужно 2 строки, чтобы поместиться во все ваши элементы. Но из-за flex-direction, flex:auto и width:100% Вы заставляете все это в одну строку.

Так что это может показаться странным, но когда вы комбинируете много типов отображения (flex, inline и table) и вы слишком полагаетесь на контейнеры, чтобы рассчитать их размеры, это происходит .

0 голосов
/ 30 апреля 2020

Из-за display: inline-block присвоено классу .wrapper.

Измените display: inline-block на display: flex, это должно решить проблему.

*,
*:before,
*:after {
  box-sizing: border-box;
}

.list {
  line-height: 22px;
}

.list:before,
list:after {
  display: table;
  content: "";
}

.list:after {
  clear: both;
}

.right-item {
  float: left;
  width: 50px;
  height: 50px;
  display: table;
  background-color: blue;
  border: 1px solid green;
  display: table;
  float: left;
}

/* changed here */
.wrapper {
  display: flex;
  width: 100%;
}

.wrapper:before,
.wrapper:after {
  content: "";
  display: table;
}

.wrapper:after {
  clear: both;
}

.floated-item {
  float: left;
  width: 50px;
  height: 50px;
  background-color: red;
  border: 1px solid black;
  margin: 0 8px 8px 0;
}

.flex-item {
  flex: auto;
  max-width: 100%;
}

.flex-container {
  display: flex;
  align-items: center;
  min-height: 15px;
  position: relative;
  align-items: center;
}

.flex-column {
  display: flex;
  flex-direction: column;
  flex-grow: 1;
  min-height: 1px;
  position: relative;
  max-width: 100%;
}

.outer-wrapper {
  display: flex;
  flex-flow: column wrap;
  margin-bottom: 24px;
  vertical-align: top;
}

.label {
  flex-grow: 0;
  overflow: hidden;
  display: inline-block;
  position: relative;
  max-width: 100%;
  min-height: 1px;
}

.label-inner {
  height: auto;
  position: relative;
  display: inline-flex;
  align-items: center;
  margin: 0;
}
<div class="outer-wrapper">
  <div class="label"><label class="label-inner">Label</label></di <div class="flex-column">
    <div class="flex-container">
      <div class="flex-item">
        <span class="wrapper">
                <div class="list">
                  <div class="floated-item">
                    <span><div class="floated-item"></div></span>
      </div>
      <div class="floated-item">
        <span><div class="floated-item"></div></span>
      </div>
      <div class="floated-item">
        <span><div class="floated-item"></div></span>
      </div>
      <div class="floated-item">
        <span><div class="floated-item"></div></span>
      </div>
      <div class="floated-item">
        <span><div class="floated-item"></div></span>
      </div>
    </div>
    <div class="right-item"></div>
    </span>
  </div>
</div>
</div>
</div>
<div>content</div>

Примечание: высота .outer-wrapper изменяется при применении inline-block к .wrapper.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...