Home > Enterprise >  flex parent still expands according to child content, even though child has `0` width
flex parent still expands according to child content, even though child has `0` width

Time:06-08

Please consider the following example:

.flexer {
  display: inline-flex;
  border: 1px solid red;
  min-width: 0;
}
.extra {
  flex: 0 1 0%; /* flex-grow: 0; flex-shrink: 1; flex-basis: 0%; */
  min-width: 0;
  transition: flex-grow .3s cubic-bezier(.4,0,.2,1);
  overflow: hidden;
}
.flexer:hover .extra {
  flex-grow: 1
}
<div >
  <div>
     test
  </div>
  <div >
    extra
  </div>
</div>

<hr>
<div >
  <div>
     test
  </div>
</div> - How it should look, when not hovered
<br>
<div >
  <div>
     test
  </div>
  <div>
    extra
  </div>
</div> - How it should look, when hovered
<br><br>
The red box should animate smoothly between the two widths.

I have trouble understanding why .flexer (the parent) doesn't shrink when not hovered (e.g: the red box still remains full, instead of shrinking around test).

From this q/a I understand that by adding min-width: 0 to the child should allow the parent to shrink. I've added it to both child and parent, to no avail.

Note 1: I'm more interested in understanding the mechanics and why this happens than finding an alternative solution (javascript, absolute positioning, etc...).
I'd like to use flexbox and I'd like to animate flex-grow - or any other animatable flex prop - for this case, if at all possible.

Note 2: the markup is irrelevant (I'm open to changing it - e.g: adding a wrapper to any of the children, if that will make my example work).

Thanks for looking into this.

CodePudding user response:

Here is my try

.flexer {
  display: inline-flex;
  border: 1px solid red;
  min-width: 0;
}
.extra {
  flex: 0 1 0%; /* flex-grow: 0; flex-shrink: 1; flex-basis: 0%; */
  width: 0;
  transition: flex-grow .3s cubic-bezier(.4,0,.2,1);
  overflow: hidden;
}

.flexer:hover .extra {
  flex-grow: 1;
  width: 100%; /* you can also use 'auto' value */
}
<div >
  <div>
     test
  </div>
  <div >
    extra
  </div>
</div>

CodePudding user response:

You were right on track. Just add width: 0; to .extra and remove the min-width. Then set the width for .extra on :hover to fit-content or auto.

.flexer {
  display: inline-flex;
  border: 1px solid red;
}

.extra {
  flex: 0 1 0%;
  /* flex-grow: 0; flex-shrink: 1; flex-basis: 0%; */
  transition: flex-grow .3s cubic-bezier(.4, 0, .2, 1);
  overflow: hidden;
  width: 0;
}

.flexer:hover .extra {
  flex-grow: 1;
  width: fit-content;
}
<div >
  <div>
    test
  </div>
  <div >
    extra
  </div>
</div>

CodePudding user response:

.flexer {
  display: inline-flex;
  border: 1px solid red;
}
.extra {
  flex: 0 1 0%;
  transition: flex-grow .3s cubic-bezier(.4,0,.2,1);
  overflow: hidden;
  width: 0;
}
.flexer:hover .extra {
  flex-grow: 1;
  width: auto;
}

CodePudding user response:

You could use max-width which can be transitioned but you will need to set a hard value of some kind so just be conscious of how much text you're putting in there and adjust accordingly.

.flexer {
  display: inline-flex;
  border: 1px solid red;
}

.extra {
  flex: 0 1 0%;
  /* flex-grow: 0; flex-shrink: 1; flex-basis: 0%; */
  transition: all .3s cubic-bezier(.4, 0, .2, 1);
  max-width: 0;
  overflow: hidden;
}

.flexer:hover .extra {
  flex-grow: 1;
  max-width: 100px;
}
<div >
  <div>
    test
  </div>
  <div >
    extra
  </div>
</div>

  • Related