Transitioning flex-basis from auto
flex-basis
can be animated and transitioned (source). However, like other properties, it can only be done if you set the values to actual length values (like px
, %
, etc. and calc()
). More info can be found in this question.
Flex transition: Stretch (or shrink) to fit content
It is possible to solve it using max-width
and calc()
.
First, replace width: 100%
with flex: 1
for the divs in CSS, so they will grow, which is better in this case. In addition, use transition for max-width
.
Now, we have to store some relevant values:
- The amount of divs that will be animated (
divsLength
variable) - 3 in this case. - The total width used for the fixed div and the borders (
extraSpace
variable) - 39px in this case.
With those 2 variables, we can set a default max-width
(defaultMaxWidth
variable) to all the divs, as well as using them later. That is why they are being stored globally.
The defaultMaxWidth
is calc((100% - extraSpace)/divsLength)
.
Now, let's enter the click function:
To expand the div, the width of the target text will be stored in a variable called textWidth
and it will be applied to the div as max-width.
It uses .getBoundingClientRect().width
(since it return the floating-point value).
For the remaining divs, it is created a calc()
for max-width
that will be applied to them.
It is: calc(100% - textWidth - extraScape)/(divsLength - 1)
.
The calculated result is the width that each remaining div should be.
When clicking on the expanded div, that is, to return to normal, the default max-width
is applied again to all .div
elements.
var expanded = false,
divs = $(".div:not(:first-child)"),
divsLength = divs.length,
extraSpace = 39, //fixed width + border-right widths
defaultMaxWidth = "calc((100% - " + extraSpace + "px)/" + divsLength + ")";
divs.css("max-width", defaultMaxWidth);
$(document).on("click", ".div:not(:first-child)", function (e) {
var thisInd = $(this).index();
if (expanded !== thisInd) {
var textWidth = $(this).find('span')[0].getBoundingClientRect().width;
var restWidth = "calc((100% - " + textWidth + "px - " + extraSpace + "px)/" + (divsLength - 1) + ")";
//fit clicked fluid div to its content and reset the other fluid divs
$(this).css({ "max-width": textWidth });
$('.div').not(':first').not(this).css({ "max-width": restWidth });
expanded = thisInd;
} else {
//reset all fluid divs
$('.div').not(':first').css("max-width", defaultMaxWidth);
expanded = false;
}
});
.wrapper {
overflow: hidden;
width: 100%;
margin-top: 20px;
border: 1px solid black;
display: flex;
justify-content: flex-start;
}
.div {
overflow: hidden;
white-space: nowrap;
border-right: 1px solid black;
text-align:center;
}
.div:first-child {
min-width: 36px;
background: #999;
}
.div:not(:first-child) {
flex: 1;
transition: max-width 1s;
}
.div:not(:first-child) span {
background: #ddd;
}
.div:last-child {
border-right: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
Click on the div you want to fit/reset (except the first div)
<div class="wrapper">
<div class="div"><span>Fixed</span></div>
<div class="div"><span>Fluid (long long long long text)</span></div>
<div class="div"><span>Fluid</span></div>
<div class="div"><span>Fluid</span></div>
</div>
Related Topics
Creating Object With Dynamic Keys
How to Animate a Progressive Drawing of Svg Path
How to Inject CSS into Webpage Through Chrome Extension
Using Jquery to Know When @Font-Face Fonts Are Loaded
What Is the Best Method to Reduce the Size of My JavaScript and CSS Files
How to Get Border Width in Jquery/Javascript
Generate Dynamic CSS Based on Variables Angular
Can Jquery Change CSS Style Definition? (Not Individual CSS of Each Element)
Toggle Visibility Property of Div
How to Check If an External (Cross-Domain) CSS File Is Loaded Using JavaScript
Google Seo and Hidden Elements
Changing Background Based on Time of Day (Using JavaScript)
Polymer Share Styles Across Elements
Serving Gzipped CSS and JavaScript from Amazon Cloudfront via S3
Screen Styling When Virtual Keyboard Is Active