
本文介绍一种基于现代 CSS 伪类(:has + :not)的纯 CSS 方案,让指定 .home 元素仅在 URL 无 fragment(即未匹配任何 :target)时显示,一旦存在 #id 目标则自动隐藏,无需 JavaScript,兼容主流现代浏览器。
本文介绍一种基于现代 css 伪类(`:has` + `:not`)的纯 css 方案,让指定 `.home` 元素仅在 url 无 fragment(即未匹配任何 `:target`)时显示,一旦存在 `#id` 目标则自动隐藏,无需 javascript,兼容主流现代浏览器。
要实现“首页默认可见、点击导航后自动隐藏”的单页体验(类似 Carrd 的首屏行为),核心难点在于:检测当前页面是否处于“无任何元素被 :target 匹配”状态。CSS 原生不提供 :not-target 这类伪类,但借助 :has() 关系选择器与 :not() 的组合,我们可以反向表达这一逻辑:
✅ 当
不包含任意一个被 :target 匹配的 .tabcontent 元素时,才显示 .home。
对应的关键 CSS 规则如下:
.tabcontent {
display: none;
}
.tabcontent:target {
display: block;
}
@supports selector(:not(:has(+ *))) {
/* 仅当浏览器支持 :has() 时启用该逻辑 */
body:not(body:has(.tabcontent:target)) .home {
display: block;
}
}
⚠️ 注意:.home 元素必须同时具有 id 和 class="home tabcontent"(如
<nav><a href="#home"><button>Home</button></a> <a href="#div01"><button>Section 1</button></a> <a href="#div02"><button>Section 2</button></a> </nav><!-- 首页需有 id,才能被 :target 匹配 --><div id="home" class="home tabcontent"> <h1>Welcome to the Home Page</h1> <p>This shows by default at index.html — and hides when #div01 or #div02 is targeted.</p> </div> <div id="div01" class="tabcontent"> <h2>Section One</h2> <p>This appears only when URL contains #div01.</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板"><img src="https://img.php.cn/upload/webcode/000/000/018/178607072210981.jpg" alt="CSS婚礼策划服务机构宣传网站模板" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板" class="overflowclass">CSS婚礼策划服务机构宣传网站模板</a> <p class="overflowclass">CSS婚礼策划服务机构宣传网站模板是一款适合提供婚礼策划和婚庆服务机构宣传网站模板下载。提示:本模板调用到谷歌字体库,可能会出现页面打开比较缓慢。</p> </div> <a rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div> </div> <div id="div02" class="tabcontent"> <h2>Section Two</h2> <p>Different content, triggered by #div02.</p> </div>
? 原理说明:
- body:has(.tabcontent:target) → 检查 body 内是否存在 当前被 target 的 tabcontent;
- body:not(...) → 取反,即“没有任何 tabcontent 被 target”;
- 此时 .home 才获得 display: block,实现“仅默认态可见”。
?️ 兼容性与降级建议:
- :has() 目前在 Chrome 105+、Edge 105+、Safari 15.4+ 支持,Firefox 尚未支持(截至 Firefox 128);
- 使用 @supports 确保规则安全生效,避免旧浏览器解析报错;
- 如需支持 Firefox 或 IE,可添加轻量 JS 回退(不推荐全量 jQuery):
// 简洁降级:监听 hashchange,手动切换显示
function updateHomeVisibility() {
const home = document.querySelector('.home');
if (location.hash && document.querySelector(location.hash + '.tabcontent')) {
home.style.display = 'none';
} else {
home.style.display = 'block';
}
}
window.addEventListener('hashchange', updateHomeVisibility);
updateHomeVisibility(); // 初始化
✅ 最佳实践总结:
- 首页 div 必须带 id(如 id="home")并参与 :target 流程,否则逻辑断裂;
- 所有可跳转内容块统一使用 .tabcontent 类,便于 CSS 统一控制;
- 导航链接应显式指向 #home,保证返回首页时 .home 能正确 :target 并重新显示(此时它会因 :target 规则显示,而 :not(:has()) 不生效,符合预期);
- 切勿将 .home 单独抽离出 .tabcontent 体系——它既是首页,也是可定位的 tab 之一。
这样,你就能用几行优雅的 CSS,实现零 JS、语义清晰、URL 友好的单页导航体验。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










