[HN Gopher] Tree views in CSS
___________________________________________________________________
Tree views in CSS
Author : divbzero
Score : 319 points
Date : 2022-11-19 05:31 UTC (17 hours ago)
(HTM) web link (iamkate.com)
(TXT) w3m dump (iamkate.com)
| alserio wrote:
| Are summary-details ok to use yet? Last time I've checked,
| ammittedly some time ago, browsers had bugs and quirks around
| them.
| its-summertime wrote:
| any issues should be easily enough to polyfill
| alserio wrote:
| Css rendering issues weren't
| chrismorgan wrote:
| * 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 wrote:
| Thank you!
| madeofpalk wrote:
| I 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...
|
| 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.
| Existenceblinks wrote:
| My 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 wrote:
| Would 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 wrote:
| It'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.
| mg wrote:
| It can actually be simplified further by skipping the <ul> and
| <li> elements and only using <details> elements:
|
| https://twitter.com/marekgibney/status/1593950777739218947
| 411111111111111 wrote:
| doesn'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 wrote:
| Do you mean the lines and the round buttons in the article?
| 411111111111111 wrote:
| yes, 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 wrote:
| The 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/
| kamranjon wrote:
| I 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.
| mg wrote:
| I would be interested to try that out.
|
| I just went through the whole first page of Google
| results for "screen reader simulator" and none worked
| without installing extra software.
|
| Is there a website, where you can test how a given piece
| of html is interpreted by screen readers?
| asadotzler wrote:
| Use Narrator, Window's built in screen reader, or, even
| better, install NVDA. It's free and open source. It's
| also the majority screen reader on Windows. (If you're on
| a Mac, you've got VoiceOver built in.)
| kamranjon wrote:
| Here is a good summary:
| https://accessibility.princeton.edu/how/content/lists
|
| WAVE is a great browser extension to have for frontend
| developers: http://wave.webaim.org/extension/
|
| It helps you identify aspects of your design that might
| not be accessible.
| kosasbest wrote:
| > 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_.
| chrismorgan wrote:
| It's worth noting here that it's _HTML_ that's doing the actual
| heavy lifting here, rather than CSS--the CSS is just making it
| look prettier.
|
| Something like the venerable checkbox hack is a case of CSS
| providing the functionality. That's imperfect.
|
| <details> is _HTML_ providing the functionality. That's the
| ideal.
| krono wrote:
| The 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.
| BeFlatXIII wrote:
| Is 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?
| bobthepanda wrote:
| browsers do provide that functionality, just with JS.
|
| CSS is not designed, to be something you're supposed to
| write Doom in even though you can. It hasn't been really
| updated with the purpose of 'obviate javascript' because
| the browsers don't really want to do that.
| krono wrote:
| Not 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 wrote:
| This 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.
| Waterluvian wrote:
| 99% of users don't make a fuss about javascript and the
| developers know. It would probably be wrong to get so
| distracted by satisfying a tiny sliver of user base (the
| pickiest sliver?) with a disproportionate share of work.
|
| Which is a shame because there's something very elegant about
| using CSS. It's usually much more performant.
| pastinaaak wrote:
| Is 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
|
| Probably with html5 draggable and the amount of variation that it
| is hard to make a standard component.
| soylentgraham wrote:
| I 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
| _HMCB_ wrote:
| Best post this week on HN. Love it.
| xjlin0 wrote:
| That's so cool! Where can I find more similar topics on JS-free
| implementation of "tree", "fixed table header", etc? Thanks!
| ssttoo wrote:
| Several examples in this article:
| https://calendar.perfplanet.com/2020/html-and-css-techniques...
| deergomoo wrote:
| This 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.
| marcosdumay wrote:
| On 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.
| mhitza wrote:
| There 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 wrote:
| Let'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.
| Bilal_io wrote:
| Perhaps the the Open UI unitiative is a good place to create a
| proposal.
|
| https://open-ui.org
| thrwawy74 wrote:
| I 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 wrote:
| The 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.
| chrismorgan wrote:
| This 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. 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.
| amadeuspagel wrote:
| Also seems useful for comment trees.
| DoctorOW wrote:
| IIRC 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.
| dmix wrote:
| > margin-left : calc(var(--radius) - var(--spacing));
|
| Can you use calc in modern browsers these days without
| transpilers?
| sphars wrote:
| Yes, all major browsers support calc() and have for a while now
|
| https://caniuse.com/calc
|
| https://developer.mozilla.org/en-US/docs/Web/CSS/calc
| c-smile wrote:
| For 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.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; }
| martyalain wrote:
| Cool 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
| martyalain wrote:
| {{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} }}} }}}}
| decasia wrote:
| I 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 wrote:
| In 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 wrote:
| I 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 wrote:
| Except 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 wrote:
| Native 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 wrote:
| Versus 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.
| mananaysiempre wrote:
| The native GUI approach seems to struggle with extending the
| behaviour of stock controls, Win32 most of all. Granted, this
| is a very fuzzy problem that's much more difficult than it
| seems (how do you shouls a CJK-style IME interact with a
| formatted-alphanumerics input?), and HTML+CSS doesn't really
| do better, but it's also a problem people have, and I don't
| think native toolkits have a convincing approach. So I'm not
| ready to declare UI toolkits solved.
| franciscop wrote:
| I 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/
|
| 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!)
| [deleted]
| greggman3 wrote:
| I recently used details and summary for a tree view in react and
| ran into this bug
|
| https://stackoverflow.com/questions/74313572/what-does-this-...
|
| Just passing on info if you decide to use details in react
| piskerpan wrote:
| You'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.
| oever wrote:
| This 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/
| hirenj wrote:
| Wow, 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!
| refset wrote:
| Very 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/c6f3ac05cacc12d547b4bc96bbeac...
| jkcxn wrote:
| This one works with variable height, you can pull some css from
| it https://codepen.io/khoama/pen/AoPeMM
| refset wrote:
| Thank 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 :)
___________________________________________________________________
(page generated 2022-11-19 23:01 UTC)