The Issue
I often run into the scenario where I'm building a toolbar with items on the left, in the middle, and on the right. The items on the left and right can often be of varying width, and as their widths change dynamically, the item in the middle moves to the left or right while it centers itself between the outer edge of the left/right items.
For example, a toolbar with some buttons on the left, a date input in the middle, and a message on the right might look like this:
But if there is only one button and a really long message, the date input shifts more to the left:
This is not a great user experience, especially if the outer column widths change dynamically.
HTML/CSS Before Applying Solution
.toolbar {
display: flex;
justify-content: center;
align-items: center;
}
<div class="toolbar">
<div class="button-col">
<button>New Event</button>
<button>Edit</button>
<button>Copy</button>
</div>
<input type="date" value="2024-08-01" />
<div class="message-col">
<span>✓ Event saved!</span>
</div>
</div>
The Solution
We can easily solve this one by applying flex-grow: 1
and flex-basis: 0
to the outer columns as follows:
.toolbar {
display: flex;
justify-content: center;
align-items: center;
}
.button-col,
.message-col {
flex-grow: 1; /* See here */
flex-basis: 0; /* And here */
}
<div class="toolbar">
<div class="button-col">
<button>New Event</button>
<button>Edit</button>
<button>Copy</button>
</div>
<input type="date" value="2024-08-01" />
<div class="message-col">
<span>✓ Event saved!</span>
</div>
</div>
And now our date input is centered, regardless of the width of the outer columns!
Dealing With Wrapping
On smaller screens, the outer columns will start to wrap when they bump up against the center column. You can set different flex-grow values at different screen widths to optimize the behaviour. You can also set white-space: nowrap
on a specific column (e.g. the buttons column) to prevent it from wrapping, which pushes the wrapping behaviour to the other column (e.g. the messages column).