如何在CSS模块中嵌套类并做出反应?

the*_*eva 6 reactjs css-modules

我正在尝试在我的React项目中使用CSS模块。问题的第一部分是,如果我编写嵌套的css类(使用sass),我不知道是否可以访问内部的类,因为它们似乎也被编译成唯一的类名。一些代码:

<div className={this.state.visible ? styles.header+" menu-visible" : styles.header}>
    <div className="menu">
        <a className="link">title</a>
    </div>
</div>

   .header {
       &.menu-visible {
            .menu {
                 display:block;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

我有一个包装类,有时它是“菜单可见的”,它会改变所有子级的属性,在React中像这样做是不好的做法吗?

如果菜单可见,则.header中有多个类可以更改,因此仅更改包装类将很方便,我可以以某种方式引用这些子类吗?这样剩下的嵌套在scss中吗?

编辑

我能想到的一种解决方案是将className =“ menu”替换为className = {styles.header.menu},但这似乎行不通。问题是,如果它的父级具有菜单可见的类,我希望.menu更改其属性。

Sim*_*son 54

更好地保留嵌套类和样式的另一种解决方案是:global在使用 sass 或 less 等预处理器时对所有嵌套类使用全局范围。

.header {
  :global {
    .menu {
      display: none;

      &.menu-visible {
        display:block;
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)
<div className={styles.header}>
  <div className="menu menu-visible">
      Whatever
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

  • 当您使用像 bootstrap 这样的组件时,这是一个很棒的解决方案,它会创建无法指定 classNames 的子包装器 (3认同)

the*_*eva 33

我解决了。我想我只是在我的脑海里做过头了。styles.header.menu我可以写而不是写styles.menu,即使它是嵌套的。

示例(反应 + JSX):

<div className={styles.header}>
  <div className={styles.menu}>
      Whatever
  </div>
</div>

.header {
   .menu {
      display: block;
   }
 }
Run Code Online (Sandbox Code Playgroud)

  • 这实际上很有帮助!这不是一条容易找到的信息(您可以参考 __any__ 嵌套类),所以非常感谢您提出这一点! (3认同)
  • 需要注意的一件事是,您无法获得嵌套类选择的强度。有时我希望他们能改变这个功能或者至少解释一下原因。目前我不确定这是一个错误还是一个功能。如果您希望嵌套类选择器实际上向下转换并存在,这也会令人困惑,因为除非您引用它们,否则它们不会,而且我相信当您导入它们时它们都会成为顶级选择器。 (2认同)

seb*_*n.i 21

您可以使用 [class~=classname]

.header {
   [class~=menu] {
      display: block;
   }
 }
Run Code Online (Sandbox Code Playgroud)

它将不会被检测为一个类并被单独保留。

  • `[class~="cat"]` 将匹配一个单词,而不是一个子字符串。因此,它只会与“cat”匹配。`[class*="cat"]` 将与 `categories` 匹配。有关此的更多信息请参见 https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors (3认同)

drs*_*ter 8

请注意,当深度嵌套选择器时,接受的答案中的解决方案可能会导致 css 包大小显着增加。

接受的解决方案具有多 1 层嵌套

JSX:

<div className={styles.header}>
  <ul className={styles.menu}>
    <li className={styles.item}>
      Whatever
    </li>
  </ul>
</div>
Run Code Online (Sandbox Code Playgroud)

社会保障体系:

.header {
   .menu {
      .item {
        display: block;
      }
   }
 }
Run Code Online (Sandbox Code Playgroud)

输出(假设 css 模块的默认设置):

<div className={styles.header}>
  <ul className={styles.menu}>
    <li className={styles.item}>
      Whatever
    </li>
  </ul>
</div>
Run Code Online (Sandbox Code Playgroud)

替代解决方案

更好的编写方法是松散地借用 BEM 方法并使用父选择器:

JSX:

<div className={styles.header}>
  <ul className={styles.headerMenu}>
    <li className={styles.headerMenuItem}>
      Whatever
    </li>
  </ul>
</div>
Run Code Online (Sandbox Code Playgroud)

社会保障体系:

.header {
   &Menu {
     &Item {
       display: block;
     }
   }
 }
Run Code Online (Sandbox Code Playgroud)

输出:

.header {
   .menu {
      .item {
        display: block;
      }
   }
 }
Run Code Online (Sandbox Code Playgroud)