[css-transitions] Transition to height (or width) "auto" #626

Open
keithjgrant opened this Issue Oct 20, 2016 · 25 comments

Comments

Projects
None yet
@keithjgrant
Contributor

keithjgrant commented Oct 20, 2016

https://drafts.csswg.org/css-transitions/#animtype-rect

It would be incredibly useful to be able to transition to (or from) height: auto. As it stands now, you need to jump through a bunch of hoops in JavaScript to simulate it. This is used frequently for transitioning in alert boxes, opening accordions, etc, but it seems silly that JavaScript is required.

I’m sure there must be discussion about this in the old mailing list, but I’d love to be privy to it here.

@AmeliaBR

This comment has been minimized.

Show comment
Hide comment
@AmeliaBR

AmeliaBR Oct 20, 2016

Adding here what I replied to @keithjgrant via Twitter:

In order to interpolate to/from an auto or other keyword value, you need to have a way of describing the intermediary state. For lengths, intermediary states can usually be described via a calc() function. 10% of the transition from 50px to 20em is calc(0.9*50px + 0.1*20em). So the most generic approach to supporting transitions with keywords would be to allow the keywords to be used in calc(), with a real-time substitution of the current computed value that the keyword would create.

Sure, there are edge cases where the performance would inevitably be horrible (e.g., if you are transitioning to/from auto at the same time you are also changing things that would cause the current computed value of auto to change), but that shouldn't be reason to prevent its use in more sensible cases.

Adding here what I replied to @keithjgrant via Twitter:

In order to interpolate to/from an auto or other keyword value, you need to have a way of describing the intermediary state. For lengths, intermediary states can usually be described via a calc() function. 10% of the transition from 50px to 20em is calc(0.9*50px + 0.1*20em). So the most generic approach to supporting transitions with keywords would be to allow the keywords to be used in calc(), with a real-time substitution of the current computed value that the keyword would create.

Sure, there are edge cases where the performance would inevitably be horrible (e.g., if you are transitioning to/from auto at the same time you are also changing things that would cause the current computed value of auto to change), but that shouldn't be reason to prevent its use in more sensible cases.

@nico3333fr

This comment has been minimized.

Show comment
Hide comment
@nico3333fr

nico3333fr Oct 21, 2016

@keithjgrant yes, this is a real problem.

