Tree views in CSS
iamkate.com
iamkate.com
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.
This is not an issue of lack of HTML support. In fact, this is exactly what CSS is for.
I really hope RSS is coming back in force.
> 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.
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.
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.
Which is a shame because there’s something very elegant about using CSS. It’s usually much more performant.
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.
The one mentioned in the article, does not use checkboxes.
It uses functionality built into HTML itself
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.
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!)
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.
{{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}
}}}
}}}}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;
}https://stackoverflow.com/questions/74313572/what-does-this-...
Just passing on info if you decide to use details in react
I’d either avoid details in your case or see how others are using it.
Details is a collapsable building block. that's it.
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.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.
Probably with html5 draggable and the amount of variation that it is hard to make a standard component.
• 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.
Here's to hoping I can figure out how to make a react component of it :)
(Thank you for showing us this!)
Can you use calc in modern browsers these days without transpilers?
The pure html was <10% of the article, the remaining 90+% were about the styling
Here is a fiddle with the first step (borders on the left) applied:
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?
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.