11 ms·
Accessible hamburger buttons without JavaScript
- robertoandred 4y agoExcept it doesn't actually perform well with keyboard navigation. Focus states are inconsistent and the spacebar doesn't work. And where are the aria attributes?
- enyo 4y agoLearn how to create an accessible hamburger button with pure HTML and CSS and why that is important.
- techn00 4y agoUnrelated: the image on the home page has a low resolution and doesn't look good ...
- enyo 4y agoWhich image (and which browser)?
- techn00 4y agoThe CTA one, looks fuzzy to me (both firefox and chrome) https://i.imgur.com/xVXWiGn.png https://i.imgur.com/xVXWiGn.png Resolution: 2k and 1080p
- enyo 4y agoThanks for letting me know! Seems to happen because it’s not a high dpi screen. I’ll get on it.
- _n0ll 4y agoSecond one(the guy on his pc), vanadium
- swyx 4y agoproviding complete copy pastable code with good default styling would help improve the article
- LocalPCGuy 4y agoNot really super important, but thoughts on using an SVG when the same hamburger button affect can be generated with just a tiny bit of HTML/CSS? As little as one element with :before/:after for the top/bottom bars, although sometimes it needs a wrapping element for best styling.
- toastal 4y agoBTW, it's been ::before/::after (pseudo-element, not pseudo-class) since IE9 (2011).
- LocalPCGuy 4y agoOh sure, I am aware, just mis-typed it in the comment.
- Semaphor 4y agoNeat solution. Also interesting about `:target:`, I had not encountered that before.
- toastal 4y agoI don't know how I feel about using a CSS hack for this. This isn't a semantic element and a lot of other browsers like TUI browsers aren't sure what to do with this sort of element. In my experience in many cases, just showing all of the menu items when JS is disabled is an easier, safer solution with cleaner markup and no hacks. After JS is detected, toggle a class on the document to hide the menu, build your button, insert it into the DOM. Some menus are too big, but most are not and the kinds of sites that need big menus often require interactivity with JavaScript anyways.
- enyo 4y agoThat is a terrible user experience for SSR though and will lead to a layout shift every time the page is loaded. I wouldn’t really call this a CSS “hack” either. There is a checkbox that defines whether the menu is open, and CSS that styles the menu accordingly. I think that this is rather elegant really. As soon as the :has pseudo class has widespread support, the checkbox can also just live inside the nav element, which removes the awkward general sibling combinator.
- toastal 4y agoCorrect me if I'm wrong but it doesn't lead to layout shift if you attach that "has-js" or remove the "no-js" class from the document if the script is in the <head> without async/defer or so it's executed before the body and CSS are even rendered. Doing this is useful for styling other <noscript> other related situations as well. Using a checkbox is a hack in that you are using a <input> but not as a part of a form. The vestigial element gets rendered in all sorts of contexts where the CSS isn't downloaded or used. And even still, to get the ARIA you need for this menu to be accessible, you'll need to invoke JavaScript for to set the element attribute states anyhow. The anchor is a hack as well because it's not being used to link to any ID on in the document. I also just gave this author's site a go. If I checked the box by using the keyboard, I can't close it with the mouse (or vise versa). It's a little funny as well since the menu items fit on the site without needing to make a menu button and at a small enough breakpoints it doesn't even break the items into multiple lines. Perhaps this is the anchor that's getting hit in the other case. ...And if the author had concerns about JavaScript, they would have done the syntax highlighting on the server side as well. I wish there was an existing element for developers to just use though since it's a common pattern at this point. Then we wouldn't need to use said hacks or involve JavaScript that many users disable by default for security/privacy.
- ElectricalUnion 4y agoI believe the details/summary tag has most of the builtin behaviour one would expect of a hamburger menu, but those are usually unfortunately not well supported by common browser accessibility tools. https://adrianroselli.com/2019/04/details-summary-are-not-insert-control-here.html https://adrianroselli.com/2019/04/details-summary-are-not-in...
- detritus 4y ago> "Over the last few decades hamburger buttons have become the de facto standard to expand larger menus on smaller devices. They are so ubiquitous that every user immediately knows what they are when seen in the top left or right corner, which makes them a good user interface element choice." "Last Few Decades"? Eh? A decade.. perhaps? "Every User Immediately"? This is not at all my experience. Perhaps with younger users, but I've seen plenty of people younger than I even stumble over sites where the nav was hidden behind a hamburger menu icon. This sounds like it was written by someone very much in their own bubble
- dwringer 4y agoThis immediately made me think of Wikipedia's latest change that moves their main menu behind just such a hamburger button on desktop, and replaces it with a table of contents down the left side. Now instead of lazily clicking from one random article to the next (or to a different language, or to "current events", or the "main page" of headline articles), one has to move the mouse twice and make two clicks to get to it through the hamburger menu, or use the URL bar. I can't even remember the last time I went back to the ToC when reading a Wikipedia article and this change is utterly incomprehensible to me.
- notRobot 4y agoWikipedia has support for different skins, including the old one: https://news.ycombinator.com/item?id=34431533 https://news.ycombinator.com/item?id=34431533
- awefji 4y agoI'm fine with it on articles, where as you say there's a table of contents. But the front page just has empty space there?!!??
- marginalia_nu 4y agoYeah on desktop it's particularly bizarre design choice. Hamburger buttons are designed to conserve pixels on cramped horizontal screens. They make zero sense on a 4k ultrawide monitor.
- chadlavi 4y agoAnchor elements aren't buttons! Stop using them as buttons!! Anchors navigate. Buttons have effects.
- enyo 4y agoThat’s why the anchor gets the role=“button”. Unfortunately you can’t set the target of the page with a button (without JavaScript), that’s why an anchor link is used.
- warp 4y agoYou can do this: <a href="#something"><button>menu</button></a> Or maybe: <form action="#something"><button type="submit">menu</button></form> Not sure either of those options are better than the original post though :)
- exogen 4y agoThe latter would probably work, but the first is invalid HTML – you can't nest interactive elements. Will browsers allow it? Yes. But it's still invalid per the spec.
- LocalPCGuy 4y agoYou could actually skip the button altogether and just make the checkbox input keyboard focus-able but visually hidden. You also avoid the issues with the hash also, as the user is then directly interacting with the element that toggles the menu. With some massaging (ensuring what is read for screen readers is set and that the visual focus state still appears to be on the hamburger when the checkbox is focused), it works quite well both for screen reader users and for non-mouse users. I don't have a current example (looks like it's been redesigned since I worked on it), but I've done something similar to this in the past on extremely large websites (thousands of views an hour in at least one instance) with much success.
- SebastianKra 4y agoSome of the most annoying StackOverflow threads are with people urging to use a <button> when I've triple checked that it isn't sufficient for my use-case.
- mkoryak 4y agoeverything old is new again. We were doing this crap in 2011
- LocalPCGuy 4y agoDefinitely - there's a whole class of stuff related to Progressive Enhancement that is being re-learned (and re-shared) every couple years, it seems like. There was whether CSS was expected to be available. In 2011, it was still being argued whether or not JS could be reliably be expected to be on. Now it's probably more about specific features of CSS/JS depending on browser support, but it's still all basically the same stuff, just maybe different techniques. I don't know if it's still true as I heard this state a few years ago, but at one point the growth rate of new web devs meant that at any given year, more than 50% of all web devs had less than 2 years of experience.
- toastal 4y ago2013 was the Snowden Leaks which ended up sparking a lot of folks interest and awareness in both security and privacy. This is the time when I and many others started keeping JavaScript off by default and enabling it iff needed. So, yes, please keep your site usable without JS if its purpose is to deliver content+information and not be a web application.
- LocalPCGuy 4y agoEh, "many others"? It's about 2% generally, and it's folks who are generally very well aware of how to re-enable it if needed. IMO, JavaScript is a building block of the web and there is no need in 2023 to build without it, even for progressive enhancement. You may have been able to argue that in 2011 +/- but now the average site should be able to assume it will be available if they have some reason to want to use it. I'm not saying you need to enable it, but that is a choice you are making, and you have the skill to turn it on/off as needed, and realize that there may be sites you won't be able to use without it. I don't think it's a reasonable expectation today that JS may not be available, except maybe to display a nice warning page stating that.
- jameshart 4y agoProof that accessibility and usability are entirely orthogonal. For screen reader users only, this provides them with the information that activating this link will open or close a menu. Screen reader users do not need to open or close menus. Menus do not take up space or sit in front of other content. Closing a menu offers no usability benefit to a screen reader user. All they need is the options to be present under a navigable heading that they can skip to when they need to access those options. Meanwhile, non screen reader users are forced to guess what will be behind the ≡ button this time.
- enyo 4y ago> Screen reader users do not need to open or close menus. Agreed, but you don’t want keyboard accessible menu items available for users that aren’t visually impaired. Offering a “show menu” button to screen readers is not less accessible to them than skipping the navigation section. If you’re building a page that is only meant to be used by screen readers, then you are absolutely right. > Meanwhile, non screen reader users are forced to guess what will be behind the ≡ button this time. The main menu? Which is behind the same ≡ button on most pages on the internet?
- jameshart 4y agoOffering a show menu button to screenreader users is accessible but poorly usable. They can’t see the menu. ‘Showing’ and ‘hiding’ mean nothing to them. And for your keyboard navigators using the visual interface, perhaps this hints that you could afford them a similar opportunity - where, from being focused on the menu, they could either descend into the menu, expanding it, or skip the menu and move focus to the next control. That’s how most OS/application keyboard accessible menus work - they don’t have ‘expand’ and ‘collapse’ affordances at all.
- enyo 4y agoMh.. yes I agree. "Expand menu" and “Collapse menu" is probably a better wording.
- meerita 4y agoThe good old "hamburger menu". That menu that stores everything designers never knew how to organize it.
- kitsunesoba 4y agoAlso known as the “app junk drawer”. Terrible design pattern in my opinion, particularly when they’re used in place of a proper menubar in a desktop app.
- shakna 4y agoExcept modern HTML actually has a builtin which is accessible, and works far better with screenreaders and other assistant technologies. The details element. <details> <summary>Menu</summary> <ul> <li><a href="/">Home</a></li> <li><a href="/thing">Thing</a></li> </ul> </details> You may want to add a tiny bit of CSS, like adding a border, and setting the cursor to a pointer, for your sighted users: details { padding: 0.5em; border-style: solid; border-width: 1px; border-radius: 0.25em; cursor: pointer; }
- mariusor 4y agoYou should still wrap the list in a <nav> element to give the browser the context about what the menu represents.
- myfonj 4y agoAlso, while details/summary support in browsers and other user agents and tools is improving over time, it is still not perfect for ... nearly anything. Sadly. https://adrianroselli.com/2019/04/details-summary-are-not-insert-control-here.html https://adrianroselli.com/2019/04/details-summary-are-not-in...
- nimish 4y agoPerfect is the enemy of the good. It's a reasonable general purpose choice. Of course don't use it if you have stricter requirements.
- runarberg 4y agoFWIW This article is almost 4 years old. When it was written 3 years hadn’t passed since Firefox had full support in Firefox 48. Meaning that more time has passed since this article was published then the time between Firefox support and the publication.
- myfonj 4y ago
- thex10 4y agoOn my site we have a "menu" link styled as a button. Before JS loads it'll link to a page we have that lists out all the menu options (literally navigating to oursite.com/menu). After JS kicks in the link gets hidden and an identical button gets shown that does the fancy side menu opening thing. TFA's approach seems nice enough but mine feels way simpler...
- enyo 4y agoThis would be way too frustrating to me :)
- zichy 4y agoThose "toggle buttons without JavaScript" are one of my pet peeves. It's always the same thing: 1. Someone finds out that you can use `:checked`. 2. They add some JavaScript to "enhance" their idea. 3. It's still less accessible than a proper implementation. This example is a CSS hack and not something you would actually want to use in a production environment. JavaScript is absolutely necessary if you are developing a custom interactive element. If `<details>` works for you, fine. If it doesn't, you might want to look up ARIA attributes.
- enyo 4y agoYou didn't actually say anything other than that it's bad and not to use on production. Care to elaborate?
- gauddasa 4y agoOh, that explains why Wikipedia hamburger button works with Javascript disabled. I disabled all Javascript for wikipedia long ago when it brought back the abusive popup culture that disrupts reading by mere presence of pointer on a hyperlink.
- runarberg 4y ago> But even if accessibility is not required in your particular case (you might be building an internal site where there are no visually impaired people) you want people to be able to navigate your page with the keyboard. I feel like this is a fundamental misunderstanding of accessibility: First of all, in many case the default choice provides accessibility for free. In this case it is the <details>/<summary> elements that other posts have highlighted. Secondly, accessibility is not just about accommodating current visually impaired users, or providing power-users with mouse free experience. There are all sorts of impairments where accessibility will help. Your mouse might decide to die all of a sudden in a middle of a form, and they just need to click that submit button, the company might hire a visually impaired developer, a developer might get sick, or have an accident and return to work needing assistive technology, etc. The cases are numerous. And finally, there are no excuses for not making your site accessible. If you are a front end developer, you know the industrial standard and you apply it. If you are not and are simply making a UI around an internal tool, you are probably either just using a rudimentary UI and browser native element (why do you need the hamburger menu in that case) or you use some UI framework that implements accessibility anyway.
- inopinatus 4y agoThe goal of a pure CSS hamburger is a noble one that I applaud and share. However, it's actually okay to introduce JS for the progressive enhancement to accessibility because ARIA is by definition dependent on RIAs. In regards to the overall construction of these I also rather like the form:valid hack, rather than the checkbox hack depicted, since the former is more general (in particular, the selectors can be ancestors instead of siblings).
- canadiantim 4y agoHonestly at this point I just make sure to include all relevant links in the footer so if people can’t use the hamburger they can just use the footer links
- ladon86 4y agoNot sure if you're the author, but I'm having an issue signing up for Pausly. After connecting an auth provider, there's a screen that asks for your name, and it's not possible to check the ToS checkbox. The error in the console is: > Cannot destructure property 'supabaseUrl' of 'Re(...)' as it is undefined.
- zagrebian 4y agoThere’s an issue: The Space key does not open the menu.
- analog31 4y agoI just noticed that the hamburger button on my (Windows) keyboard doesn't activate the hamburger menu in my browser.
- urban_alien 4y agoWouldn't only visually hide the checkbox solve the accessibility issue?