如何使用Vanilla Extract为子元素设置样式?

5

我开始使用香草提取物来为NextJS应用程序添加样式。有没有一种方法可以在不创建另一个类的情况下从父元素中样式化子元素?

在React组件中,我的结构如下:

 <ul className={styles.ul}>
   <li>a</li>
   <li>b</li>
   <li>c</li>
 </ul>

在样式文件中可以像这样写:
import { style } from "@vanilla-extract/css"

export const ul = style({
    display: vars.display.flex,
    listStyleType: vars.none,
})

你得到了答案吗? - Mohammad Hossein Dolatabadi
2个回答

6

无需创建新的CSS类来定位li元素,但需要有两个不同的CSS规则,无论您使用何种预处理器或纯CSS。

请记住在纯CSS中所编写的内容:

.some-specific-ul {
    margin: 4em;
}

.some-specific-ul > li {
    color: grey;
}

使用vanilla-extract编写的内容几乎相同。唯一的区别在于类名不再是硬编码的,而是以某种方式生成的。尽管如此,您仍然可以在多个规则中使用该类名。
import { globalStyle, style } from "@vanilla-extract/css";

export const ul = style({
    margin: '4em',
});

globalStyle(`${ul} > li`, {
    color: 'grey',
});

在这两种情况下,您只需要将一个类应用于
    元素,
  • 元素也会自动应用样式。在第二种情况下,仅导出
      类名称是合理的,因为没有办法强制要求
    • 规则,它只能根据父
        自动应用。
        现在,请记住,如果滥用“自动应用规则”,您的代码可能变得不太可维护。随着规则数量和元素层次结构的深度增加,人们将不知道样式来自哪里。我相信,在某个点上,值得显式地应用你所应用的样式。在幕后,它创建CSS类,但您不应该关心这一点。
        想象一下:
        import { style } from "@vanilla-extract/css";
        
        export const ul = style({
            margin: '4em',
        });
        
        export const li = style({
            color: 'grey',
        });
        

        import * as React from "react";
        import * as classNames from "./my-list.css";
        
        export const MyList: React.FC<{ items: string[] }> = ({ items }) => (
            <ul className={classNames.ul}>
                {items.map(item => (
                    <li key={item} className={classNames.li}>{item}</li>
                )}
            </ul>
        );
        

        重要建议是,您的样式文件将保持不变,您需要花费一些额外时间编写类名称,但在维护方面将节省更多时间。


4
您可以使用CSS选择器(例如nth-child)结合&表示符号,并按如下方式在您的样式中使用,示例如下:

编辑:此代码片段根本无法工作 :(

  export const ul = style({
    display: vars.display.flex,
    listStyleType: vars.none,
    selectors:{
      '& li:nth-child(n)': {
          display: vars.display.flex,
      }
    }
  })


实际上,&代表你的样式,就像在css中一样。在这个例子中,&表示class-name
编辑: 正如vanilla extract文档所述: 为了提高可维护性,每个样式块只能针对单个元素。为了强制执行此操作,所有选择器都必须针对“&”字符进行定位,该字符是对当前元素的引用。
例如,'&:hover:not(:active)'和[${parentClass} &]是有效的,而'& a[href]'和[& ${childClass}]则不是。
如果要定位另一个作用域类,则应在该类的样式块中定义它。
例如,[& ${childClass}]是无效的,因为它没有定位到“&”,因此应该在childClass的样式块中定义它。
如果要全局定位当前元素内的子节点(例如'& a[href]'),则应使用globalStyle。
有用的链接:
https://github.com/seek-oss/vanilla-extract
https://tsh.io/blog/vanilla-extract-library/

是的,我错了。请在我编辑的选择器中尝试它。 - Mohammad Hossein Dolatabadi
不,那种方法只针对<ul>元素的子元素而不是它们的孩子。 - David Rios
我误解了你想要的。请尝试新版本。 - Mohammad Hossein Dolatabadi
我尝试了那个,它抛出了 Error: Invalid selector: & li:nth-child(n) 截图 - David Rios
你不能这么做。这不是库本身的技术限制,而是它强制执行的良好实践,以使我们的类更易于维护。 - Mohammad Hossein Dolatabadi
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接