Sliding expandable inline menu
-
30-06-2021 - |
Question
I had a concept for a simple (in appearance) menu which expands and retracts submenus using only CSS.
This is what have conceptualized:
<ul>
<li><a href="#">home</a></li>
<li><a href="#">main one</a>
<ul>
<li><a href="#">sub one</a></li>
<li><a href="#">sub two</a></li>
<li><a href="#">sub three</a></li>
</ul>
</li>
<li><a href="#">main two</a>
<ul>
<li><a href="#">sub one</a></li>
<li><a href="#">sub two</a></li>
</ul>
</li>
<li><a href="#">main three</a></li>
</ul>
I have coded the basic framework above (ignore lack of classes, ids, pipe symbols etc.) using nested unordered lists, but I'm having trouble keeping everything inline. All lists are list-style-type: none
and all list items are floated left.
Also, I don't know how to prevent the word wrapping so that the whole list item is moved to a new line as a whole instead of being broken in two.
Additionally, what property could I use in conjunction with the transition property to make the nested lists slide out on mouse click?
Solution
I can think of two methods:
1. Using a:focus + ul
(a:active + ul
for IE) to make the menu expand on click.
Advantages:
- it has excellent browser support: works as intended even in IE8; somewhat in IE7, though you need to hover off the link to see the menu expanding;
- preserves your current HTML structure, you just need to add
tabindex='1'
to the links you want to trigger an action when clicked (like an expanding submenu)
Disadvantages:
- you cannot have multiple submenus in the 'expanded' state at once;
- it is not persistent; this means that once you click somewhere else in the page, the link that expanded the submenu loses focus => the submenu colapses;
How it works:
a:focus
selects the link that has focus (a link gets focus after being clicked and it keeps focus until something else is clicked)a:focus + ul
selects the unordered list (ul
) that is a sibling of the link that has focus (after being clicked in this case) and comes right after it (= there is no other element between them) in the HTML - see this: adjacent sibling combinatora:focus + ul li
selects the list item that is a descendant of the unordered list described abovea:focus + ul a
selects the link that is a descendant of the unordered list described above
2. Using the checkbox hack.
Advantages:
- you can have multiple submenus expanded at once;
- it is persistent; expanded menus don't collapse when you click somewhere else on the page;
Disadvantages:
- you need to change your HTML structure;
- doesn't work in IE8 or older;
How it works:
input[type=checkbox]:checked
selects checked checkboxes; the checkboxes are hidden here (setdisplay: none
on them), but clicking on alabel
checks the checkbox whoseid
is the same as the value of thefor
attribute of thelabel
that was clicked;input[type=checkbox]:checked ~ ul
selects the unordered list that is a sibling (not necessarily adjacent) of the checked checkbox - see this: general sibling combinator
OTHER TIPS
set main one child to
display:none;
and on hover of main one
set them to
display:block;