Skip to header Skip to main navigation Skip to main content Skip to footer
Cookies UI
Alaa Haddad Offers Exceptional Drupal Custom Theming and Modules in Austin TX Alaa Haddad - Drupal Expert
Main navigation
  • Professional Profile
  • Drupal Services
    • Drupal Development
    • Drupal Developer
    • Drupal Themer
    • Drupal Architect
    • Drupal Consultant
  • My Drupal Modules & Themes
      • Cloudflare Purge
      • Solo Copy Blocks
      • W3CSS Paragraphs
      • Paragraphs Bundles
      • Acquia Purge Varnish
      • Reference Blocked Users
      • Module Matrix
      • Paragraphs Bundles Import
      • Selectify
      • Solo Utilities
      • Utilikit
      • Solo
      • Amun
      • Anhur
      • Amunet
      • W3CSS Theme
      • 3D Carousel
      • 3D FlipBox
      • Accordion
      • Carousel
      • Hero
      • Lightbox
      • Parallax
      • Reveal
      • Slideshow
      • Tabs
  • Blog
  • Videos
  • Contact
  • Hire Me (opens in new tab)
Search form
User login
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
  • Reset your password
User account menu
  • Hire Me (opens in new tab)
  • Drupal Services
  • Blog
Site branding
Alaa Haddad - Drupal Expert
Consultant • Architect • Developer • Themer - Expert Drupal Solutions
Article Title Image - Block 1

display: none vs visibility: hidden in Drupal Dropdowns

Content Info - Article Info
 
  10:55 PM CDT, Sun September 13, 2026
Share

Breadcrumbs

Breadcrumb

  • Home
  • multi-dropdown menus
  • display: none vs visibility: hidden in Drupal Dropdowns

Main page content

Neither display: none nor visibility: hidden leaves a submenu available to a screen reader — both remove it from the accessibility tree — so accessibility is not the tiebreaker between them, and choosing on that basis is choosing on a false premise.

That is the correction this article exists to make, and Drupal core states it in its own stylesheet. core/modules/system/css/components/hidden.module.css defines three utilities and documents exactly what each one does to assistive technology:

/* Hide elements from all users. */
.hidden { display: none; }

/* Hide elements visually, but keep them available for screen readers. */
.visually-hidden {
  position: absolute !important;
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
  width: 1px;
  height: 1px;
  word-wrap: normal;
}

/* Hide visually and from screen readers, but maintain layout. */
.invisible { visibility: hidden; }

Read the third comment. Core's own class for visibility: hidden is documented as hiding content from screen readers; the only difference core draws between it and .hidden is layout. And note why .visually-hidden needs clip and a one-pixel box at all: if visibility: hidden kept content in the accessibility tree, that class would be one line long.

Three ways to hide, and what each one costs

How the three hiding techniques differ, measured against what a dropdown menu needs
Behaviourdisplay: nonevisibility: hidden.visually-hidden
In the accessibility treeNoNoYes
Reachable by keyboard TabNoNoYes
Occupies layout spaceNoYes, unless out of flowNo, it is absolutely positioned
Found by browser in-page searchNoNoYes
Measurable by JavaScriptNo, all dimensions read 0YesYes, but 1×1
TransitionableOnly with discrete transitionsYes, paired with opacityNot applicable
Right for a closed submenuUsuallyWhen you want the fadeNever

The third row is the one most write-ups get wrong. "visibility: hidden still takes up space" holds only for an element in normal flow, and a dropdown submenu almost never is — it is absolutely positioned so it overlays the page instead of pushing it down. Out of flow, the layout objection disappears entirely.

What my own theme does, and why it does two different things

Solo, the Drupal theme I maintain, ships several menu styles, and they deliberately do not all answer this the same way.

