父菜单项获焦点时显示子菜单的CSS问题求助
WordPress主题菜单键盘导航子菜单无法显示问题
问题描述
自定义WordPress主题时,菜单支持纯键盘导航,但按Tab键遍历子菜单项时,子菜单无法显示。确认导航逻辑正常——遍历完所有子菜单项后,焦点会跳转到下一个父菜单项。
移除部分样式让所有菜单项始终可见时功能正常,但这种方式不实用。目前通过left: -999em;默认隐藏子菜单,鼠标hover父菜单项时设置left:0;可正常显示子菜单,但使用:focus伪类时该效果无效。
相关CSS代码
header .navigation li{ position: relative; } header .navigation li .sub-menu { position: absolute !important; z-index: 999; top: 100%; left: -999em; background-color: lightgray; box-shadow: 1px 1px 10px rgba(0,0,0,0.1); margin: 0; padding: 0; list-style-type: none; width: 200px; border-radius: .5rem; } header .navigation li .sub-menu a{ display: block; padding: .25rem; text-align: center; text-decoration: none; } header .navigation li .sub-menu a:hover, header .navigation li .sub-menu a:focus { color: white; /* BOTH WORK*/ } header .navigation > .menu-item-has-children:hover > .sub-menu, header .navigation > .menu-item-has-children:focus > .sub-menu { left: 0; /* ONLY THE :HOVER WOKRS */ }
最小可复现示例
CSS代码
header .navigation { list-style: none; margin: 0; display: flex; justify-content: left; align-items: center; width: 900px; word-break: keep-all; } header .navigation li a { padding: .25rem 1rem; color: #000; width: 100%; } header .navigation li:first-child a { padding-left: 0; } header .navigation li { position: relative; } header .navigation li .sub-menu { position: absolute !important; z-index: 999; top: 100%; left: -999em; background-color: lightgray; box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.1); margin: 0; padding: 0; list-style-type: none; width: 200px; border-radius: .5rem; } header .navigation li .sub-menu:focus { left: 0; } header .navigation li .sub-menu a { display: block; padding: .25rem; text-align: center; text-decoration: none; } header .navigation li .sub-menu a:hover, header .navigation li .sub-menu a:focus { color: white; /*BOTH WORK*/ } header .navigation>.menu-item-has-children:hover>.sub-menu, header .navigation>.menu-item-has-children:focus>.sub-menu { left: 0; /* ONLY THE :HOVER WOKRS */ }
HTML代码
<header class="sticky-top"> <div class="container-fluid"> <h1>test</h1> <div class="menu-all-pages-container"> <ul id="menu-all-pages" class="navigation"> <li id="menu-item-1636" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-1636"><a href="http://wpthemetestdata.wordpress.com/">Home</a></li> <li id="menu-item-1637" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1637"><a href="http://localhost/wordpress/?page_id=703">Blog</a></li> <li id="menu-item-1638" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1638"><a href="http://localhost/wordpress/?page_id=701">Front Page</a></li> <li id="menu-item-1639" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-1639"><a href="http://localhost/wordpress/?page_id=2">About The Tests</a> <ul class="sub-menu" tabindex="0"> <li id="menu-item-1760" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1760"><a href="http://localhost/wordpress/?page_id=1133">Page Image Alignment</a></li> <li id="menu-item-1761" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1761"><a href="http://localhost/wordpress/?page_id=1134">Page Markup And Formatting</a></li> <li id="menu-item-1640" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1640"><a href="http://localhost/wordpress/?page_id=501">Clearing Floats</a></li> <li id="menu-item-1641" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1641"><a href="http://localhost/wordpress/?page_id=155">Page with comments</a></li> <li id="menu-item-1642" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1642"><a href="http://localhost/wordpress/?page_id=156">Page with comments disabled</a></li> </ul> </li> <li id="menu-item-1643" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-1643"><a href="http://localhost/wordpress/?page_id=174">Level 1</a> <ul class="sub-menu"> <li id="menu-item-1644" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-1644"><a href="http://localhost/wordpress/?page_id=173">Level 2</a> <ul class="sub-menu"> <li id="menu-item-1645" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1645"><a href="http://localhost/wordpress/?page_id=172">Level 3</a></li> <li id="menu-item-1762" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1762"><a href="http://localhost/wordpress/?page_id=746">Level 3a</a></li> <li id="menu-item-1763" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1763"><a href="http://localhost/wordpress/?page_id=748">Level 3b</a></li> </ul> </li> <li id="menu-item-1764" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1764"><a href="http://localhost/wordpress/?page_id=742">Level 2a</a></li> <li id="menu-item-1765" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1765"><a href="http://localhost/wordpress/?page_id=744">Level 2b</a></li> </ul> </li> <li id="menu-item-1646" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1646"><a href="http://localhost/wordpress/?page_id=146">Lorem Ipsum</a></li> <li id="menu-item-1766" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1766"><a href="http://localhost/wordpress/?page_id=733">Page A</a></li> <li id="menu-item-1767" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1767"><a href="http://localhost/wordpress/?page_id=735">Page B</a></li> </ul> </div> </div> </header>
问题原因及解决方案
原因分析
:focus伪类仅作用于可获得焦点的元素,你当前的CSS给父菜单项的<li>标签设置了:focus规则,但<li>元素默认无法获得焦点。键盘导航时,焦点实际落在父菜单项内部的<a>标签上,而非<li>本身,所以:focus规则根本不会触发。
另外,给子菜单<ul>添加的tabindex="0"只能让子菜单自身获得焦点,无法解决父菜单项触发子菜单显示的问题。
解决方案
方案1:使用:focus-within伪类(推荐)
:focus-within会在元素本身或其任意子元素获得焦点时触发,完美适配父元素响应子元素焦点的场景:
header .navigation > .menu-item-has-children:hover > .sub-menu, header .navigation > .menu-item-has-children:focus-within > .sub-menu { left: 0; }
方案2:针对<a>标签的:focus状态(兼容旧浏览器)
若需要兼容不支持:focus-within的旧浏览器(如IE),可修改选择器,指向父菜单项内<a>标签的:focus状态:
header .navigation > .menu-item-has-children:hover > .sub-menu, header .navigation > .menu-item-has-children > a:focus + .sub-menu { left: 0; }
额外优化:保持子菜单在焦点遍历期间可见
为确保用户遍历子菜单项时,子菜单不会消失,需添加子菜单自身的焦点状态规则:
header .navigation li .sub-menu:focus, header .navigation li .sub-menu:focus-within { left: 0; }
这样焦点进入子菜单后,子菜单会保持显示,直到焦点离开整个父菜单项区域。
内容的提问来源于stack exchange,提问作者ilmaria
相关产品推荐
相关产品推荐

