Next.js 13 Link组件样式不生效:菜单hover效果实现求助
Next.js 13导航菜单hover样式不生效的问题排查与解决
我是Next.js 13新手,尝试创建带hover效果的导航菜单,代码如下,但给Link组件添加的menu-item类样式未生效,无法实现预期hover效果。根据文档,Next.js13的Link无需嵌套<a>标签,但样式就是不工作:
import Link from 'next/link'; const MenuItem = ({ href, label }) => ( //This Link has a className that doesn't get styled. <Link href={href} className="menu-item"> {label} </Link> ); function MainNavigation() { return ( <> <style jsx>{` .header { height: 5rem; display: flex; align-items: center; justify-content: space-between; background-color: #ffffff; padding: 0 10%; font-family: system-ui, sans; font-size: 2.5rem; font-weight: 800; } .logo { font-size: 2rem; color: white; font-weight: bold; } .header ul { list-style: none; margin: 0; padding: 0; display: flex; align-items: baseline; } .header li { margin-left: 3rem; } .menu-item { color: #000; position: relative; text-decoration: none; } .menu-item::before { background: hsl(45 100% 70%); content: ""; inset: 0; position: absolute; transform: scaleX(0); transform-origin: right; transition: transform 0.5s ease-in-out; z-index: -1; } .menu-item:hover::before { transform: scaleX(1); transform-origin: left; } `}</style> <header className='header'> <div className='logo'>React Meetups</div> <nav> <ul> <li> <MenuItem href='/' label='menu item 1' /> </li> <li> <MenuItem href='/' label='menu item 2' /> </li> </ul> </nav> </header> </> ); } export default MainNavigation;
问题原因
核心问题是JSX作用域样式的隔离特性:你在MainNavigation组件中定义的<style jsx>是作用域样式,只会对当前组件内直接渲染的元素生效,而MenuItem是独立的子组件,里面的Link元素无法继承父组件的作用域样式。
正确实现方式
方法1:将样式移到MenuItem组件内
把menu-item相关的样式放到MenuItem组件的<style jsx>中,让样式直接作用到组件内的Link元素:
import Link from 'next/link'; const MenuItem = ({ href, label }) => ( <> <style jsx>{` .menu-item { color: #000; position: relative; text-decoration: none; } .menu-item::before { background: hsl(45 100% 70%); content: ""; inset: 0; position: absolute; transform: scaleX(0); transform-origin: right; transition: transform 0.5s ease-in-out; z-index: -1; } .menu-item:hover::before { transform: scaleX(1); transform-origin: left; } `}</style> <Link href={href} className="menu-item"> {label} </Link> </> ); // MainNavigation组件保留原有其他样式,移除原<style jsx>中的menu-item相关代码
方法2:使用全局样式
把menu-item的样式放到全局CSS文件(比如app/globals.css)中,然后在布局组件中引入:
在app/globals.css添加:
.menu-item { color: #000; position: relative; text-decoration: none; } .menu-item::before { background: hsl(45 100% 70%); content: ""; inset: 0; position: absolute; transform: scaleX(0); transform-origin: right; transition: transform 0.5s ease-in-out; z-index: -1; } .menu-item:hover::before { transform: scaleX(1); transform-origin: left; }
在app/layout.js中引入全局样式:
import './globals.css'; // 布局组件其他代码...
方法3:使用作用域样式的全局扩展
在MainNavigation的<style jsx>中用:global()标记需要全局生效的类,让子组件的元素也能应用样式:
// MainNavigation中的<style jsx>修改为: <style jsx>{` /* 保留原有header、logo等样式 */ :global(.menu-item) { color: #000; position: relative; text-decoration: none; } :global(.menu-item::before) { background: hsl(45 100% 70%); content: ""; inset: 0; position: absolute; transform: scaleX(0); transform-origin: right; transition: transform 0.5s ease-in-out; z-index: -1; } :global(.menu-item:hover::before) { transform: scaleX(1); transform-origin: left; } `}</style>
内容的提问来源于stack exchange,提问作者Ersch
相关产品推荐
相关产品推荐

