Is it possible to make a smooth transition from a numeric value of width to a non-numeric value and/or viceversa?

Issue

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?

Solution

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>

Answered By – Mahdiar Mransouri

Answer Checked By – Terry (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.