Closed bob2517 closed 1 year ago
Good morning, my friend! Long time no coms. Hope all is well across the pond.
Have you tried this approach? Replace the height with max height so that the height of the container does not overcome the actual size of the container or box and it actually works as auto. Secondly, we set the after-transition to “auto” instead we have to set it to a value that the container or box will never attain. ~ https://www.geeksforgeeks.org/how-to-make-transition-height-from-0-to-auto-using-css/
Video example with Grid and Flex layouts: ~ https://www.youtube.com/watch?v=B_n4YONte5A
Good morning! All good thanks. Hope all good with you.
Hmmm... thanks for that suggestion. That's a good point. The only thing to check is does it give an even transition on elements of varying heights? In other words does it take 1 second to expand a small div and 1s to expand a large div, so it takes the same amount of time to expand both divs fully? Ie. do the transitions for both the small and large divs finish at the same time?
Just need to check that. If it's fine then I'll close this issue as a red herring.
Yes, timing, regardless of distance, can be controlled via the timing function.
https://developer.mozilla.org/en-US/docs/Web/CSS/transition-timing-function
Yes indeed - just need to check if setting the max-height to 999999px on a small container of 200px gives us an inappropriately fast transition effect when setting the speed to 1s. If it's fine, then I'll close this issue.
Changing these to slide-up and slide-down to make them more obvious to people what this supposed to be used for. CSS will be needed for the transition, and the docs will show how that is done.
Checking the min-height solution. It's messy when used on its own. The solution I have used previously which got me onto doing this issue was to dynamically set the height to the actual size of the container at the point of click. This enables a smooth transition effect which doesn't create ugly jumping of sizes at the point of slide up or down.
Note to self - in the core, set up events to sort out the expanded els at point of resize and orientation change so it's a complete solution:
window:resize,
window:orientationchange {
/* Adjust any "open" accordion sections so they are the correct size. */
ul.slidingOptions > li.listItemSelected > div:nth-of-type(2) parallel {
height: auto;
height: {= o.secSelObj.offsetHeight + "px" =} after stack;
}
}
Now on branch. Example code to follow.
ACSS:
li:not(.opened) .header:click {
& < li {
add-class: .opened;
}
slide-down: & + .slideable;
}
li.opened > .header:click {
& < li {
remove-class: .opened;
}
slide-up: & + .slideable;
}
#openAll:click {
slide-down: .slideable;
li {
add-class: .opened;
}
}
#closeAll:click {
slide-up: .slideable;
li {
remove-class: .opened;
}
}
HTML:
<button id="openAll">Open all</button>
<button id="closeAll">Close all</button>
<ul>
<li>
<div class="header">
<div class="arrow">↓</div>
<div class="title">Option 1</div>
</div>
<div class="slideable">
<div class="description">
Lorem ipsum
</div>
</div>
</li>
<li>
<div class="header">
<div class="arrow">↓</div>
<div class="title">Option 2</div>
</div>
<div class="slideable">
<div class="description">
Lorem ipsum
</div>
</div>
</li>
<li>
<div class="header">
<div class="arrow">↓</div>
<div class="title">Option 3</div>
</div>
<div class="slideable">
<div class="description">
Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum
</div>
</div>
</li>
</ul>
CSS:
:root {
--slideSpeed: 1s;
}
ul {
position: relative;
width: 600px;
list-style-type: none;
}
li {
position: relative;
margin: 0 0 10px;
color: white;
user-select: none;
cursor: pointer;
}
li .header {
padding: 10px 20px;
background-color: darkslategray;
}
li .header > .arrow {
float: right;
transform: translateY(-2px);
transition: transform var(--slideSpeed) ease-out;
}
li.opened .header > .arrow {
transform: translateY(1px) rotate(-180deg);
}
li .slideable {
height: 0;
transition: height var(--slideSpeed) ease-out;
overflow: hidden;
}
li .description {
width: calc(100% - 20px);
margin: 10px;
padding: 10px 20px;
background-color: lightgreen;
}
Syntax:
slide-up: (selector);
slide-down: (selector);
Selector can refer to a single element or a set of elements.
Don't add a margin or a padding to the element that is sliding. If you need a margin or a padding inside the sliding container, set them inside the container and not on the sliding element itself.
Still need to add the resize and orientation change events on this issue.
Orientation change handled after slide down transitionend by setting height to auto. Now on branch.
Closing in preparation for release.
When I make accordions with containers of height auto, I use a run command to max out the height when expanding and another to set to 0 when contracting. I use regular CSS transitions on the height, padding and margins of the inner containers to animate the slide.
Rather than show the run command hack, and it does look like a hack, I'm going to put this into an ACSS command, so they can be used with CSS transitions. I don't think it's a good idea to do a jQuery slideUp/slideDown, as those have limitations by their nature, and devs should learn standard CSS transitions as they are not hard to learn if an effort is made.
Hopefully one day CSS will be able to handle transitions on a height auto (which could be done these days if it's relooked at - need to confirm it doesn't already do it and I've just missed it), but meanwhile the new command will be:
A full accordion example will be in the docs when this goes up.