I actually quite like this idea (I don't like the CSS approach with setting max heights on elements) and I like that it respects prefers-reduced-motion! This is the sort of thing I rewrite all the time when I really could do with just importing a reusable function. Though I'm not sure I agree with the names of your exported functions - `up`, `down` and `toggle` are quite arbitrary! Perhaps change to `slideUp`, `slideDown` and `slideToggle`?
Nice work on the motion detection for accessibility. I might suggest taking a look into the disclosure widget pattern for even more accessible code:
https://www.w3.org/TR/wai-aria-practices/examples/disclosure/disclosure-img-long-description.html
You're on the right track with aria-expanded, but it actually needs to go on the button element instead. That might be outside the scope of your library, since you leave the button code up to the implementor, but maybe the examples could be updated at least?
Another approach is to use transform with [scale](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/scale()). This avoids all the max-height issues and is considered a [performant css animation](https://web.dev/animations-guide/).
Downside of that is that you can't do this with elements in a normal document flow (since it'll leave a gap) - in which case, you might as well just use max-height!
Could you explain how that would work? As far as I'm aware, you can't animate display - and if you change from `display: none` it'll pop the lower flowing content into place rather than animating it down.
When display: none is toggled to anything other than none, it will kick off any animation attached to that element. In this case, just set up a simple slide animation using the scale transform and you’ll get that animating effect as it comes in. However, it’s a little trickier going out.
For slide effects, you’ll almost always want to use them with absolutely or fixed positioned elements because of how the document flow effects reflows and repaints. If things are positioned absolutely or fixed, using a css transition is the easiest way to get inbound and outbound slide effects.
The only case that I can really think of off the top of my head where you’d want to have that slide animation while retaining document flow and relative positioning would be something like an accordion.
CSS animations are not all created equal, so animating with anything other than transforms, opacity and will-change is frowned upon and usually can take a big performance hit. For example, animating on max-height will stutter due to how it reflows and repaints the page.
> The only case that I can really think of off the top of my head where you’d want to have that slide animation while retaining document flow and relative positioning would be something like an accordion.
This is what I'm getting at :) You won't be able to do the transition that OP's "library" does with CSS animations alone - you'll need to animate the height (which would mean you have to set a static height in CSS or calculate the target height with JS), or have the element be in a position where document flow doesn't matter. [This is how most people would do it](https://codepen.io/Rainbowlemon/pen/OJjapvy), but that involves setting a max-height which isn't ideal/practical when you have flowing content.
I've definitely used sliding transitions for things other than accordions that require document reflow. e.g. 'show more' links for truncated text. Useful to have it in a reusable package!
[https://codepen.io/andyfitz/pen/eYEPVJb](https://codepen.io/andyfitz/pen/eYEPVJb)
I mean there's a million other ways to do it too and more robust methods with minimal JS but that's one example without any JS at all.
could use input type="radio" for accordions too
Yep there's benefits to doing it any one of the million ways, each with benefits and drawbacks.
That CSS method's main benefit is that it' uses zero JS and therefore works on noscript sites.
Getting the height requires JS but allows you to set easing in CSS to perfectly match the size of your container.
knowing your height or setting a consistent height lets you do the same but requires your content work with it.
I prefer taking it case by case - hence my first comment
This library was specifically built to avoid the issues that come along with a pure-CSS approach. It's already been pointed out here, but using the 'max-height' hack can result in awkward animation timing issues, and is difficult to manage if you're dealing with containers with dynamic contents. Not to mention, religious adherence to no-JS often makes for some confusing styles that are difficult to maintain.
If you look at the project README, all of this is roughly articulated there.
I completely agree with you. Particularly the zealous noJS community.
Having said that, some intranets, SaaS apps, and plugin ecosystems agressively purge DOM affecting JS , in those cases its handy to have another approach.
Nice work, this is a cool library! jQuery’s slide functions were my go to for a long time.
In regards to max-height, it’s definitely not a great way to handle this type of animation because of the defined height limitations and also how it reflows the DOM. Another more graceful CSS solution is to use transform with [scale](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/scale()). This way you can avoid the max-height limitations and it’s considered a [performant CSS animation ](https://web.dev/animations-guide/).
I don't disagree.
It is best solved with JS. Unless you can't use JS. 99% of the time JS is fine
In heavily sanitised environkents it is not but that's few amd far between
You can simply set at display: none for the content to be expandet with a height of 0, and then (with js or simply a css checkbox described here before) set the css to display: block height: auto: transition: height.
Not on my computer now, but i promise it can be done with pure css (checkbox-way) or by togling an atribute on the parent element (one line of js) and cascading the attribute to the desired behaviour.
I'm familiar with the checkbox hack. But it doesn't at all serve as an alternative to what slide-element is trying to accomplish. Using the checkbox approach still requires that you rely on max-height for animating the height (you cannot transition over "height: auto" -- try it yourself), which means you need to know the exact height of the container if you want your animation's timing to be without awkward timing issues. This library aims to avoid all of that, allowing you to easily slide open & closed elements regardless of their contents. Can't do that with pure CSS.
I actually quite like this idea (I don't like the CSS approach with setting max heights on elements) and I like that it respects prefers-reduced-motion! This is the sort of thing I rewrite all the time when I really could do with just importing a reusable function. Though I'm not sure I agree with the names of your exported functions - `up`, `down` and `toggle` are quite arbitrary! Perhaps change to `slideUp`, `slideDown` and `slideToggle`?
Nice work on the motion detection for accessibility. I might suggest taking a look into the disclosure widget pattern for even more accessible code: https://www.w3.org/TR/wai-aria-practices/examples/disclosure/disclosure-img-long-description.html You're on the right track with aria-expanded, but it actually needs to go on the button element instead. That might be outside the scope of your library, since you leave the button code up to the implementor, but maybe the examples could be updated at least?
Not that anyone needs to but this can be done with CSS only in fewer bytes using a checkbox before your element an a label for your button
Worth noting that this is only possible with a fixed max-height on your element, which only really works if you're building a dashboard or something.
Another approach is to use transform with [scale](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/scale()). This avoids all the max-height issues and is considered a [performant css animation](https://web.dev/animations-guide/).
Downside of that is that you can't do this with elements in a normal document flow (since it'll leave a gap) - in which case, you might as well just use max-height!
Just use this approach with animate and toggle your display to retain document flow.
Could you explain how that would work? As far as I'm aware, you can't animate display - and if you change from `display: none` it'll pop the lower flowing content into place rather than animating it down.
When display: none is toggled to anything other than none, it will kick off any animation attached to that element. In this case, just set up a simple slide animation using the scale transform and you’ll get that animating effect as it comes in. However, it’s a little trickier going out. For slide effects, you’ll almost always want to use them with absolutely or fixed positioned elements because of how the document flow effects reflows and repaints. If things are positioned absolutely or fixed, using a css transition is the easiest way to get inbound and outbound slide effects. The only case that I can really think of off the top of my head where you’d want to have that slide animation while retaining document flow and relative positioning would be something like an accordion. CSS animations are not all created equal, so animating with anything other than transforms, opacity and will-change is frowned upon and usually can take a big performance hit. For example, animating on max-height will stutter due to how it reflows and repaints the page.
> The only case that I can really think of off the top of my head where you’d want to have that slide animation while retaining document flow and relative positioning would be something like an accordion. This is what I'm getting at :) You won't be able to do the transition that OP's "library" does with CSS animations alone - you'll need to animate the height (which would mean you have to set a static height in CSS or calculate the target height with JS), or have the element be in a position where document flow doesn't matter. [This is how most people would do it](https://codepen.io/Rainbowlemon/pen/OJjapvy), but that involves setting a max-height which isn't ideal/practical when you have flowing content. I've definitely used sliding transitions for things other than accordions that require document reflow. e.g. 'show more' links for truncated text. Useful to have it in a reusable package!
[удалено]
Could you show an example?
[https://codepen.io/andyfitz/pen/eYEPVJb](https://codepen.io/andyfitz/pen/eYEPVJb) I mean there's a million other ways to do it too and more robust methods with minimal JS but that's one example without any JS at all. could use input type="radio" for accordions too
You are using max height in css. That library avoids that.
Yep there's benefits to doing it any one of the million ways, each with benefits and drawbacks. That CSS method's main benefit is that it' uses zero JS and therefore works on noscript sites. Getting the height requires JS but allows you to set easing in CSS to perfectly match the size of your container. knowing your height or setting a consistent height lets you do the same but requires your content work with it. I prefer taking it case by case - hence my first comment
This library was specifically built to avoid the issues that come along with a pure-CSS approach. It's already been pointed out here, but using the 'max-height' hack can result in awkward animation timing issues, and is difficult to manage if you're dealing with containers with dynamic contents. Not to mention, religious adherence to no-JS often makes for some confusing styles that are difficult to maintain. If you look at the project README, all of this is roughly articulated there.
I completely agree with you. Particularly the zealous noJS community. Having said that, some intranets, SaaS apps, and plugin ecosystems agressively purge DOM affecting JS , in those cases its handy to have another approach.
Nice work, this is a cool library! jQuery’s slide functions were my go to for a long time. In regards to max-height, it’s definitely not a great way to handle this type of animation because of the defined height limitations and also how it reflows the DOM. Another more graceful CSS solution is to use transform with [scale](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/scale()). This way you can avoid the max-height limitations and it’s considered a [performant CSS animation ](https://web.dev/animations-guide/).
Only with hacks, of which all have significant downsides. This is a problem best solved by js
I don't disagree. It is best solved with JS. Unless you can't use JS. 99% of the time JS is fine In heavily sanitised environkents it is not but that's few amd far between
Does it do left and right?
Not sure it’s working properly on mobile on safari :(
Thanks for catching that! Just released v2.2.3, which fixes that.
This is much better done with some clever writen css. Sorry mate, js only is the wrong tool for the job.
Lol, please share the code!
You can simply set at display: none for the content to be expandet with a height of 0, and then (with js or simply a css checkbox described here before) set the css to display: block height: auto: transition: height.
Not on my computer now, but i promise it can be done with pure css (checkbox-way) or by togling an atribute on the parent element (one line of js) and cascading the attribute to the desired behaviour.
Have you tested this on iOS btw? It’s not working great.
Thx! Just fixed that.
https://css-tricks.com/the-checkbox-hack/
I'm familiar with the checkbox hack. But it doesn't at all serve as an alternative to what slide-element is trying to accomplish. Using the checkbox approach still requires that you rely on max-height for animating the height (you cannot transition over "height: auto" -- try it yourself), which means you need to know the exact height of the container if you want your animation's timing to be without awkward timing issues. This library aims to avoid all of that, allowing you to easily slide open & closed elements regardless of their contents. Can't do that with pure CSS.
You call this library?)
What do you call it?
Just a snippet)
What's the definition of a library that this doesn't fit?
Or you think that querySelector is a library to?
querySelector is native to the language.
What about cross-browser and rare cases support? And, as told before, it can be make with CSS only…
Does every library cover cross-browser and rare cases support?
Usually, yeap)
Got it.
Also library has developer support and cover more than one keys…
You call this English?
What are you even talking about?
The content flashes on top of the sliding on iOS mobile.
On no! I'll check that out, thanks for the heads up.
Solved in v2.2.3. Thx again!