Ensure that the flex item expands to occupy the vacant space left when other child elements are deleted

I am facing an issue with multiple children inside a parent container that has the CSS properties display: flex and flex-direction: column.

There is a toggle button on the webpage which removes one of the children when clicked.

The problem I need to solve is making sure that the table height expands to fill all the remaining space when any child is removed.

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

After removing Child2, the table shifts up but doesn't adjust its height, causing scrollbars to appear within the table content.

Answer №1

Allow the items to be flexible in order to expand and fill up the available space.

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

 .child {
   padding: 5px;
 }
 
 .child:last-child {
   flex-grow: 1; /* consume available space */
   
   /* provide 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>

Answer №2

Applying flex: 0 1 100%; to the .child elements will make them occupy all available space, ensuring that the div.child containing the table will extend to the full height of its parent if there are no other .child divs present. Additionally, since your table currently has a fixed height of 160px, you can adjust it to match its parent by setting it to 100% or specifying a min-height of 100%.

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

.child {
  padding: 5px;
  flex: 0 1 100%; /* ensure children expand fully */
}

#table {
  display: table;
  height: 100%; /* match parent size */
}

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

Answer №3

The table height cannot automatically adjust because you have specified a fixed height.

To create spacing between items, you can use justify-content: space-around or justify-content: space-between on the parent element. Additionally, adding flex: 1 to the .child elements will help keep the items spaced out evenly.

If you want the table to fill the available space, you can set its height to 100%. In this case, you may need to remove the .child wrapper from the table structure.

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

.child {
  padding: 5px;
  flex: 1;
}
#table {
  display: table;
  height: 100%;
}
.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>

Answer №4

Utilize the Css attribute flex-grow: 0; on the .child Css. When it comes to the table, this will be overridden by the configuration in the .child:last-child clause.

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>

Note

I misinterpreted OP's needs in my initial response (due to reading too quickly ...). This solution has been rectified.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for inserting a PHP array into an email communication

I have a question regarding sending emails through PHP. How can I include PHP arrays in the message section of an email? Here is a simple array that I created and attempted to include in the email, but it seems incorrect as I couldn't find any releva ...

The sidebar on the right side of the screen is content to relax beneath my

The positioning of my sidebar is currently below the content on the left side of the page, but I want it to sit beside the content on the right side. I've tried various solutions from similar questions without success. Here is an example of how I woul ...

What is the best way to prevent the dropdown function in a selectpicker (Bootstrap-Select)?

Is there a way to completely disable a selectpicker when a radio button is set to "No"? The current code I have only partially disables the selectpicker: $("#mySelect").prop("disabled", true); $(".selectpicker[data-id='mySelect']").addClas ...

Executing a function with the initial click

Is there a way to run a function only on the first click, without having it run every time? I already have another function running on window.onload, so I can't use that. Both functions work fine independently, but not together. Right now, I'm ca ...

JQuery is having trouble with playing multiple sound files or causing delays with events

I've been working on a project that involves playing sounds for each letter in a list of text. However, I'm encountering an issue where only the last sound file is played instead of looping through every element. I've attempted to delay the ...

Run each element in sequence after the page has finished loading

I am currently exploring animate.css at and I am curious if it is feasible to apply CSS animations to multiple elements sequentially upon page load. Below are the three distinct elements I aim to animate: <img src="flowers.png" data-test="bounceInDow ...

What is the best way to make a div expand to the full width of the screen while still being contained within its parent div?

I am facing an issue with the black bar at the bottom of the slider not stretching full-width on the screen. While it works fine on the left, the right side is cut off at the container edge. I am using Master Slider if that's relevant information. Can ...

Utilizing the @page CSS rule in Vue.js: A step-by-step guide

I am facing an issue with printing a specific page in landscape mode. Here is the code snippet I have been using: @page { margin: 0; size: A4 landscape; } The problem is that this style rule affects all pages in my application because all style se ...

Embedding a CSS class within the primary class selector

Can someone help me with this HTML challenge? <div class="span3"> <div class="abc">code for first div</div> <div class="abc">code for second div</div> </div> I'm trying to hide the first "abc" division within th ...

What could be the reason for the clone function not duplicating the data within the table

Recently, I utilized jQuery's clone method to duplicate and add an HTML table. The rows and cells of the table were added using jQuery. However, despite using clone, it only replicated the headers and CSS, not the appended data. This raises the ques ...

Break the page after generating specific charts with JQuery

I have a task to create multiple charts, where the first page needs to include a header and the first 8 charts. How can I insert a page break after the 8th chart and move on to a second page without a header? Each student has different subjects and score ...

When applying a maximum width of 100% with automatic height, images may become cropped

I'm a beginner in learning CSS, and since my technical skills are limited, I'll try to keep things simple. Currently, I have an image taking up half of the screen with the following CSS code that I found after reading some articles: <div class ...

I am having trouble scrolling through the main content when the side-drawer is open. How can I fix this issue?

When the sidebar is opened, I am facing issues with the main content scroll and certain fields such as select options and search bar not functioning properly. I have included the main content in the routes from which it is being loaded. However, the scroll ...

How can users change the displayed Twitch channel?

My coding skills aren't the greatest, especially when it comes to something like this. I've tried searching for a solution with no luck, so I apologize if this is too basic or impossible. I have a simple page that loads up Twitch with a predefin ...

Using SCSS to apply a class in Next.js

Currently, I am working on a project using Next.js and implementing the SCSS module procedure for styling. An example component directory structure is as follows: SampleComponent -> index.tsx and SampleComponent.module.scss The code in SampleComponent ...

Creating a toggle button for a div element to expand and collapse its content: Step-by-step guide

For my e-commerce site selling musical instruments, I'm designing a product landing page that showcases guitars, keyboards, violins, and cellos. As part of the design, I want to include expandable sections with detailed information about each instrume ...

css failing to load properly following javascript redirection

Upon clicking the button labeled id=cancel, the user will be directed to index.php. $('#cancel').click(function() { if(changes > 0){ $('#dialog-confirm').dialog('open'); }else{ window.location.href = ". ...

How to export HTML table information to Excel using JQuery and display a Save As dialog box

This script has been an absolute lifesaver for my web application. Huge thanks to sampopes for providing the solution on this specific thread. function exportToExcel() { var tab_text="<table border='2px'><tr bgcolor='#87AFC6& ...

The text that follows the cursor seems to stand out taller than the rest

When I type words in a textarea input field, the cursor seems to be taller than it should be (as shown below). What is causing this issue and is there a way to make it as tall as the words with a font size of 38px? Here is the code snippet: <textarea n ...

perfecting the styling of a tab management system

For reference, please check out the following link: http://jsfiddle.net/XEbKy/3/ In my design, I have organized two layers of tabs. The top layer consists of two tabs while the bottom layer has three tabs. My goal is to have all these tabs neatly enclosed ...