JSFiddle - React, Tailwind, and code Playground
HTML
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css">
<ol style="list-style-type: none; padding: 0em;">
<li>
<input class="expander" type="checkbox"><i>Step one</i>
<ol>
<li>big ol paragraph of stuff</li>
<li>
<input class="expander" type="checkbox"><i>Nesting works! :)</i>
<ul>
<li>big ol paragraph of stuff</li>
</ul>
</li>
</ol>
</li>
<li>
<input class="expander" type="checkbox"><i>Step two</i>
<ol>
<li class="file">File 1</li>
</ol>
</li>
<li>
<input class="expander" type="checkbox" checked><i>Just set input to "checked" to open by default</i>
<ol>
<li class="file">File 1</li>
</ol>
</li>
</ol>
<hr>
<input class="expander caret" type="checkbox"><i>Works for generic elements, not just a tree!</i>
<pre>
highlights:
* leveraging (hidden) checkbox element to maintain expand/collapse state
not an original idea, from here: http://www.thecssninja.com/css/css-tree-menu
but like how was able to boil extra elements and css down to a
single additional checkbox to enable the whole effect
* sporting font-awesome icons for expand/collapse widgets instead of hidden input widget via :before { content: "\fxyz" }
http://fortawesome.github.io/Font-Awesome/icons/
</pre>
CSS
/* highlights:
* leveraging (hidden) checkbox element to maintain expand/collapse state
not an original idea, from here: http://www.thecssninja.com/css/css-tree-menu
but with a little less fluff
* sporting font-awesome icons for expand/collapse widgets instead of hidden input widget via :before { content: "\fxyz" }
http://fortawesome.github.io/Font-Awesome/icons/
*/
/*markdown renderers tend to add extra empty p tags*/
p:empty {
display: none;
}
/* hide the native checkbox widget */
input.expander {
opacity: 0;
cursor: pointer;
margin: 5px 0;
position: absolute;
}
/* main settings for the visible "expander" element */
input.expander + p + *:before, /*handle extra p tag inserted after heading tags*/
input.expander + *:not(p):before { /*everything else normal */
content: "\f196 "; /*fa-plus-square-o - these codes can be found on the detail page for each fa icon*/
font-family: FontAwesome;
cursor: pointer;
width: 1em;
display: inline-block;
/*font-size: larger;*/
color: blue !important;
}
input.expander + p + * {
display: inline-block;
}
input.expander + i {
font-style: normal;
}
/* change the icon in the expanded state, i.e. checkbox checked = expanded */
input.expander:checked + p + *:before,
input.expander:checked + *:not(p):before {
content: "\f147 "; /*fa-minus-square-o*/
}
/* alternative caret icon look */
input.expander.caret + p + *:before,
input.expander.caret + *:not(p):before {
content: "\f0da";
}
input.expander.caret:checked + p + *:before,
input.expander.caret:checked + *:not(p):before {
content: "\f0d7";
}
input.expander + p + * + *,
input.expander + *:not(p) + * {
transition: all 0.5s ease-in-out;
}
input.expander:not(:checked) + p + * + *,
input.expander:not(:checked) + *:not(p) + * {
overflow-y: hidden;
height: 0;
transform: scaleX(0) scaleY(0);
opacity: 0;
margin: 0;
}