Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make flexbox child's height to fit to content instead of 100% height of its container

Tags:

css

flexbox

#container {
  display:flex;
  height:300px;
  background:#333;
}
#child1 {
  width:30%;
  background:#3cf;
}
#child2 {
  width:30%;
  background:#3fc;
}
#child3 {
  width:40%;
  background:#cf3;
}
#child1_child {
  width:100%;
  background:#fc3;
}
pre {
  margin:0px;
}
    <div id="container">
    <div id="child1"><div id="child1_child"><pre>CONTENT<BR>CONTENT<BR>CONTENT<BR>CONTENT</pre></div></div>
    <div id="child2"></div>
    <div id="child3"></div>
    </div>

The height of #child1 is automatically set to the same height of #container, How can I make it to fit to #child1_child rather than 100% height of #container?

The height of #child1_child is not static, it can be changed by content inside of it, height of #child1 with static value is useless.

like image 845
Fei Sun Avatar asked Feb 28 '16 15:02

Fei Sun


People also ask

How do I make my flexbox fill height?

Getting the child of a flex-item to fill height 100%Set position: absolute; on the child. You can then set width/height as required (100% in my sample).

How do I fix my flexbox size?

Solution with Flexbox If you want to have a fixed-width column with Flexbox, you need to use the CSS flex or flex-basis property. First of all, we set the display of our <div> container to "flex". Then, we specify the flex of the "grey" class as "0 0 50px".

How do you set height to 100% of a parent?

container div has two parent elements: the <body> and the <html> element. And we all know that the default value of the height property is auto , so if we also set the height of <body> and <html> elements to 100%, the resulting height of the container div becomes equal the 100% height of the browser window.


3 Answers

fit-content is limited in support; IE won't ever support it, and Firefox still requires a prefix. This solution has jQuery for demo purposes only and is not required for the solution. There are four choices:

  1. NONE: No extra styles on .A
  2. FIT-CONTENT: Adds the CSS property fit-content on .A
  3. MAX-CONTENT: Adds the CSS property max-content on .A
  4. TABLE: Adds the CSS property display:table on .A

Option 2 and 3 behave identically , so in conclusion the simplest solution is to apply display:table and it's incredibly compatible as it is simple. height: fit-content and max-content is almost as compatible with one minor caveat being that IE does not support it (IE is going the way of the dinosaur so it's pretty much a non issue).


Demo

$('.rad').on('change', switchStyle);

function switchStyle(e) {
  var pick = $(this).val();
  switch (pick) {
    case 'nil':
      $('.A').removeClass('fit max tab');
      break;
    case 'fit':
      $('.A').addClass('fit').removeClass('max tab');
      break;
    case 'max':
      $('.A').addClass('max').removeClass('fit tab');
      break;      
    case 'tab':
      $('.A').addClass('tab').removeClass('fit max');
      break;
    default:
      break;
  }
}
.box {
  display: flex;
  height: 300px;
  background: #333;
}
.A {
  width: 30%;
  background: #3cf;
}
.B {
  width: 30%;
  background: #3fc;
}
.C {
  width: 40%;
  background: #cf3;
}
.A1 {
  width: 100%;
  background: #fc3;
}
pre {
  margin: 0px;
}
.set {
  position: relative;
  z-index: 1;
  bottom: 300px;
  left: 30%;
  width: 30ch;
  font: 400 16px/1.428 Verdana;
}
.A.fit {
  height: -moz-fit-content;
  height: -webkit-fit-content;
  height: -fit-content;
}
.A.max {
  height: max-content;
}
.A.tab {
  display: table;
}
<div class="box">
  <div class="A">
    <div class="A1"><pre>
    CONTENT
    CONTENT
    CONTENT
    CONTENT</pre>
    </div>
  </div>
  <div class="B"></div>
  <div class="C"></div>
</div>

<fieldset class='set'>
  <label>NONE
    <input class='rad' name='rad' type='radio' value='nil' checked>
  </label>
  <label>FIT-CONTENT
    <input class='rad' name='rad' type='radio' value='fit'>
  </label><br>
  <label>MAX-CONTENT
    <input class='rad' name='rad' type='radio' value='max'>
  </label>  
  <label>TABLE
    <input class='rad' name='rad' type='radio' value='tab'>
  </label>
</fieldset>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
like image 112
zer00ne Avatar answered Oct 22 '22 05:10

zer00ne


Using of experimental values of the height CSS property is generally discouraged.

If it is individual flexbox child which you want to fill the height according to its content, use align-self: baseline; for it (see the example). If it is all the children, put align-items: baseline; into the parent container.

#container {
  display: flex;
  height: 300px;
  background: #333;
}

#child1 {
  width: 30%;
  background: #3cf;
  align-self: baseline;
}

#child2 {
  width: 30%;
  background: #3fc;
}

#child3 {
  width: 40%;
  background: #cf3;
}

#child1_child {
  width: 100%;
  background: #fc3;
}

pre {
  margin: 0;
}
    <div id="container">
    <div id="child1"><div id="child1_child"><pre>CONTENT<BR>CONTENT<BR>CONTENT<BR>CONTENT</pre></div></div>
    <div id="child2"></div>
    <div id="child3"></div>
    </div>
like image 33
Neurotransmitter Avatar answered Oct 22 '22 03:10

Neurotransmitter


Try setting min-height or min-width... Magic.

#container {
  display: flex;
  height: 100%;
  min-height: 0;
}

By default, flex items won’t shrink below their minimum content size (the length of the longest word or fixed-size element). To change this, set the min-width or min-height property. (See §4.5 Automatic Minimum Size of Flex Items.) https://www.w3.org/TR/css-flexbox-1/#propdef-flex

like image 9
Austen Stone Avatar answered Oct 22 '22 03:10

Austen Stone