7 ms·
Tree views in CSS
- martyalain 4y agoCool Kate and thank you for this smart code. You could have a look to your code rewritten in my small lambdaway project : http://lambdaway.free.fr/lambdawalks/?view=viewing_trees http://lambdaway.free.fr/lambdawalks/?view=viewing_trees
- martyalain 4y ago{{tree} {li {details open {summary Giant planets} {ul {li {details close {summary Gas giants} {ul {li Jupiter} {li Saturn} }}} {li {details close {summary Ice giants} {ul {li Uranus} {li Neptune} }}} }}}}
- thrwawy74 4y agoI like this a lot. I wish sidebery (firefox extension for vertical tabs) had a style like this. It's all I've ever wanted from vertical tabs but no one seems to get this right. If I could do it myself... Here's to hoping I can figure out how to make a react component of it :) (Thank you for showing us this!)
- jeroenhd 4y agoThe addon Tree Style Tabs has the option of adding your own CSS to style the tree view. I don't know the the HTML that renders the tabs is built up, but I'm confident that it's possible to replicate this style with some CSS tweaks.
- amadeuspagel 4y agoAlso seems useful for comment trees.
- DoctorOW 4y agoIIRC there was a Reddit alternative frontend that tried this to avoid using any JS and counterintuitively performance was awful. I think because this is somewhat obscure it's less optimized by browser vendors than DOM manipulation via JS.
- decasia 4y agoI love the hacker thought process of "Is there an HTML element that can hide and show content right out of the box (without js), and now can we borrow it to implement a completely different data structure that wasn't obviously part of its design?"
- timeon 4y agoIn old days (around the time when Yahoo switched from table design to css layout) people were hacking this with :hover. But mouse had to stay in the 'opened' content.
- hakre 4y agoI love that :hover trick, a well placed tag in back and the mouse does not leave the "opened" (active) content that easily. There is also :focus.
- layer8 4y agoExcept that native menus don’t really work like that. They have a nontrivial interplay between hovering and mousedown/mouseup that you can’t replicate with just CSS. Not to speak of the missing keyboard functionality.
- hakre 4y agoNative menus? When I need native menus, I use a GUI toolkit, you might have put too much of your concerns into my words. When I do "native" Menus in HTML I use lists und you can skip to navigation on top if you like but content comes first. And yes, the site works natively in a textmode browser.
- pjmlp 4y agoVersus the native GUIs approach of here is a control for doing what you want, and here is a clean architecture to design you own controls.
- deleted 4y ago[deleted]
- madeofpalk 4y agoI did something similar a while back in Github Issues markdown to show stats for files in the codebase that https://github.com/grafana/grafana/issues/46451#issuecomment-1065104201 https://github.com/grafana/grafana/issues/46451#issuecomment... Used nested details/summary, but not ul/li - It can be quite tricky to use the right level of whitespace to get GFM to render what you intended.
- pastinaaak 4y agoIs there a good JS part, a tree manager that comes close to a standard component? I`ve been looking for one the last few days. The closest i've found: https://www.naiveui.com/en-US/os-theme/components/tree https://www.naiveui.com/en-US/os-theme/components/tree Probably with html5 draggable and the amount of variation that it is hard to make a standard component.
- soylentgraham 4y agoI made one specifically for viewing & editing json. Has draggable reordering with rough rules, auto-editable-values, copes with live updates whilst user is using it and other bits and bobs. Maybe along the lines of what youre looking for? https://github.com/NewChromantics/WebComponent_TreeView https://github.com/NewChromantics/WebComponent_TreeView
- kosasbest 4y ago> A tree view (collapsible list) can be created using only HTML and CSS, without the need for JavaScript A bit tangential, but so much more should be done in CSS rather than resorting to JavaScript. One gripe I've always had are hamburger menus that fail to work with JS disabled. Most of my browsing is done with Safari on iOS and I've disabled JS on that browser since 1) I enjoy the privacy benefits 2) popup modals and other distractions are non-existent. You can code a hamburger menu that opens when you click on it, without JS. Yes, CSS is not just for styling it can also be used for functionality.
- krono 4y agoThe majority of those CSS "hacks" are not at all accessible, however. You'd get to browse the web without JavaScript, and millions of others would not be able to browse the web at all.
- chrismorgan 4y agoThis is what’s often (OK, almost always) missed with such JavaScriptless components: progressive enhancement with JavaScript, so that it works without JavaScript, and works better with just a little JavaScript. Most of the traditional CSS hacks can be made just as good as the JavaScript version designed with accessibility in mind without too much effort. Most of the time it’s just managing some ARIA attributes and no more. Occasionally you might add an extra supporting element or slightly restructure an existing one.
- BeFlatXIII 4y agoIs that a problem with the browsers not providing functionality that should be standard or is it a problem of custom components that need the JS for the dev to specify how they work?
- krono 4y agoNot entirely sure if I fully understand your question. To clarify, these CSS hacks often use checkbox inputs for isomorphic state management and that is simply incompatible with the semantics those elements are designed and expected to represent. ECMAScript is a browser standard and was specifically invented for adding interactivity like toggling a hamburger menu. Yes it's also used for less savoury business but that's not the end-user's fault and shouldn't be made into their problem.
- chrismorgan 4y agoThis is not what is typically called a tree view: this is collapsible nested lists. The differences are important, and very fiddly to reconcile. The key difference is that in a tree view, every node is focusable and has an action associated with activating it (which for parent nodes might be expanding/collapsing, but need not be), whereas with collapsible nested lists, only parent nodes are focusable, and their action is reserved and limited to expanding and collapsing. (You could make leaf nodes focusable and give them actions—e.g. make each one a link—but you can’t give parent nodes any other action, which is a fundamental limitation.) Here’s what tree views are: https://w3c.github.io/aria-practices/#TreeView https://w3c.github.io/aria-practices/#TreeView. This describes the functionality and interaction modes (including all the expected keyboard behaviours), with examples. One important secondary difference: the article said that “the standard keyboard interaction is supported automatically”, and this is true for collapsible nested lists, but false for a tree view. In the former, each parent node is separately focusable, and you expect to use Tab/Shift+Tab to navigate between parent nodes; but tree views are composite widgets that manage focus, only appearing once in the tab order and using other keys (like the arrow keys) to manipulate focus within. Is it possible to implement a true tree view with <details>? Mostly, yes, but there are limitations and difficulties. If you’re OK with parent nodes’ only action being to toggle expansion, it’s not particularly hard; do it largely as shown in this article, making each leaf node focusable, and add some (nicely optional) JavaScript to get the keyboard interactions right and give the right ARIA attributes. The ARIA Authoring Practices document already linked will guide you through approximately all of the considerations. (If you haven’t worked with this document before, please do read the “Read Me First” section first.) In fact, I strongly recommend this general approach: make something that functions with only the HTML, then enhance it with JavaScript. If you want parent nodes to have actions, parent nodes’ actions will need to be moved out of the <summary>. You’ll end up with something like this: <ul class="tree"> <li> <a href>Giant planets</a> <details open> <summary>Expand</summary> <ul> <li> <a href>Gas giants</a> <details> <summary>Expand</summary> <ul> <li><a href>Jupiter</a></li> <li><a href>Saturn</a></li> </ul> </details> </li> <li> <a href>Ice giants</a> <details> <summary>Expand</summary> <ul> <li><a href>Uranus</a></li> <li><a href>Neptune</a></li> </ul> </details> </li> </ul> </details> </li> </ul> Focus and accessibility management will become a little more complicated, but it’s still workable. But styling will be at least somewhat painful because of the DOM structures and the order of things. You’ll probably want to use details::before for the marker. Grid and `details { display: contents }` might help with layout, though absolute positioning is probably the pragmatic approach (and test cross-browser before doing anything like `details { display: contents }`, the two features can have surprising interactions). Also in the absence of JavaScript, it’s not going to be possible to get the expected interaction order: you would want the focus order to be expand/collapse button, then the node itself, then children, but those first two will necessarily be transposed. Still, it’ll be better than it not working at all.
- alserio 4y agoAre summary-details ok to use yet? Last time I've checked, ammittedly some time ago, browsers had bugs and quirks around them.
- its-summertime 4y agoany issues should be easily enough to polyfill
- alserio 4y agoCss rendering issues weren't
- chrismorgan 4y ago• IE and EdgeHTML never supported <details>, so until comparatively recently you had to polyfill it. Now, you need not worry about this, because you should actively not support IE or old Edge. • WebKit still doesn’t use ::marker on summary. If you’re hiding the disclosure marker, you can’t just use `summary { display: block }` or `summary::marker { display: none; }`, and must remember to `::-webkit-details-marker { display: none }` as well. And if you want to change it, you can’t just change its list-style-type or manipulate ::marker, but must clobber the whole thing and use ::before or similar. (Aside: if you don’t use a Mac, Epiphany is a good WebKit-based alternative to Safari on other platforms that will exhibit most of the same behaviours and quirks as Safari.) Other than that, it’s all pretty solid now.
- alserio 4y agoThank you!
- spookie 4y agoMay I also recommend Falkon, as an Epiphany alternative! Really hoping the best for both projects!
- chrismorgan 4y ago
- mg 4y agoIt can actually be simplified further by skipping the <ul> and <li> elements and only using <details> elements: https://twitter.com/marekgibney/status/1593950777739218947 https://twitter.com/marekgibney/status/1593950777739218947
- 411111111111111 4y agodoesn't that make the desired styling impractical unless you replace them with divs? I dont think that would simplify it unless i'm mistaken
- mg 4y agoDo you mean the lines and the round buttons in the article?
- 411111111111111 4y agoyes, that styling was what the article was mostly about after all. The pure html was <10% of the article, the remaining 90+% were about the styling
- mg 4y agoThe styling is done via borders and ::before and ::after content applied to the nodes. Why would you not be able to do that with <details> elements? Here is a fiddle with the first step (borders on the left) applied: https://jsfiddle.net/qvb3udj6/ https://jsfiddle.net/qvb3udj6/
- kamranjon 4y agoI think probably the more concerning thing here is that you're removing the semantic value of HTML, in general I think you want to use the element that best suits your content. Lists make it easier for crawlers and screen readers to understand your website.
- franciscop 4y agoI made another totally different kind of "tree view" in CSS a while back, in this case to see some kind of JSON-html tree into a tree: https://francisco.io/demo/tree/ https://francisco.io/demo/tree/ It was a fork of a much earlier project but I improved it a lot IIRC; unfortunately I lost the original source and now chances of finding it are very small (unless someone here knows it!)
- nikodotio 4y agovery cool. Is it possible to collapse “sidebar” to “main”?
- refset 4y agoVery neat! Any ideas how to add correct vertical line heights with multi-line / variable-height items? e.g. the vertical line next to "Jupiter" here is too short https://gist.github.com/refset/c6f3ac05cacc12d547b4bc96bbeac8c8 https://gist.github.com/refset/c6f3ac05cacc12d547b4bc96bbeac...
- jkcxn 4y agoThis one works with variable height, you can pull some css from it https://codepen.io/khoama/pen/AoPeMM https://codepen.io/khoama/pen/AoPeMM
- refset 4y agoThank you! I guess the trick with this suggestion is to move the vertical line to directly beneath the text such that it doesn't need to be taller...which is probably a good enough workaround, even if not exactly what I was hoping for :)
- oever 4y agoThis summer I made a website to show the closest common ancestors of arbitrary species. The hardest part was to get the tree to look nice. It's still not perfect. A naive approach gives a very wide tree. https://sol.vandenoever.info/ https://sol.vandenoever.info/
- hirenj 4y agoWow, this is a really nice little tool! I usually end up manually traversing Wiki entries to get to this info, so it’s a great shortcut!
- nikodotio 4y agoI worked on a big project showing arbitrary family trees. Collapsing what are actually graphs into visually compact trees is very hard! Nice job
- deergomoo 4y agoThis is very clever, and it’s nice that it’s fully accessible and requires no JS. However, looking at that final CSS just makes me wish that we added new interface elements to HTML far more often. Folks run rings around themselves to implement things that have been in any desktop UI toolkit worth its salt since the 90s.
- mhitza 4y agoThere are so many ARIA guidelines on implementing alerts, modals, comboboxes and anything in between. Yet most don't have any equivalent presentational or functional counterparts in the existing browsers. Writing this comment, just as I'm writing an accessible combobox in a project where I'm not using any frontend framework and minimal JavaScript.
- eurasiantiger 4y agoLet’s extend this thought a bit deeper. Why are we consuming different brands of fixed-form content through bespoke interfaces? Why is there no standard for navigation of any type of content? I really hope RSS is coming back in force.
- marcosdumay 4y agoOn this case, the functionality is there right on the HTML, and the CSS is just customizing the appearance to make it look like a desktop widget. This is not an issue of lack of HTML support. In fact, this is exactly what CSS is for.
- Bilal_io 4y agoPerhaps the the Open UI unitiative is a good place to create a proposal. https://open-ui.org https://open-ui.org
- toastal 4y agoThey are really bad at first impressions. Do they not think about their own code? Literally the first thing I see when I visit the page is a misused <blockquote> > The blockquote element represents a section that is quoted from another source. — the W3 blocquote specification Their copy isn’t quoted from another source, it’s a janky admonition writers of Markdown use when their tools, Markdown, don’t support the semantics they mean. <blockquote> does not mean “put this in a box”. Click the navigation and the first things you see are links to GitHub and Discord, two very not open platforms—which should go against the philosophy of the project if they want open standards.
- Existenceblinks 4y agoMy app has some huge tree (CRUD-able). Say 20k-30k nodes (sweet spots for being usable without virtualizaion). And Chrome perf sucks real bad for "Recalculate Style" phrase" the `.tree ul li::before{content:''}` is going to be ruining perf. Meanwhile firefox is wicked fast for overall perf for lots of dom nodes.
- equalsione 4y agoWould you consider using d3.js? I’ve been able to get great performance for large deeply nested trees using d3. It depends on your use case of course.
- Existenceblinks 4y agoIt's 278.58kB(.min), I'm not sure how good its tree shaking is. I pick every js dependency seriously. Generally libs < 7kB gzip for each.
- greggman3 4y agoI recently used details and summary for a tree view in react and ran into this bug https://stackoverflow.com/questions/74313572/what-does-this-recursive-react-using-usestate-fail/74313675#74313675 https://stackoverflow.com/questions/74313572/what-does-this-... Just passing on info if you decide to use details in react
- piskerpan 4y agoYou’re complicating the two elements; They are interactive without javascript. Your answer is listening to native “open” change event, then reading this value and setting it back to the attribute via JSX. If the event happens at the wrong time, you’re possibly reading the previous value (closed) and setting it back to the details element. I’d either avoid details in your case or see how others are using it.
- greggman3 4y agoI am not, as I need to state of the details to be settable. That's the whole mo of react, that all UI state is under your control and has a single source of truth. For example you want a tree of files, give the user a search function, and want to expand/collapse any subtreee that contains/does not contain a result. Details is a collapsable building block. that's it.
- c-smile 4y agoFor what it's worth... In Sciter you can simply define tree view as <select type="tree">: <select type="tree" treelines> <option> <caption>Giant planets</caption> <option> <caption>Gas giants</caption> <option>Jupiter</option> <option>Saturn</option> </option> <option> <caption>Ice giants</caption> <option>Uranus</option> <option>Neptune</option> </option> </option> </select> And you will get: https://sciter.com/wp-content/uploads/2022/11/select-tree.png https://sciter.com/wp-content/uploads/2022/11/select-tree.pn... Tree view is quite popular in desktop UI, so I've decided to add it as built-in. And needless to say, that rendering of a tree is just one part - it should also be keyboard navigation and other a18y things. As of tree lines themselves: :scope[treelines] option > option { display: list-item; list-style-type: tree-line; // <<<< Sciter's CSS++ list-marker-size:1px; list-marker-color:#ccc; list-marker-style:solid; }
- xjlin0 4y agoThat's so cool! Where can I find more similar topics on JS-free implementation of "tree", "fixed table header", etc? Thanks!
- ssttoo 4y agoSeveral examples in this article: https://calendar.perfplanet.com/2020/html-and-css-techniques-to-reduce-your-javascript/ https://calendar.perfplanet.com/2020/html-and-css-techniques...
- _HMCB_ 4y agoBest post this week on HN. Love it.
- dmix 4y ago> margin-left : calc(var(--radius) - var(--spacing)); Can you use calc in modern browsers these days without transpilers?
- sphars 4y agoYes, all major browsers support calc() and have for a while now https://caniuse.com/calc https://caniuse.com/calc https://developer.mozilla.org/en-US/docs/Web/CSS/calc https://developer.mozilla.org/en-US/docs/Web/CSS/calc