If you allow the elements to expand and contract freely, it's best not to specify a fixed flex-basis value.
Each child element can be resized using width, min-width, or flex-grow properties.
Here is an example showcasing these three rules with flex-basis set to auto:
* {
box-sizing: border-box;
}
body {
display: flex;
gap: 1em;
}
.container {
display: flex;
width: 150px;
}
.item {
flex: 1 1 auto;
border: 1px solid blue;
}
.item:focus {
border-color: red;
}
.width .item:focus {
width: 66.66%;
}
.min-width .item:focus {
min-width: 66.66%;
border-color: yellow;
}
.grow-4 .item:focus {
flex-grow: 4;
border-color: hotpink;
}
<div class="container width">
<div class="item" tabindex="0">
<p>1</p>
</div>
<div class="item" tabindex="0">
<p>2</p>
</div>
<div class="item" tabindex="0">
<p>3</p>
</div>
</div><div class="container min-width">
<div class="item" tabindex="0">
<p>1</p>
</div>
<div class="item" tabindex="0">
<p>2</p>
</div>
<div class="item" tabindex="0">
<p>3</p>
</div>
</div><div class="container grow-4">
<div class="item" tabindex="0">
<p>1</p>
</div>
<div class="item" tabindex="0">
<p>2</p>
</div>
<div class="item" tabindex="0">
<p>3</p>
</div>
</div>
To prevent shrinking: instead of setting flex-shrink to 1, set it to 0 and allow wrapping or overflow. Flex-basis can handle this task on its own, and flex-grow can be reset to 0 if needed.
* {
box-sizing: border-box;
}
body {
display: grid;
gap: 1em;
}
.container {
display: flex;
width: 150px;
background: silver;
}
.container + .container {
flex-wrap: wrap;
}
.item {
flex: 0 0 33.33%;
border: 1px solid blue;
}
.item:focus {
border-color: red;
flex-basis: 66.66%;
}
<div class="container">
<div class="item" tabindex="0">
<p>1</p>
</div>
<div class="item" tabindex="0">
<p>2</p>
</div>
<div class="item" tabindex="0">
<p>3</p>
</div>
</div>
<div class="container">
<div class="item" tabindex="0">
<p>1</p>
</div>
<div class="item" tabindex="0">
<p>2</p>
</div>
<div class="item" tabindex="0">
<p>3</p>
</div>
</div>