Заставить гибкий элемент заполнять доступное пространство при удалении других дочерних элементов - PullRequest
1 голос
/ 08 мая 2020

У меня есть несколько дочерних элементов внутри родителя с display: flex и flex-direction: column.

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

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

.parent {
  border: black 1px solid;
  height: 260px;
  display: flex;
  flex-direction: column;
}

.child {
  padding: 5px;
}

#table {
  display: table;
  height: 160px;
}

.tr {
  display: table-row;
  padding: 5px;
}

.td {
  display: table-cell;
  padding: 5px;
  width: 150px;
  border: #000000 solid 1px;
  margin: 5px;
}
<div class="parent">
  <div class="child">
    Child1
  </div>
  <div class="child">
    Child2
  </div>
  <div class="child">
    Child3
  </div>
  <div class="child">
    <div id="table">
      <div class="tr">
        <div class="td">Row 1, <br />Column 1</div>
        <div class="td">Row 1, Column 2</div>
        <div class="td" style="background:#888888;"></div>
      </div>
      <div class="tr">
        <div class="td">Row 2, <br />Column 1</div>

        <div class="td" style="background:#888888;"></div>
        <div class="td">Row 2, Column 2</div>
      </div>
    </div>
  </div>
</div>

CodeSandbox

В настоящее время, если мы удаляем Child2, таблица перемещается вверх, но высота не регулируется. У содержимого таблицы также есть свиток.

Ответы [ 4 ]

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

Используйте свойство Css flex-grow: 0; на .child Css. Только для таблицы, это будет отменено настройкой в ​​предложении .child:last-child.

function toggleChild ( eve ) {
  let s_idButton = (eve.target.tagName.toLowerCase() === "button") ? eve.target.id : eve.target.parentNode.id
    , s_idChild = s_idButton.replace("b", "c")
    , e_child = document.querySelector(`#${s_idChild}`)
    , s_state = e_child.style.display
    ;

e_child.style.display = (s_state === "none") ? "flex" : "none";
  document.querySelector(`#${s_idButton} > span`).textContent = (e_child.style.display === "none") ? "Show" : "Hide";
} // toggleChild

function ready ( eve ) {
  Array.from(document.querySelectorAll('button'))
    .forEach ( (pe_b) => { pe_b.addEventListener( 'click', toggleChild ); } );
} // ready

window.addEventListener( 'load', ready );
.parent {
   border: black 1px solid;
   height: 260px;
   display: flex;
   flex-direction: column;
 }

 .child {
   padding: 5px;
   flex-grow: 0; /* helps in consuming available space */
 }

 .child:last-child {
   flex-grow: 1; /* consumes available space */

   /* give flexibility to child (table element) */
   display: flex;
   flex-direction: column;
 }

 #table {
   display: table;
   /* height: 160px; */
   height: 100%; /* full height; will shrink to fit container because of
                    default flex-shrink: 1 */
 }

 .tr {
   display: table-row;
   padding: 5px;
 }

 .td {
   display: table-cell;
   padding: 5px;
   width: 150px;
   border: #000000 solid 1px;
   margin: 5px;
 }
<div class="parent">
  <div id="c1" class="child">
    Child1
  </div>
  <div id="c2" class="child">
    Child2
  </div>
  <div id="c3" class="child">
    Child3
  </div>
  <div id="c4" class="child">
    <div id="table">
      <div class="tr">
        <div class="td">Row 1, <br />Column 1</div>
        <div class="td">Row 1, Column 2</div>
        <div class="td" style="background:#888888;"></div>
      </div>
      <div class="tr">
        <div class="td">Row 2, <br />Column 1</div>

        <div class="td" style="background:#888888;"></div>
        <div class="td">Row 2, Column 2</div>
      </div>
    </div>
  </div>
</div>

<button id="b1"><span>Hide</span> Child #1</button>
<button id="b2"><span>Hide</span> Child #2</button>
<button id="b3"><span>Hide</span> Child #3</button>

Примечание

Я (полностью) неправильно понял требования OP в первом ответ (прочитав слишком быстро ...). Решение исправлено.

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

Высота стола не может регулироваться сама по себе, поскольку вы установили фиксированную высоту.

Вы можете использовать justify-content: space-around или между родительским элементом, или вы можете добавить flex: 1 к элементам .child, чтобы элементы оставались разнесенными.

Вы можете установить высоту стола 100%, чтобы заполнить пространство. Вам также, вероятно, придется убрать со стола обертку .child.

.parent {
  border: black 1px solid;
  height: 400px;
  display: flex;
  flex-direction: column;
}

