Introduction
There are accessibility problems with the hidden checkbox hack used for many CSS only menus, including the one at the top of this page.
The HTML and CSS standards are changing all the time and one of the newest HTML tags being worked on is a fork of the <select> tag which was named <selectmenu> but currently named <selectlist>. The control was first announced in August 2020 but in January 2024 is still under development. I am excited about this new tag and foresee that at some time this will become the main menu for this site.
In the meantime I took a look at the <details> tag which was introduced around 2011, and what that can do. I particularly wanted to do this as the <details> tag is made to be accessible. It is both tabbable and can be opened and closed using either the Enter key or Spacebar.
Testing
This page was tested in Chrome (120.0.6099.200), Edge (120.0.2210.133), Forefox (121.0.1) and Opera (106.0.4998.28).
I couldn't think of or find a way of closing the details tag without using JavaScript, so JavaScript must be enabled for the tags to work properly.
Styling the <Summary> Tag Icon
The default arrow icon in the <summary> tag uses the list-style property. It can be removed by simply setting it's styling to "none", but the easiest way is to simply set the <summary> tag's display styling to "block".
Lorem Ipsum...
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
The CSS to do the above is:
.sumtestd { display:block; }
Alternatively, using the list-style property the following can be used:
.sumtestd {list-style: none} .sumtestd::-webkit-details-marker {display: none; }
The problem with the above that there is now no indication at all that the element is clickable. The <details> tag is both tabbable and can be opened and closed using either the Enter key or Spacebar, but there are other visual clues that can be used such as changing the cursor on the <summary> tag to cursor: pointer; changing the color on mouse hover, underlining the text, using a tooltip, adding a border and others.
Suppose you want to use your own icons instead of the default. First of all remove the default icons as in the last example then use the ::before CSS selecor to insert your own. I use the up/down triangle in my current menus, so I'll use those here...
Lorem Ipsum...
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
The CSS to do this is:
.sumteste { display:block; } .detteste .sumteste::before { content:"\25BC "; } .detteste[open] .sumteste::before { content:"\25B2 "; }
Using the ::after pseudo-selector the position of the icon can be moved to after the summary text...
Lorem Ipsum...
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
The CSS to do this is...
.sumtestf { display:block; } .dettestf .sumtestf::after { content:"\25BC "; } .dettestf[open] .sumtestf::after { content:"\25B2 "; }
The JavaScript used to close the tags when a new one is opened is as used before.
<script type="text/javascript"> document.querySelectorAll('.dettestc').forEach((D,_,A)=>{ D.ontoggle =_=>{ if(D.open) A.forEach(d =>{ if(d!=D) d.open=false })} }) </script>
A Full Menu
A test of what can be done with the <details> and <summary> tags would be to reproduce the main menu for the pages on this site:
The HTML for the above menu is:
<div id="menubar"> <details class="detmenu" id="detmenu1"> <summary>All Sections</summary> <div class="submenu"><!--#include virtual="/inc/main_menu.htm" --></div> </details> <details class="detmenu" id="detmenu2"> <summary>Web Section</summary> <div class="submenu"><!--#include virtual="/web/inc/web_menu.htm" --></div> </details> </div>
The includes are just adding unordered lists on the server.
The CSS for it is:
#menubar { width: 100%; height: 1.5em; background-color: midnightblue; color: white; font-family: Arial, Helvetica, sans-serif; font-size: 1.2em; position: relative; } .detmenu { display:inline-block; position: absolute; width: 100%; padding-top: 0.2em; } .detmenu summary { cursor: pointer; width: fit-content; padding 0 0.5em; } .detmenu summary:hover, .detmenu summary:focus { color: cyan; } .submenu { position: relative; display: block; cursor: pointer; background-color: midnightblue; } #detmenu1 { left: .5em; } #detmenu1 .submenu { left: -0.5em; } #detmenu2 { left: 8em; } #detmenu2 .submenu { left: -8em; } .submenu a:hover, .submenu a:focus { color: cyan; } .submenu ul { column-count: 6; padding: 0.5em; margin-top: -20px; } .submenu li { list-style-type: none; display:block; } .submenu a { color: white; text-decoration: none; }
The JavaScript for it is:
document.querySelectorAll('.detmenu').forEach((D,_,A)=>{ D.ontoggle =_=>{ if(D.open) A.forEach(d =>{ if(d!=D) d.open=false })}})
The above JavaScript came from Stack Overflow and may be too terse for maintainability, in which case one of the other snippets on the page can be used.
The number of columns in the submenus can be changed using media queries, for example:
@media screen and (max-width : 600px) { .submenu ul { column-count: 3; } }
The menu will still work with JavaScript turned off, but because of the number of links, I made the submenus the full width of the div they are in and repositioned them to left. This means they overlay eachother so the uppermost must be closed to see the open ones underneath. For single list menu items with no repositioning of the submenus, this should not be a problem, it just means all the currently selected submenus will be seen.
Sources and Resources
The <details> Tag
<details>: The Details disclosure element - MDN Web Docs
Automatically close all the other <details> tags after opening a specific <details> tag - Stack Overflow
Can I use details - Browser support for details & summary elements
CSS Selector Reference - W3Schools
Focusable Elements - Browser Compatibility Table - A nice table showing which HTML elements are focusable and tabbable
HTML <details> Tag - W3Schools
The details and summary elements, again - Interesting article by Scott O'Hara discussing the accessibility of the details tag
The Details Element - W3C Working Draft
Using <details> for Menus and Dialogs is an Interesting Idea - CSS Tricks
UTF-8 Geometric Shapes - W3Schools
Accessibility Checkers
AccessiBe accessScan - Online accessibility checker
Accessible Web - Online accessibility checker
AChecker - Online accessibility checker
ADAScan βeta - Online accessibility checker
axe DevTools - Chrome Browser Extension accessibility checker
Experte Accessibility Check - Online accessibility checker
Intent Based Accessibility Checker - Online accessibility checker
WAVE - Chrome Browser Extension accessibility checker
Web Accessibility Evaluation Tools List - W3C Web Accessibility Initiative
<selectlist> & <selectmenu> Tag
Add customizable select element, currently <selectlist> - GitHub
Customizable <select> Element - Chrome Platform Status
Open UI's <selectlist> demos - Microsoft Edge Demos
Say Hello to selectmenu, a Fully Style-able select Element - CSS Tricks
Selectlist Element - Open UI
Styling 'select' elements for real - Microsoft Windows Blog