Pure CSS collapsible tree menu
The classic tree view, we all know it, it’s used everywhere and it definitely can be useful in the right context. I’ve seen various examples about doing it with CSS and they’ve all required JavaScript. Not content with any of those solutions I investigated doing it with pure CSS, I got a good head start from my Custom Radio and Checkbox inputs article. From there I’ve come up with a solution that works pretty well.
Another demo, another bug
Everything I seem to investigate lately seems to present itself with an annoying bug/feature in various browsers. Last time it was the inconsistency between browsers and generated content on form elements. This time it is WebKit not being able to apply styles using the checked pseudo-class in conjunction with a general sibling combinator (E ~ F
) or chained adjacent sibling combinator (E + F + F
). Making it very hard, and probably the reason I haven’t seen a CSS solution that works in WebKit browsers. I did come across this demo but due to the bug mentioned above doesn’t work in WebKit browsers.
So I soldiered on and came up with a pretty decent attempt, and remember folks I’m not a designer so be kinder this time with design critiques all I’m doing is showing you how to do the technique ;). With that out of the way let’s dig into the inner workings and road blocks I faced.
General sibling combinators are flaky
The CSS3 selector module has a very useful addition to compliment the CSS2.1 adjacent sibling combinator. Unlike the adjacent selector the general selector gives us some flexibility in that it will match a sibling that isn’t immediately preceded by our first element.
Great, I have 3 elements an , & the general sibling combinator is the perfect tool to do things like input:checked ~ ol
. Check Firefox, awesome works, Opera too! Woo! Surely WebKit will have this…nope nothing. Let me try input ~ ol
, yep works across the board, *face palm*.
So I dug into WebKits bug tracker and came out with this bug which has been around since 2007. Stating that general sibling combinators in combination with dynamic CSS, ala :checked
, won’t reflect changes. Nor will it do chained adjacent combinator which was going to be my next solution.
However doing :checked
with a single adjacent sibling combinator works fine in post 2008 WebKit browsers. So using this information I went about and built a working demo that has good browser support.
The demo is built using an ordered list (ol) nested with further ordered lists to naturally represent a basic folder structure.
As you can see, in order to get around the general combinator issue in WebKit based browsers I have switched the label to come first then the input so the “folders” could be expanded/collapsed by checking/unchecking the checkbox.
To sit the input and label in the right visual order I absolutely positioned the input and applied a left padding to the label to push it out. That way changing the styles of the child ol, when the input is checked, can be done using the adjacent sibling combinator. I’ve also set the cursor to pointer when hovered over the input or label to visual show they’re clickable.
Unlike my custom radio and checkbox article where I added the background image on the label, this time I had to do some trickery and apply it to the direct sibling ol of an input. Applying a sprite image to the ol wouldn’t be possible in this situation due to it being applied to the ol which would make it difficult to effectively hide other images within the sprite image.
To position the ol correctly I use a negative margin to pull it into the right location so it will sit next to the label and underneath the invisible checkbox.
To hide the sub folders so they don’t appear when the parent folder is collapsed I target the child list items and set them to, a zero height and hide any overflowAndy pointed out that I could just use display: none over height, this also stops the keyboard navigation from tabbing into non expanded items as they’re now hidden.
- Related:
- Futurebox, lightbox without the javascript and target pseudo-class
- Custom radio and checkbox inputs using CSS
- Futurebox, revisited
- Create the accordion effect using CSS3
- Real text rotation with CSS
- Futurebox, lightbox without the JavaScript
- Chroming: How google is changing the browser
- Don’t kill IE6, degrade it.