.child {
  padding: 5px;
  flex: 1;
}
#table {
  display: table;
  height: 100%;
  /* height:160px; */
}
.tr {
  display: table-row;
  padding: 5px;
}
.td {
  display: table-cell;
  padding: 5px;
  width: 150px;
  border: #000000 solid 1px;
  margin: 5px;
}
<div class="parent">
  <div class="child">
    Child1
  </div>
  <div class="child">
    Child2
  </div>
  <div class="child">
    Child3
  </div>

  <div id="table">
    <div class="tr">
      <div class="td">Row 1, <br />Column 1</div>
      <div class="td">Row 1, Column 2</div>
      <div class="td" style="background:#888888;"></div>
    </div>
    <div class="tr">
      <div class="td">Row 2, <br />Column 1</div>

      <div class="td" style="background:#888888;"></div>
      <div class="td">Row 2, Column 2</div>
    </div>
  </div>
</div>
0 голосов
/ 08 мая 2020

Добавив flex: 0 1 100%; к элементам .child, вы можете заставить их занять все доступное пространство, поэтому div.child, содержащий таблицу, займет всю высоту родительского элемента, если нет других .child div. Кроме того, ваша таблица имеет фиксированную высоту 160px, чтобы сделать ее такой же большой, как и родительская, измените ее на 100%. Или установите min-height из 100%.

.parent {
  border: black 1px solid;
  height: 260px;
  display: flex;
  flex-direction: column;
}

.child {
  padding: 5px;
  flex: 0 1 100%; /* force children to take up as much space as possible */
}

#table {
  display: table;
  height: 100%; /* make it as big as its parent */
}

.tr {
  display: table-row;
  padding: 5px;
}

.td {
  display: table-cell;
  padding: 5px;
  width: 150px;
  border: #000000 solid 1px;
  margin: 5px;
}
<div class="parent">
  <div class="child">
    <div id="table">
      <div class="tr">
        <div class="td">Row 1, <br />Column 1</div>
        <div class="td">Row 1, Column 2</div>
        <div class="td" style="background:#888888;"></div>
      </div>
      <div class="tr">
        <div class="td">Row 2, <br />Column 1</div>

        <div class="td" style="background:#888888;"></div>
        <div class="td">Row 2, Column 2</div>
      </div>
    </div>
  </div>
</div>
0 голосов
/ 08 мая 2020

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

 .parent {
   border: black 1px solid;
   height: 260px;
   display: flex;
   flex-direction: column;
 }

 .child {
   padding: 5px;
 }
 
 .child:last-child {
   flex-grow: 1; /* consume available space */
   
   /* give flexibility to child (table element) */
   display: flex;
   flex-direction: column;
 }

 #table {
   display: table;
   /* height: 160px; */
   height: 100%; /* full height, but will not overflow container because of
                    default flex-shrink: 1 */
 }

 .tr {
   display: table-row;
   padding: 5px;
 }

 .td {
   display: table-cell;
   padding: 5px;
   width: 150px;
   border: #000000 solid 1px;
   margin: 5px;
 }
<div class="parent">
  <div class="child">Child1</div>
  <div class="child">Child2</div>
  <div class="child">Child3</div>
  <div class="child">
    <div id="table">
      <div class="tr">
        <div class="td">Row 1, <br />Column 1</div>
        <div class="td">Row 1, Column 2</div>
        <div class="td" style="background:#888888;"></div>
      </div>
      <div class="tr">
        <div class="td">Row 2, <br />Column 1</div>
        <div class="td" style="background:#888888;"></div>
        <div class="td">Row 2, Column 2</div>
      </div>
    </div>
  </div>
</div>

<hr>

<div class="parent">
  <div class="child">Child1</div>
  <div class="child">Child2</div>
  <div class="child">
    <div id="table">
      <div class="tr">
        <div class="td">Row 1, <br />Column 1</div>
        <div class="td">Row 1, Column 2</div>
        <div class="td" style="background:#888888;"></div>
      </div>
      <div class="tr">
        <div class="td">Row 2, <br />Column 1</div>
        <div class="td" style="background:#888888;"></div>
        <div class="td">Row 2, Column 2</div>
      </div>
    </div>
  </div>
</div>

<hr>

<div class="parent">
  <div class="child">Child1</div>
  <div class="child">
    <div id="table">
      <div class="tr">
        <div class="td">Row 1, <br />Column 1</div>
        <div class="td">Row 1, Column 2</div>
        <div class="td" style="background:#888888;"></div>
      </div>
      <div class="tr">
        <div class="td">Row 2, <br />Column 1</div>
        <div class="td" style="background:#888888;"></div>
        <div class="td">Row 2, Column 2</div>
      </div>
    </div>
  </div>
</div>
...