The hover dropdown in css/components/solo-menu.css hides submenus with display: none and reveals them with display: flex on li:hover. Every tier below the first is position: absolute using logical properties — inset-inline-start, inset-block-start — so the same rules work right-to-left without a mirrored stylesheet. There is no transition here, so nothing is lost, and the panes stay out of the render tree until needed.

The off-canvas sidebar menu, in css/theme/solo-menu-side.css, does the opposite. It sits at visibility: hidden, parked out of view with inset-inline-start: 100%, and its transition names both properties:

.primary-sidebar-menu {
  visibility: hidden;
  transition:
    transform var(--solo-sidebar-speed, 400ms) ease-in-out,
    visibility var(--solo-sidebar-speed, 400ms) ease-in-out;
}

.primary-sidebar-menu.toggled {
  visibility: visible;
  transform: translateX(-100%);
}

Listing visibility in the transition is not decoration. It animates discretely, and naming it is what keeps the panel visible for the whole slide-out, vanishing only once the slide-in finishes. Drop it and the panel disappears the instant the class is removed, leaving the transform animating something nobody can see.

Same theme, same question, two answers — and the deciding factor both times was whether there is an animation, not accessibility. To see these in a working install rather than a listing, installing and customising Solo walks through the settings that switch between them.

Animation is no longer the deciding factor either

The classic reason to prefer visibility: hidden was that display could not be animated. Modern CSS has closed that gap with two features that work together:

  • transition-behavior: allow-discrete, which lets discrete properties such as display participate in a transition instead of snapping at the start.
  • @starting-style, which supplies the "before" values an element should animate from when it first becomes rendered — the missing piece that made entry animations impossible from display: none.

Together they let a submenu fade in from display: none and fade back out to it, with nothing left occupying anything in between. Check current browser support before relying on it; the fallback is benign, because without support the menu still opens and closes, just instantly.

The Drupal-specific traps

Hidden content measures zero

Anything inside a display: none ancestor has no box, so every geometry read returns zero — and Drupal themes measure things constantly. Solo's responsive pass in js/components/solo-scripts.js reads getBoundingClientRect().width per region and assigns a width class from it, so a region measured under a display: none ancestor reads 0 and lands in the narrowest bucket. The same mechanism catches out sliders, charts and sticky-header offsets initialised inside a closed panel. visibility: hidden does not have this problem, which is a real reason to pick it that has nothing to do with animation.

Behaviours inside a pane that was hidden

When JavaScript reveals a pane containing Drupal-rendered content — a Views block, an exposed filter, a field group — that content's behaviours may never have run, or may have run against a zero-size box. Call Drupal.attachBehaviors(revealedElement, drupalSettings) on the newly visible element, passing the element rather than document so you re-process only what changed.

Hiding is not the same as not rendering

A menu link hidden in CSS is still in the HTML, still crawled, and still counted by an accessibility audit. If a menu item should not be there, unpublish it or remove it from the menu. The same confusion turns up with block titles, where "hidden" means several different things depending on which control you used — why hidden block titles in Drupal still affect SEO and accessibility works through that case in detail.

The choice that actually matters more than either property

A submenu revealed only by :hover cannot be opened by a keyboard, and on a touch screen the first tap on the parent either does nothing or follows the link. Whichever property hides it, a hover-only dropdown excludes people.

The accessible pattern is a real <button> carrying aria-expanded, toggled on click and on Enter or Space, with Escape closing the menu and returning focus to the button. Solo's menubar and mega-menu variants work this way; the state is managed in js/menu/solo-menu-state-manager.js. Hover can stay as an enhancement on top — it just cannot be the only way in. Getting that wiring right on top of Drupal's menu markup and an RTL layout takes longer than people expect; it is squarely Drupal theming work, and worth budgeting for rather than discovering during an audit.

Common questions

So which one should I use for a dropdown?

display: none by default. Reach for visibility: hidden plus opacity when you want a fade and cannot yet rely on discrete transitions, or when something inside the panel has to be measurable while closed.

Is opacity: 0 on its own a valid way to hide a menu?

