Gatsby单页面滚动到对应区块时导航栏激活项自定义样式实现问题
问题根因
- 嵌套
<a>标签错误:你在ScrollSpy下直接写了原生<a>标签,内部又嵌套了Gatsby的<Link>组件(本身会渲染为<a>标签),违反HTML规范,导致属性、类名传递异常 active类挂载位置错误:react-scrollspy-navigation默认会将激活类添加到它的直接子元素(也就是你写的原生<a>标签)上,而你把activeClassName写在了内部的<NavLinks>组件上,类名根本没挂载到正确的元素- 样式优先级冲突:styled-components生成的类名优先级高于你全局CSS里的
.active规则,就算类名正确也会被覆盖
可行解决方案
第一步:修正导航结构,移除嵌套a标签
把ScrollSpy下的原生<a>标签删掉,直接把href、ref属性挂载到<NavLinks>组件上:
<ScrollSpy offsetTop={80} duration={1500}> <NavItem> <NavLinks to="/#s1" href="/#s1" ref={React.createRef()}>Company</NavLinks> </NavItem> <NavItem> <NavLinks to="/#s4" href="#s4" ref={React.createRef()}>Features</NavLinks> </NavItem> {/* 剩余导航项全部按照上述结构修改,删除外层的a标签 */} <NavBtn> <ButtonOne href="#s8" ref={React.createRef()} style={{scrollBehavior: "smooth"}}>BOOK NOW</ButtonOne> </NavBtn> </ScrollSpy>
第二步:调整样式规则,解决优先级问题
两种方案二选一即可:
方案A:在styled-components里定义激活样式(推荐,优先级匹配)
修改NavLinks的styled定义,添加.active类的样式规则:
const NavLinks = styled(Link)` color: #fff; display: flex; align-items: center; text-decoration: none; padding: 0.5rem 1rem; height: 100%; &:hover { color: #fabf49; } /* 新增激活样式 */ &.active { color: #fabf49; } @media screen and (max-width: 1120px) { text-align: center; padding: 2rem; width: 100%; display: table; color: #fabf49; &:hover { color: white; transition: all 0.3s ease; } /* 移动端激活样式可按需调整 */ &.active { color: white; } } `
方案B:给全局CSS的active规则提升优先级
修改你layout.css里的规则:
.active{ color: #fabf49 !important; }
第三步:可选优化
把每个导航项的ref用useRef提前声明,避免每次渲染都新建ref:
// Navbar组件顶部声明ref const s1Ref = useRef(null) const s4Ref = useRef(null) // 剩余s7、s6、s8等同理声明
然后把对应导航项的ref属性替换成你声明的变量即可。
内容的提问来源于stack exchange,提问作者Khabees Insaan
相关产品推荐
相关产品推荐

