Horizontal Accordion of Links

I'm working on an interface for reviewing videos: https://pairs.trwb.live. One of the UI elements I would like are buttons on the left-hand side of the screen that, when clicked, expand to a set of options. Currently I have code like:
label:has(input:checked) ~ ul li {
&:nth-of-type(1) {
left: calc(1 * var(--item-width));
}
&:nth-of-type(2) {
left: calc(2 * var(--item-width));
}
&:nth-of-type(3) {
left: calc(3 * var(--item-width));
}

label:has(input:checked) ~ ul li {
&:nth-of-type(1) {
left: calc(1 * var(--item-width));
}
&:nth-of-type(2) {
left: calc(2 * var(--item-width));
}
&:nth-of-type(3) {
left: calc(3 * var(--item-width));
}

The problem is the elements aren't all the same width, so there's some overlap. Can I achieve this effect without hard-coding --item-width? Also, the effect I would really like to have is the first option appears, then the second from below that, then the third, and so on. I guess for that I could use animation-delay… I want for the expansion time to be the same regardless of how many elements there are, but I assume I could use a calc to work that out. In any case, I've ported my existing code to a CodeSandbox: https://codesandbox.io/p/sandbox/folding-menu-test-vvh3q5?file=%2Fcomponents%2FFoldingMenu.module.css%3A34%2C1-44%2C1
5 Replies
Chris Bolson
Chris Bolson13mo ago
can't you use 100%? I can't get your codesandbox link to actually do anything on click so I haven't been able to fully understand what you are doing ah.... I see why I can't get it to work... you are using has()and I am using Firefox... OK, I have it working in Chrome - my idea of 100% does not work. Sorry.
Mannix
Mannix13mo ago
you can do 100% divided by number of items instead of setting a fixed value
dysbulic 🐙
dysbulic 🐙13mo ago
Users will have the ability to add new items, so it is possible the list will be wider than the screen. I was thinking has was available everywhere now. Good to know I ought to change the structure… I'm using the <label><input/></label> structure to avoid putting an id on the <input/> because there are multiple menus on the same page. I can generate a unique id though & use the <label for="…"/><input id="…"/> format and obviate the need for the has.
Chris Bolson
Chris Bolson13mo ago
Not a solution for the Firefox has() issue but a way to resolve the different widths issue could be let the "<li>"s keep their natural position within the parent and slide out the whole <ul> rather than each individual <li>. This would be less code and you wouldn't have to worry about the number of buttons. Something like this: https://codesandbox.io/p/sandbox/folding-menu-test-forked-jdkl7j?file=%2Fcomponents%2FFoldingMenu.module.css%3A25%2C39 I realize that this idea won't give you the accordion effect so maybe it isn't an option.
dysbulic 🐙
dysbulic 🐙13mo ago
Nah, I like the idea. I'll give that a shot. blobthx