No, and it is the worst option. A transparent element is still in the accessibility tree, still focusable and still intercepts clicks, so keyboard users tab into an invisible menu and mouse users hit an invisible wall. Always pair it with visibility: hidden.

What about the HTML hidden attribute?

The user-agent stylesheet applies it as display: none, so it behaves like the first column above, with the advantage that the state lives in the markup where both server-rendered code and JavaScript can see it. Any CSS display rule of equal or greater specificity overrides it silently.

Can I use these to hide things only on small screens?

You can, but hiding is usually the wrong answer to a narrow layout: the content is still downloaded and now unreachable for that visitor. Reflow it instead — small screen sizes in responsive web design covers how narrow layouts really behave in a Drupal theme.

My submenu will not open after an AJAX request. Is this the cause?

Probably not the CSS. More often the JavaScript that binds the toggle ran once on page load and never ran again for the replaced markup, or ran twice and cancelled itself out. Check the behaviour before you touch the stylesheet — troubleshooting CSS issues in a Drupal sub-theme covers how to tell a CSS problem from a JavaScript one.

Next step

Try one test on your own menu right now: load the page, press Tab repeatedly, and see whether you can open every submenu without a mouse. If you cannot, the property you used to hide it was never the real problem.

If that test fails and the menu is load-bearing for your site, describe what happens when you tab through it and I will tell you whether it is a stylesheet fix or a rebuild of the menu markup.

multi-dropdown menus
Slide 1 of 27
Acquia Purge Varnish - API V2 (Drupal Module)
Slide 2 of 27
Amun - W3CSS Sub-Theme (Drupal Theme)
Slide 3 of 27
Amunet - W3CSS Sub-Theme (Drupal Theme)
Slide 4 of 27
Anhur - W3CSS Sub-Theme (Drupal Theme)
Slide 5 of 27
Cloudflare Purge (Drupal Module)
Slide 6 of 27
Module Matrix (Drupal Module)
Slide 7 of 27
Paragraphs Bundles (Drupal Module)
Slide 8 of 27
Paragraphs Bundles Import (Drupal Module)
Slide 9 of 27
Reference Blocked Users (Drupal Module)
Slide 10 of 27
Selectify (Drupal Module)
Slide 11 of 27
Solo (Drupal Theme)
Slide 12 of 27
Solo Copy Blocks (Drupal Module)
Slide 13 of 27
Solo Utilities (Drupal Module)
Slide 14 of 27
Utilikit (Drupal Module)
Slide 15 of 27
Views 3D Carousel (Drupal Module)
Slide 16 of 27
Views 3D FlipBox (Drupal Module)
Slide 17 of 27
Views Accordion (Drupal Module)
Slide 18 of 27
Views Carousel (Drupal Module)
Slide 19 of 27
Views Hero (Drupal Module)
Slide 20 of 27
Views Lightbox (Drupal Module)
Slide 21 of 27
Views Parallax (Drupal Module)
Slide 22 of 27
Views Reveal (Drupal Module)
Slide 23 of 27
Views Slideshow (Drupal Module)
Slide 24 of 27
Views Tabs (Drupal Module)
Slide 25 of 27
VVJ Core (Drupal Module)
Slide 26 of 27
W3CSS Paragraphs (Drupal Module)
Slide 27 of 27
W3CSS Theme (Drupal Theme)
1 of 27

Our mission is to make Drupal more accessible and user-friendly, empowering businesses of all sizes, especially small enterprises with powerful tools that streamline content customization and enhance digital experiences.

Need help with your Drupal project? Hire Me through Flash Web Center, LLC.

Search

The Drupal 11 Module and Theme Stack, With Versions Checked

ARIA Live Regions in Drupal 11: What Core Does, What You Add

Drupal Architect: The Decisions Expensive to Reverse

Drupal Services: Development, Theming, Upgrades | Austin TX

Paragraphs Bundles

