CSS3 Treeview. No JavaScript.

Try Semtex – the new HTML5, CSS3 and JavaScript UI framework!

NOTE: You may want to check the new version of the treeview with added support for nested nodes selection and updated look and feel.

Can you believe that the treeview on the image below does not use any JavaScript, but relies only on CSS3?

Go to the live example

CSS3 Treeview. No JavaScript.

Today I’m going to show you a really easy and absolutely JavaScript-less solution for creating multi-level treeviews with minimal markup and with the power of CSS3. Basically what we need is a simple list:

<div class="css-treeview">
    <ul></ul>
</div>

… With any number of nested items and subtrees. Each item that is going to be a container of a subtree should be supplied with a label and a checkbox.

Normal (non-clickable) item:

<li><a href="./">item</a></li>
<li><a href="./">item</a></li>

Expandable (clickable) submenu item:

<li><input type="checkbox" id="item-0" /><label for="item-0">folder</label>
    <ul>
        <li><input type="checkbox" id="item-0-0" /><label for="item-0-0">folder</label>
            <ul>
                <li><input type="checkbox" id="item-0-0-0" /><label for="item-0-0-0">folder</label>
                    <ul>
                        <li><a href="./">item</a></li>
                        <li><a href="./">item</a></li>
                        <li><a href="./">item</a></li>
                        <li><a href="./">item</a></li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</li>

Making it work is pretty simple and straightforward. All we need is to query the normal and :checked states of the checkboxes and set the adjacent <ul /> element to visible or hidden in the stylesheet:

Unchecked checkbox:

.css-treeview input + label + ul
{
    display: none;
}

Selected checkbox:

.css-treeview input:checked + label + ul
{
    display: block;
}

For aesthetic purposes we hide the checkboxes like this:

.css-treeview input
{
    position: absolute;
    opacity: 0;
}

It is recommended to hide the checkbox with position/opacity rather than with display: none, otherwise you will have problems with certain browsers.

If your treeview is going to contain disabled subtrees, you can utilize the :not() selector, so disabled items with submenus will not be clickable:

.css-treeview input:checked:not(:disabled) + label + ul
{
    display: block;
}

The visual representation of the disabled items can be accomplished by changing the opacity and the cursor of the label element:

.css-treeview input:disabled + label
{
    cursor: default; /* or no-drop */
    opacity: .6;
}

Finally, for the +/- buttons on the left, we can use generated content with the :before pseudo element:

.css-treeview label,
.css-treeview label::before
{
    background: url("icons.png") no-repeat;
}

.css-treeview label::before
{
 content: "";
 width: 16px;
 margin: 0 22px 0 0;
 vertical-align: middle;
 background-position: 0 -32px;
}

.css-treeview input:checked + label::before
{
 background-position: 0 -16px;
}

All of the icons that have been used in the example are in the icons.png sprite. The solution will work with any browser supporting the adjacent element selector (E + E) and the attribute selectors of CSS3. Do not forget that the values of the for/id attribute pairs for the label and checkbox elements should be unique, otherwise the treeview will not work. Tab/Spacebar navigation is supported natively. The demo is availble on this page, or you can download it straight away from this link.

Of course this is just the basic concept that you can use for inspiration. A few ideas that can bring you even further:

– By adding the disabled attribute to a checkbox in your markup, the nested subtree will become expanded by default.
– You can use the cool CSS3 transitions to achieve cool behaviors.
– You can use additional classes to display different “folder” items.
– You can use :hover in order to show the pluses and minuse only when the treeview is hovered.
– You can use an additional class name that will show the pluses and minuses only when applied.
– You can use the attribute selectors to display different icons for each normal item according to the extension in the href attribute, for example:

li a[href$=".js"]
{
    background: url("js.png") no-repeat center;
}

li a[href$=".css"]
{
    background: url("css.png") no-repeat center;
}

This solution works with all modern browsers and Internet Explorer 9+. If you are interested in purchasing a JavaScript enabler for IE8 for the CSS3 Treeview, please, click here.

View the demo and find more experiments here.

Related Posts