Почему flex-direction: column устраняет эффект flex: 1? - PullRequest
1 голос
/ 25 сентября 2019

Я создаю представление списка с фиксированным заголовком и хотел бы, чтобы тело представления списка расширялось до нижней части страницы и по-прежнему допускало переполнение по оси Y.На практике я смог заставить все работать, кроме того, что я не пытался расширить его до нижней части страницы, пока не решил поместить его на страницу.До этого я использовал фиксированные высоты, и все работало, как ожидалось.После того как я поместил его на свою страницу, представление списка затем вышло далеко за пределы страницы и вместо того, чтобы простираться до нижней части страницы и иметь переполнение внутри тела, это просто вызвало переполнение страницы.

Теперь я провел некоторое исследование по этой теме и несколько раз успешно внедрял решение flexbox в других своих веб-стилях.Тем не менее, это оказывается немного болезненным, и я не уверен, что полностью понял концепцию этого подхода.

Мне удалось создать минимальный пример проблемы, и в ходе этого процессаМне удалось выяснить, что одна строка в моем CSS, которая вызывает проблемы, - flex-direction: column в классе .container.Когда я удаляю эту строку, представление списка распространяется только на нижнюю часть страницы, и переполнение происходит в представлении списка.Однако, добавление его обратно приведет к тому, что представление списка расширит страницу.

var testTable = document.getElementById("test-table");
for (let i = 0; i < 150; i++)
  testTable.innerHTML += '<tr><td>DATA ' + (i + 1) + '</td><td>' + i + '</td></tr>';
html,
body {
  margin: 0;
  height: 100%;
  background-color: #fc3;
  background-image: linear-gradient(45deg, #fc3, #f33);
}

.container {
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  height: 100%;
}

.test-header {
  height: 150px;
  background-color: #fff3;
}

.test-body {
  display: flex;
  flex-direction: column;
  background-color: #33f5;
}

.test-body table {
  width: 100%;
  table-layout: fixed;
}

.test-body-header {
  background-color: #fff5;
}

.test-body-body {
  flex: 1;
  overflow-y: auto;
}
<div class="container">
  <div class="test-header">A</div>
  <div class="test-body">
    <div class="test-body-header">
      <table>
        <tr>
          <th>Data ID</th>
          <th>Value</th>
        </tr>
      </table>
    </div>
    <div class="test-body-body">
      <table id="test-table"></table>
    </div>
  </div>
</div>

Я добавил немного JavaScript, чтобы уменьшить количество разметки, необходимой для воспроизведения проблемы.


Почемудобавив flex-direction: column к моему .container классу, вызвать этот нежелательный эффект?Кроме того, поскольку я явно установил высоту моего .test-header класса на 150px, почему эта высота не отображается?Связаны ли два эффекта?

Ответы [ 2 ]

1 голос
/ 25 сентября 2019

Просто внесите две незначительные корректировки, и все готово.

1.Проблема с заголовком

Поскольку я явно установил высоту моего .test-header класса на 150px, почему эта высота не отображается?

Ваш заголовок(.test-header) не учитывает 150px, поскольку для flex-shrink по умолчанию установлено значение 1 (включено).Это означает, что гибкий элемент может сжиматься ниже своего первоначального размера, чтобы предотвратить переполнение контейнера.

Поскольку его брат (.test-body) потребляет всю оставшуюся высоту в контейнере, а затем больше,заголовок сжимается настолько сильно, насколько это возможно.

Вам необходимо отключить flex-shrink.

Вместо этого:

.test-header {
   height: 150px;
 }

Попробуйте это:

.test-header {
   height: 150px;
   flex-shrink: 0;
 }

Или, что еще лучше, и в соответствии со спецификацией, это:

.test-header {
   flex: 0 0 150px; /* fg, fs, fb */
 }

7.2.Компоненты гибкости

Авторам рекомендуется контролировать гибкость с помощью сокращения flex, а не напрямую с его свойствами, так как сокращение корректно сбрасывает любые неуказанные компоненты для удовлетворения общего использования.


2.Проблема с прокруткой

Почему добавление flex-direction: column в мой класс .container вызывает нежелательный эффект?

Элемент flex по умолчанию не может быть меньше егосодержимое вдоль главной оси, которая является вертикальной в flex-direction: column ( полное объяснение ).

Это означает, что для вашего элемента содержимого (.test-body) установлено значение min-height: auto, что предотвращаетусловие переполнения, так как элемент просто расширяется, чтобы вместить больше содержимого, и нет никакой причины для вертикальной полосы прокрутки.

Этот параметр необходимо переопределить.Добавьте этот код:

.test-body {
  min-height: 0; /* new */
  display: flex;
  flex-direction: column;
}

var testTable = document.getElementById("test-table");
for (let i = 0; i < 150; i++)
  testTable.innerHTML += '<tr><td>DATA ' + (i + 1) + '</td><td>' + i + '</td></tr>';
.container {
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  height: 100vh;
}

.test-header {
  flex: 0 0 150px; /* adjustment */
  background-color: #fff3;
}

.test-body {
  min-height: 0; /* new */
  display: flex;
  flex-direction: column;
  background-color: #33f5;
}

.test-body table {
  width: 100%;
  table-layout: fixed;
}

.test-body-header {
  background-color: #fff5;
}

.test-body-body {
  flex: 1;
  overflow-y: auto;
}

body {
  margin: 0;
  background-color: #fc3;
  background-image: linear-gradient(45deg, #fc3, #f33);
}
<div class="container">
  <div class="test-header">A</div>
  <div class="test-body">
    <div class="test-body-header">
      <table>
        <tr>
          <th>Data ID</th>
          <th>Value</th>
        </tr>
      </table>
    </div>
    <div class="test-body-body">
      <table id="test-table"></table>
    </div>
  </div>
</div>
1 голос
/ 25 сентября 2019

, чтобы позволить дочернему элементу flex прокручиваться, вам нужно установить переполнение: скрыто на родительском элементе, иначе переполнение остается видимым, и дочерний элемент не будет обращать внимания на родителя высоты.

Ваш CSS повторно

var testTable = document.getElementById("test-table");
for (let i = 0; i < 150; i++)
  testTable.innerHTML += '<tr><td>DATA ' + (i + 1) + '</td><td>' + i + '</td></tr>';
html,
body {
  margin: 0;
  height: 100%;
  background-color: #fc3;
  background-image: linear-gradient(45deg, #fc3, #f33);
}

.container {
  display: flex;
  flex-direction: column;
  height: 100%;
  /* overflow rule unnecessary yet here */
}

.test-header {
  height: /*1*/50px;/* down to fifty for the small snippet it stands along*/
  background-color: #fff3;
}

.test-body {
  flex: 1;/* tel it to use all free space */
  overflow: hidden;/* only free space, no more */
  display: flex;
  flex-direction: column;
  background-color: #33f5;
}

.test-body table {
  width: 100%;
  table-layout: fixed;
}

.test-body-header {
  background-color: #fff5;
}

.test-body-body {
  flex: 1;
  overflow: auto;/* let me scroll */
}
<div class="container">
  <div class="test-header">A</div>
  <div class="test-body">
    <div class="test-body-header">
      <table>
        <tr>
          <th>Data ID</th>
          <th>Value</th>
        </tr>
      </table>
    </div>
    <div class="test-body-body">
      <table id="test-table"></table>
    </div>
  </div>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...