Drupal Module - Paragraphs Bundles

Drupal Theme - Solo

Drupal Theme - Solo

Drupal Work List - Drupal Work

Reference Blocked Users (Drupal Module)

Solo Utilities (Drupal Module)

Views Hero (Drupal Module)

Solo (Drupal Theme)

Paragraphs Bundles Import (Drupal Module)

Drupal Theme - W3CSS Theme

Drupal Theme - W3CSS Theme

Drupal Module - W3CSS Paragraphs

Drupal Module - W3CSS Paragraphs

Inspiration

Inspiration is the fuel that powers our creative engine, often coming from our surroundings, experiences, or the works of others. It's that magical moment when something clicks inside your brain, and you suddenly see a path forward that you hadn't noticed before. Inspiration can strike at any time, providing the motivation and energy needed to explore new possibilities and bring your ideas to life.

Unique Ideas

Unique Ideas

Unique ideas are the seeds of innovation, representing original thoughts or concepts that stand out from the usual. They're the sparks that ignite the process of creating something new and different, often leading to unexpected and groundbreaking solutions or products. Whether in art, science, business, or technology, unique ideas challenge the status quo and pave the way for progress.

Brainstorming

Brainstorming

Brainstorming is a creative group activity designed to generate a large number of ideas or solutions to a problem. It's a free-flowing and open-ended discussion where every suggestion is welcomed and considered, no matter how outlandish it may seem. Brainstorming encourages thinking outside the box, fostering an environment where creativity and collaboration lead to innovative solutions.

Planning

Planning

Planning is the blueprint for turning your ideas into reality. It involves setting goals, outlining steps, and organizing resources in a way that makes achieving your objectives possible. Good planning considers potential challenges and opportunities, making it easier to navigate the journey from concept to completion. It's about preparing the groundwork so that your projects can grow and flourish.

Drupal Developer

A Drupal Developer stands as the technical powerhouse behind dynamic websites, wielding expertise in PHP, custom module development, and Drupal's sophisticated API ecosystem. This role transforms business requirements into functional, secure, and scalable web solutions that power everything from small business sites to enterprise platforms serving millions of users. A Drupal Developer's expertise spans the entire development lifecycle—from architecting custom modules and integrating third-party services to optimizing performance and ensuring security compliance. Discover the complete guide to Drupal Developer skills, career paths, and hiring strategies.

Drupal Themer

A Drupal Themer serves as the artistic craftsperson who transforms wireframes and design mockups into pixel-perfect, accessible, and responsive user experiences using Twig templates, CSS, and JavaScript. This specialized role bridges the gap between design vision and technical implementation, ensuring every website not only looks exceptional but performs flawlessly across all devices and meets WCAG accessibility standards. A Drupal Themer's work encompasses the entire front-end ecosystem—from creating custom theme architectures and optimizing Core Web Vitals to implementing complex responsive designs and ensuring seamless integration with Drupal's rendering system. Explore the comprehensive guide to Drupal Themer expertise, theming best practices, and career advancement.

Drupal Architect

A Drupal Architect emerges as the strategic visionary of web construction, armed with encyclopedic knowledge of enterprise architecture patterns, infrastructure design, and Drupal's extensive technological ecosystem. This senior role operates at the highest technical level, making critical decisions that determine whether complex implementations scale successfully or collapse under real-world demands. A Drupal Architect's responsibilities begin long before development starts—during strategic planning phases where the foundation for secure, performant, and maintainable systems is established through careful evaluation of technology stacks, integration strategies, and scalability requirements. Learn about Drupal Architect skills, enterprise architecture strategies, and career progression to principal roles.

Footer menu

  • Contact
  • Professional Resume
  • Resume Summary
  • Technical Skills
  • Privacy Policy
  • Terms & Conditions
  • Search
  • Login
  • Sitemap

Copyright © 2026 Flash Web Center, LLC - All rights reserved

Developed & Designed by Alaa Haddad