For the moment, we set up transitions on max-height value (using magic numbers for values, max-height = enough_and_pray_the_content_is_not_that_tall), and if you want to do it including accessibility pov, you have to transition on visibility (as display is not possible, cf this accordion https://a11y.nicolas-hoffmann.net/accordion/?animated=1 ) with a delay... really complicated for something that should be simple. :)

@keithjgrant yes, this is a real problem.

For the moment, we set up transitions on max-height value (using magic numbers for values, max-height = enough_and_pray_the_content_is_not_that_tall), and if you want to do it including accessibility pov, you have to transition on visibility (as display is not possible, cf this accordion https://a11y.nicolas-hoffmann.net/accordion/?animated=1 ) with a delay... really complicated for something that should be simple. :)

@rickyp-ms

This comment has been minimized.

Show comment
Hide comment
@rickyp-ms

rickyp-ms Nov 3, 2016

Looking around the web, you can easily see that this is a constant problem for developers. Velocity.js even notes this specific missing feature in its first paragraph of why it exists (https://fabric.io/blog/introducing-the-velocityreact-library). I can probably give a ton of references (on request) of developers rendering an element, measuring it, setting it's height to 0 then animating to that specific height. Even JQueryUI does a similar measurement technique just to get this to work and it's been around for almost a decade now.

What can we do as the larger software development community to petition this change and make sure it gets in on the next iteration?

Do we need to have more people come here and upvote this bug? Do we need to email a specific individual? Let us know so we can let you know what we need most.

Looking around the web, you can easily see that this is a constant problem for developers. Velocity.js even notes this specific missing feature in its first paragraph of why it exists (https://fabric.io/blog/introducing-the-velocityreact-library). I can probably give a ton of references (on request) of developers rendering an element, measuring it, setting it's height to 0 then animating to that specific height. Even JQueryUI does a similar measurement technique just to get this to work and it's been around for almost a decade now.

What can we do as the larger software development community to petition this change and make sure it gets in on the next iteration?

Do we need to have more people come here and upvote this bug? Do we need to email a specific individual? Let us know so we can let you know what we need most.

@k2snowman69

This comment has been minimized.

Show comment
Hide comment
@k2snowman69

k2snowman69 Dec 5, 2016

I too am curious what we (the web programming community in general) can do to petition a change in the spec... I've got a few issues I know I could get quite a few people backing.

I too am curious what we (the web programming community in general) can do to petition a change in the spec... I've got a few issues I know I could get quite a few people backing.

@birtles

This comment has been minimized.

Show comment
Hide comment
@birtles

birtles Dec 5, 2016

Contributor

I caught up with @dbaron about this recently and it seems a likely way forward is to make 'auto' into a computed value. As well as enabling animation with auto, that would also make it possible to write expressions like calc(auto + 10px). While that might not be trivial to implement, since there is interest from authors' and, I believe, browser vendors, it seems promising.

(One way to push this forward would be to submit a patch to one of the open-source browsers for this. Once you've proven the technical feasibility of this, it's easier to argue for it to be added to the spec.)

Contributor

birtles commented Dec 5, 2016

I caught up with @dbaron about this recently and it seems a likely way forward is to make 'auto' into a computed value. As well as enabling animation with auto, that would also make it possible to write expressions like calc(auto + 10px). While that might not be trivial to implement, since there is interest from authors' and, I believe, browser vendors, it seems promising.

(One way to push this forward would be to submit a patch to one of the open-source browsers for this. Once you've proven the technical feasibility of this, it's easier to argue for it to be added to the spec.)

@dbaron

This comment has been minimized.

Show comment
Hide comment
@dbaron

dbaron Dec 5, 2016

Member

auto is already a computed value; the thing that needs to happen is adding support for auto to calc().

Member

dbaron commented Dec 5, 2016

auto is already a computed value; the thing that needs to happen is adding support for auto to calc().

@k2snowman69

This comment has been minimized.

Show comment
Hide comment
@k2snowman69

k2snowman69 Dec 6, 2016

Awesome I'll start looking into it using Firefox since I think theirs would be the easiest source code to get a hold of. That said, it may take me a while due to lack of cpu resources (my computer is a 2 core 2.4ghz processor... it's going to take a while to build).

Awesome I'll start looking into it using Firefox since I think theirs would be the easiest source code to get a hold of. That said, it may take me a while due to lack of cpu resources (my computer is a 2 core 2.4ghz processor... it's going to take a while to build).

@nilssolanki

This comment has been minimized.

Show comment
Hide comment
@nilssolanki

nilssolanki Dec 13, 2016

Thank you very much for bringing this up. We currently work around this by reading out an elements scrollHeight and transitioning to that height, only to revert the element height to auto on transitionend. So making this a platform feature would be fantastic.

Thank you very much for bringing this up. We currently work around this by reading out an elements scrollHeight and transitioning to that height, only to revert the element height to auto on transitionend. So making this a platform feature would be fantastic.

@craigfrancis

This comment has been minimized.

Show comment
Hide comment
@craigfrancis

craigfrancis Dec 13, 2016

It has been suggested that we use max-height: max-content.

But trying to get the browsers to implement either has been very difficult, as the CSS animations are typically done between 2 known values, which is why animation usually needs to be done with something like max-height: 500em.

As an aside (and for some of the background on this), I've been trying to get browsers to support auto-height <iframes> and <textarea>s, which will work in pretty much the same way:

https://github.com/craigfrancis/iframe-height

https://discourse.wicg.io/t/feature-request-animating-max-height-height-based-on-content/1403

It has been suggested that we use max-height: max-content.

But trying to get the browsers to implement either has been very difficult, as the CSS animations are typically done between 2 known values, which is why animation usually needs to be done with something like max-height: 500em.

As an aside (and for some of the background on this), I've been trying to get browsers to support auto-height <iframes> and <textarea>s, which will work in pretty much the same way:

https://github.com/craigfrancis/iframe-height

https://discourse.wicg.io/t/feature-request-animating-max-height-height-based-on-content/1403

@Jakobud

This comment has been minimized.

Show comment
Hide comment
@Jakobud

Jakobud Dec 13, 2016

+1. Not being able to transition on height: auto and display: <anything!> (You can't even do a transition-delay on display) has always been a big pain.

Jakobud commented Dec 13, 2016

+1. Not being able to transition on height: auto and display: <anything!> (You can't even do a transition-delay on display) has always been a big pain.

@k2snowman69

This comment has been minimized.

Show comment
Hide comment
@k2snowman69

k2snowman69 Dec 14, 2016

Just FYI I'm currently out of the country and I'm also checking with my legal department to see if this is something I'm allowed to do due to where I work (non-compete and helping competitor issues). I'll be back in town on the 20th.

@nilssolanki That's the same trick we're using and it's just annoying.

@Jakobud I would say animating display is a bit out of the bounds of this request and may also have a few edge cases that would be interesting (animating inline to block?).

Just FYI I'm currently out of the country and I'm also checking with my legal department to see if this is something I'm allowed to do due to where I work (non-compete and helping competitor issues). I'll be back in town on the 20th.

@nilssolanki That's the same trick we're using and it's just annoying.

@Jakobud I would say animating display is a bit out of the bounds of this request and may also have a few edge cases that would be interesting (animating inline to block?).

@k2snowman69

This comment has been minimized.

Show comment
Hide comment
@k2snowman69

k2snowman69 Jan 13, 2017

My legal department has come back to me informing me that I'm unable to currently work on this request due to non-compete legal stuff. That said, I'll have to (frustratingly) recuse myself of any code writing for this feature.

Just to note, I also asked a google groups question here if anyone is interested in taking this up. It should give a basic guide to how I was planning on tackling the problem.

https://groups.google.com/forum/#!searchin/mozilla.dev.tech.layout/auto%7Csort:relevance/mozilla.dev.tech.layout/fFuJqwXvu2I/6_mt7HmhDAAJ

My legal department has come back to me informing me that I'm unable to currently work on this request due to non-compete legal stuff. That said, I'll have to (frustratingly) recuse myself of any code writing for this feature.

Just to note, I also asked a google groups question here if anyone is interested in taking this up. It should give a basic guide to how I was planning on tackling the problem.

https://groups.google.com/forum/#!searchin/mozilla.dev.tech.layout/auto%7Csort:relevance/mozilla.dev.tech.layout/fFuJqwXvu2I/6_mt7HmhDAAJ

@danegraphics

This comment has been minimized.

Show comment
Hide comment
@danegraphics

danegraphics Jun 26, 2017

Just want to make sure this is still happening.

This is actually rather important because, yes, we can precalculate a value for height and other properties using javascript and things like document.getElementById(elementID).scrollHeight+'px' , but sometimes we need the property to have an auto value after the animation/transition so that we can make changes inside and around the element that the element will respond to appropriately.

For example, I have an element that transitions from a height of 0 to a height of 'auto'. After the transition is completed I want the height of the element to be able to adjust correctly to the changing elements inside of it without me having to recalculate it myself.

So if it really is just adding auto compatibility to the calc() function, as @dbaron has mentioned, is someone working on that, and if not, how would one do so?

Just want to make sure this is still happening.

This is actually rather important because, yes, we can precalculate a value for height and other properties using javascript and things like document.getElementById(elementID).scrollHeight+'px' , but sometimes we need the property to have an auto value after the animation/transition so that we can make changes inside and around the element that the element will respond to appropriately.

For example, I have an element that transitions from a height of 0 to a height of 'auto'. After the transition is completed I want the height of the element to be able to adjust correctly to the changing elements inside of it without me having to recalculate it myself.

So if it really is just adding auto compatibility to the calc() function, as @dbaron has mentioned, is someone working on that, and if not, how would one do so?

@k2snowman69

This comment has been minimized.

Show comment
Hide comment
@k2snowman69

k2snowman69 Jun 26, 2017

To my knowledge no one has picked up this work and I'm still barred due to legal constraints. But if you download the source code and read the conversation here:
https://groups.google.com/forum/#!searchin/mozilla.dev.tech.layout/auto%7Csort:relevance/mozilla.dev.tech.layout/fFuJqwXvu2I/6_mt7HmhDAAJ

It should give you a few locations to pinpoint where you would need to make the changes you need. Not sure if those are all of them but it should give you a starting point for learning the code base.

Good luck, I hope you do take this up because it would be an amazing addition!

To my knowledge no one has picked up this work and I'm still barred due to legal constraints. But if you download the source code and read the conversation here:
https://groups.google.com/forum/#!searchin/mozilla.dev.tech.layout/auto%7Csort:relevance/mozilla.dev.tech.layout/fFuJqwXvu2I/6_mt7HmhDAAJ

It should give you a few locations to pinpoint where you would need to make the changes you need. Not sure if those are all of them but it should give you a starting point for learning the code base.

Good luck, I hope you do take this up because it would be an amazing addition!

@tabatkins

This comment has been minimized.

Show comment
Hide comment
@tabatkins

tabatkins Jun 27, 2017

Member

I'd have to review to make sure that 'auto' doesn't have any special behaviors that make it incompatible with explicit lengths in some situations. That is, any place where the layout system does special things if the width/height is "auto", such that replacing the "auto" with its equivalent absolute length would give a different result.

Member

tabatkins commented Jun 27, 2017

I'd have to review to make sure that 'auto' doesn't have any special behaviors that make it incompatible with explicit lengths in some situations. That is, any place where the layout system does special things if the width/height is "auto", such that replacing the "auto" with its equivalent absolute length would give a different result.

@craigfrancis

This comment has been minimized.

Show comment
Hide comment
@craigfrancis

craigfrancis Jun 27, 2017

I can't remember the source, but it was recommended we use height: max-content rather than auto... this might have started from you TJ.

Where it would be nice if we could use this keyword for iframe's and textarea's as well.

I can't remember the source, but it was recommended we use height: max-content rather than auto... this might have started from you TJ.

Where it would be nice if we could use this keyword for iframe's and textarea's as well.

@danegraphics

This comment has been minimized.

Show comment
Hide comment
@danegraphics

danegraphics Jun 27, 2017

@k2snowman69 I would love to take this on and get it done. My question is what all would I need to change? I understand that there are the specification pages that explain how the transitions should be interpolated, and that those should be changed if this is added, but is there also some actual coded function or set of functions that would need to be modified? If so, where can I find them?

@tabatkins Do you know of any situations where that would be the case? (that auto acts differently than it's explicitly stated px size?)

danegraphics commented Jun 27, 2017

@k2snowman69 I would love to take this on and get it done. My question is what all would I need to change? I understand that there are the specification pages that explain how the transitions should be interpolated, and that those should be changed if this is added, but is there also some actual coded function or set of functions that would need to be modified? If so, where can I find them?

@tabatkins Do you know of any situations where that would be the case? (that auto acts differently than it's explicitly stated px size?)

@jcrben

This comment has been minimized.

Show comment
Hide comment
@jcrben

jcrben Jul 20, 2017

Linked to this discussion in an answer at Stackoverflow where I point out that transition to height: max-content does seem to work in Chrome: https://stackoverflow.com/a/45203565/4200039 nevermind, deleted the answer as I think I got confused somehow - doesn't seem to work

How can I transition height: 0; to height: auto; using CSS? is currently the top-voted question in the css-transitions tag, with nearly 5 times as many votes as the third-highest.

Also, what's the story with bugzilla these days as far as CSS? There's this bug - pointed here.

jcrben commented Jul 20, 2017

Linked to this discussion in an answer at Stackoverflow where I point out that transition to height: max-content does seem to work in Chrome: https://stackoverflow.com/a/45203565/4200039 nevermind, deleted the answer as I think I got confused somehow - doesn't seem to work

How can I transition height: 0; to height: auto; using CSS? is currently the top-voted question in the css-transitions tag, with nearly 5 times as many votes as the third-highest.

Also, what's the story with bugzilla these days as far as CSS? There's this bug - pointed here.

@danegraphics

This comment has been minimized.

Show comment
Hide comment
@danegraphics

danegraphics Jul 20, 2017

While height is easy to get to the calculated auto through max-content, it would be best if this were to work for multiple properties such as width (there is no setting comparable to auto) and others. It is impossible to use javascript to get width to work properly without manually doing the math to remove the L&R margins, padding, and border from the 100% calculation, and other properties have similar setting problems.

Using the pre-calculated auto value as the target setting for each property that has an 'auto' option, while actually setting it to 'auto', would be the best method from what I can see.

PS: The data from Stackoverflow suggest that this is the most requested feature for the next CSS update. Using Stackoverflow's highly voted issues would probably be a good place to look for other features that might be good to include in the next version.

danegraphics commented Jul 20, 2017

While height is easy to get to the calculated auto through max-content, it would be best if this were to work for multiple properties such as width (there is no setting comparable to auto) and others. It is impossible to use javascript to get width to work properly without manually doing the math to remove the L&R margins, padding, and border from the 100% calculation, and other properties have similar setting problems.

Using the pre-calculated auto value as the target setting for each property that has an 'auto' option, while actually setting it to 'auto', would be the best method from what I can see.

PS: The data from Stackoverflow suggest that this is the most requested feature for the next CSS update. Using Stackoverflow's highly voted issues would probably be a good place to look for other features that might be good to include in the next version.

@jonjohnjohnson

This comment has been minimized.

Show comment
Hide comment
@jonjohnjohnson

jonjohnjohnson Apr 12, 2018

I used to really really want this feature, but over the years have found myself being content with transitioning a transform in many cases, while having a parent element set in inaccessible ways...

.parent {
  pointer-events: none;
  visibility: none;
  overflow: hidden;
}
.element {
  pointer-events: auto;
  visibility: visible;
  transition: transform ease .375s;
  will-change: transform;
}
.transformed .element {
  transform: translateY(-100%);
}

Here, the -100% seamlessly takes care of the auto height and transitions a texture over possibly invaliding layout during a height transition. Not saying this is the silver bullet for the issue, but offering what I've found to be a more performant option for most cases. And furthermore, if we did get the ability to transition to/from auto, I'd rarely use it over this approach. Though, this obviously doesn't handle the case where you'd want flow content to move along with the "height" transition, which again, is not as performant.

jonjohnjohnson commented Apr 12, 2018

I used to really really want this feature, but over the years have found myself being content with transitioning a transform in many cases, while having a parent element set in inaccessible ways...

.parent {
  pointer-events: none;
  visibility: none;
  overflow: hidden;
}
.element {
  pointer-events: auto;
  visibility: visible;
  transition: transform ease .375s;
  will-change: transform;
}
.transformed .element {
  transform: translateY(-100%);
}

Here, the -100% seamlessly takes care of the auto height and transitions a texture over possibly invaliding layout during a height transition. Not saying this is the silver bullet for the issue, but offering what I've found to be a more performant option for most cases. And furthermore, if we did get the ability to transition to/from auto, I'd rarely use it over this approach. Though, this obviously doesn't handle the case where you'd want flow content to move along with the "height" transition, which again, is not as performant.

@cohsteve

This comment has been minimized.

Show comment
Hide comment
@cohsteve

cohsteve Apr 24, 2018

@jonjohnjohnson do you have a codepen/jsfiddle example of this anywhere and if not would you mind posting an example here? Many thanks

@jonjohnjohnson do you have a codepen/jsfiddle example of this anywhere and if not would you mind posting an example here? Many thanks

@jonjohnjohnson

This comment has been minimized.

Show comment
Hide comment
@jonjohnjohnson

jonjohnjohnson Apr 24, 2018

@cohsteve Quick -> https://jsfiddle.net/rwozw4bs/

Also, read up on FLIP animation methodology to see how you *could approach animating transforms while simulating the movement of flow content. https://aerotwist.com/blog/flip-your-animations/

@cohsteve Quick -> https://jsfiddle.net/rwozw4bs/

Also, read up on FLIP animation methodology to see how you *could approach animating transforms while simulating the movement of flow content. https://aerotwist.com/blog/flip-your-animations/

@keithjgrant

This comment has been minimized.

Show comment
Hide comment
@keithjgrant

keithjgrant Apr 24, 2018

Contributor

@jonjohnjohnson A transform effect works for absolutely positioned elements. But if the element is statically positioned, it still takes up space in document flow when scaled down to height 0.

Transitioning max-height was also mentioned above, but this too has a problem: the timing function is unreliable, since part of the transition will continue well after the max-height has reached the actual height of the element.

Contributor

keithjgrant commented Apr 24, 2018

@jonjohnjohnson A transform effect works for absolutely positioned elements. But if the element is statically positioned, it still takes up space in document flow when scaled down to height 0.

Transitioning max-height was also mentioned above, but this too has a problem: the timing function is unreliable, since part of the transition will continue well after the max-height has reached the actual height of the element.

@jonjohnjohnson

This comment has been minimized.

Show comment
Hide comment
@jonjohnjohnson

jonjohnjohnson Apr 24, 2018

@keithjgrant correct. I find the gains from transforming a texture and not invalidating layout worthwhile, as opposed to the *few times I find myself wanting to animate within a flow.

@keithjgrant correct. I find the gains from transforming a texture and not invalidating layout worthwhile, as opposed to the *few times I find myself wanting to animate within a flow.

@danegraphics

This comment has been minimized.

Show comment
Hide comment
@danegraphics

danegraphics Jun 22, 2018

Just making sure that this project hasn't been abandoned.

@dbaron, I see you are also the one assigned to the Mozilla ticket as well? (https://bugzilla.mozilla.org/show_bug.cgi?id=571344)

(I don't mean to be so pokey about this. I just keep running into designs where having this would immediately make the desired-but-impossible possible. So I hope that a fix for this bug will come soon.)

Just making sure that this project hasn't been abandoned.

@dbaron, I see you are also the one assigned to the Mozilla ticket as well? (https://bugzilla.mozilla.org/show_bug.cgi?id=571344)

(I don't mean to be so pokey about this. I just keep running into designs where having this would immediately make the desired-but-impossible possible. So I hope that a fix for this bug will come soon.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment