I have several form buttons positioned in a div using display: flex
.
Upon clicking the "Save" button I want to hide the original content of the save button and show a centered spinning icon. However, I do not want the width of the button to change since that causes the page other elements (buttons) around it to shift. Here's what happens with that I have now:
How do I ensure that the button keeps it's original width and does not shrink? I know I could set a min-width
on the button, but that would require me to specify a different width for each button this behavior is on since the text could be shorter or longer each time. I have also tried adding various combinations of flex-shrink: 0
styles to the buttons, but that doesn't seem to work either.
Code Pen Example
https://codepen.io/kspearrin/pen/eVNeMX
HTML
<div class="wrapper">
<button type="button" id="save">
<span id="savetext"><i class="fa fa-save"></i> Save</span>
<i class="fa fa-spinner fa-spin hide" id="spinner"></i>
</button>
<button type="button" id="cancel">Cancel</button>
<div class="right">
<button type="button"><i class="fa fa-star"></i></button>
<button type="button"><i class="fa fa-trash"></i></button>
</div>
</div>
CSS
.wrapper {
display: flex;
width: 400px;
align-items: center;
background-color: lightblue;
padding: 10px;
}
button {
margin-right: 10px;
text-align: center;
padding: 5px 10px;
}
button:last-child {
margin-right: 0;
}
.right {
margin-left: auto;
display: flex;
align-items: center;
}
.hide {
display: none;
}
JS
document.getElementById("save").onclick = () => {
document.getElementById("savetext").classList.add("hide");
document.getElementById("spinner").classList.remove("hide");
};
document.getElementById("cancel").onclick = () => {
document.getElementById("savetext").classList.remove("hide");
document.getElementById("spinner").classList.add("hide");
};
As said in comments, it is not related to flexbox: the behavior is normal. A box that is not display
will fit its content width.
You can use visibility
and flexbox to set the layout of your spinner.
Here, I just set the upper div to position:relative
, it does nothing except it becomes the reference for #spinner
which is absolute
.
I stretch it to the maximum and center its content with the flexbox :)
document.getElementById("save").onclick = () => {
document.getElementById("savetext").classList.add("hide");
document.getElementById("spinner").classList.remove("hide");
};
document.getElementById("cancel").onclick = () => {
document.getElementById("savetext").classList.remove("hide");
document.getElementById("spinner").classList.add("hide");
};
.wrapper {
display: flex;
width: 400px;
align-items: center;
background-color: lightblue;
padding: 10px;
}
button {
margin-right: 10px;
text-align: center;
padding: 5px 10px;
}
button:last-child {
margin-right: 0;
}
.right {
margin-left: auto;
display: flex;
align-items: center;
}
.hide {
visibility: hidden;
}
#save {
position: relative;
}
#spinner {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
bottom: 0;
top: 0;
left: 0;
right: 0;
}
<div class="wrapper">
<button type="button" id="save">
<span id="savetext"><i class="fa fa-save"></i> Save</span>
<i class="fa fa-spinner fa-spin hide" id="spinner"></i>
</button>
<button type="button" id="cancel">Cancel</button>
<div class="right">
<button type="button"><i class="fa fa-star"></i></button>
<button type="button"><i class="fa fa-trash"></i></button>
</div>
</div>
The updated codepen (font-awesome does not work here): https://codepen.io/anon/pen/vdOpJd