My intention is to have a round colored bullet centered under some text, or an underline as long as the text, depending on the size of the viewport; and a smooth transition should occur between the two states.
However, it looks like transitioning from a numeric to non-numeric value of width
or viceversa is not possible.
For demonstration purpose, in the example below I don't use a media query to change from one state to another but a checkbox.
In the snippet below you can see that the transition of width
from auto
to 1em
doesn't work (the value changes abruptly as the check box changes state).
input div {
margin-bottom: 0.4em;
display: inline-block;
margin: auto;
}
input div::after {
display: block;
content: "";
height: 0.5em;
background-color: blue;
transition-property: all;
transition-duration: 2s;
margin: auto;
width: auto;
}
input:checked div::after {
height: 1em;
width: 1em;
border-radius: 100%;
margin: auto;
}
<input type="checkbox">
<div>some very long word</div>
On the other hand, changing width: auto
to, say, width: 5em;
, makes the transition smooth.
input div {
margin-bottom: 0.4em;
display: inline-block;
margin: auto;
}
input div::after {
display: block;
content: "";
height: 0.5em;
background-color: blue;
transition-property: all;
transition-duration: 2s;
margin: auto;
width: 5em;
}
input:checked div::after {
height: 1em;
width: 1em;
border-radius: 100%;
margin: auto;
}
<input type="checkbox">
<div>some very long word</div>
My question is: is it possible somehow to have a smooth width
transition in the scenario described above? If not, why? And what workarounds are advisable?
CodePudding user response:
No, Transitions ONLY work from specific
numeric value to another
but there are a few tricks to beat it
first and best is using min-width and max-width instead of width
second is using transform:scale
Here is the example for min-width
input div {
margin-bottom: 0.4em;
display: inline-block;
margin: auto;
}
input div::after {
display: block;
content: "";
height: 0.5em;
background-color: blue;
transition-property: all;
transition-duration: 2s;
margin: auto;
max-width: 10rem;
}
input:checked div::after {
height: 1em;
max-width: 1em;
border-radius: 100%;
margin: auto;
}
<input type="checkbox">
<div>some very long word</div>