Next.js SCSS模块疑问:li.active样式未生效是否正常?
我有一个pagination.tsx组件和一个pagination.module.scss文件,文件内容如下:
SCSS模块代码
.pagination { ul { display: inline-block; padding-left: 0; margin: 20px 0; border-radius: 4px; } li { display: inline; color: black; float: left; padding: 8px 16px; text-decoration: none; &.active { background-color: #4CAF50; color: white; border-radius: 5px; } &:hover:not(.active) { background-color: #ddd; border-radius: 5px; } } }
React组件代码(简化版)
import React from 'react'; import styles from './pagination.module.scss'; const Pagination: React.FC<Props> = () => { return ( <div className={styles.pagination}> <ul> <li className={'active'}>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> </div> ); }; export default Pagination;
注:实际代码中active类通过classNames动态设置,此处为静态示例。
我的问题是:.pagination li.active的样式未生效,背景色#4CAF50无法显示;但ul和普通li的样式均可正常应用,请问这是Next.js SCSS模块的正常表现吗?还是我哪里操作有误?
原因分析
这不是Next.js SCSS模块的正常表现,问题出在SCSS模块的局部作用域机制:
SCSS模块会自动给所有类名添加唯一哈希值(比如.pagination会变成.pagination_xyz123),以此实现样式的局部隔离。你在组件里写的className={'active'}是全局类名,没有哈希后缀,但SCSS里的&.active编译后会变成.pagination_xyz123 li.active_xyz123,两者无法匹配,所以样式不生效。
解决方法
有两种可行的修改方式:
方法一:使用SCSS模块导出的active类
直接通过styles.active引用SCSS模块里定义的active类,这样类名会带上正确的哈希:
修改组件中的li代码:
<li className={styles.active}>1</li>
(如果是用classNames动态设置,写法类似className={classNames({ [styles.active]: currentPage === 1 })})
方法二:将active类设为全局类
如果需要保留全局的active类名,在SCSS中用:global()包裹对应的选择器:
li { // 其他样式... &:global(.active) { background-color: #4CAF50; color: white; border-radius: 5px; } }
这样该选择器不会被添加哈希,就能匹配组件中全局的active类名。
内容的提问来源于stack exchange,提问作者Kristi Jorgji

