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>