V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ericgui
V2EX  ›  程序员

前端的问题: css modules vs styled components 老铁们选哪个?为什么?

  •  
  •   ericgui · 2019-09-21 13:40:02 +08:00 · 10432 次点击
    这是一个创建于 1898 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我组长用 styled component,所以我也跟着用,没选择权的。

    我们这是建一个自己的产品,所以 styled component 看起来还是很合适的,虽然我在初期似乎不太习惯。但现在觉得 styled components 很强大


    然而,css modules 似乎也不错,关键是把样式和 js 代码分开了,不再`CSS-in-JS`
    这样的话,好处也是明显的:如果将来我们要改版,就不会那么费劲了,对吧?

    而且我自己在写一个博客,希望做成一个小产品,允许用户们自己设计主题,这必然要提供一系列的 css class,让用户可以自己来覆盖样式

    所以想问一下各位的选择是什么,为什么?谢谢
    第 1 条附言  ·  2019-09-22 23:58:50 +08:00
    第 2 条附言  ·  2019-09-23 00:44:49 +08:00
    上面的链接是 BEM 风格,具体是什么,请去 google

    但我要个例子:vuetify

    大家都说 vuetify 这个库的 css 代码非常牛逼,我以前就知道他们的 css class name 非常有规律,今天才意识到,这个就是 BEM 风格。

    我要用这个风格了,我很喜欢这个风格
    68 条回复    2021-06-06 23:26:48 +08:00
    noe132
        1
    noe132  
       2019-09-21 14:04:56 +08:00
    抬个杠,我用 vue 和 angular,都自带 scoped css

    说实话 css module 的侵入性比 styled component 要小
    但是两个我都不喜欢。我见过的 react 项目都是直接写样式用 css-loader 加载。组件内使用 namespaced classname
    AnnatarHe
        2
    AnnatarHe  
       2019-09-21 14:14:54 +08:00   ❤️ 5
    都不用,建议了解一下 [tailwindcss]( https://tailwindcss.com/)

    写 css 这么多年,接触了 tailwind 才意识到正确的 css 写法是什么
    Cbdy
        3
    Cbdy  
       2019-09-21 14:16:25 +08:00 via Android
    styled jsx 了解一下
    https://github.com/zeit/styled-jsx
    noe132
        4
    noe132  
       2019-09-21 14:26:49 +08:00
    styled jsx 唯一的缺点在于不支持 preprocessor
    ChefIsAwesome
        5
    ChefIsAwesome  
       2019-09-21 14:47:20 +08:00   ❤️ 2
    css 大体可以分几部分:
    1.直接针对 HTML 的。像 reset,或者富文本的样式。
    2.grid,gutter,margin-left-5 这种 layout 相关。或是 round-corner,box-shadow-5 这些所谓 atomic design 的样式。他们都跟具体组件没什么关系。
    3.强制字号,强制文字颜色,强制隐藏,跟具体组件没什么关系,甚至是专门用来覆盖固有样式的工具类。
    4.通用 UI 组件。按钮,对话框之类的。
    5.没什么通用性的,具体的 UI。像页面布局之类的。

    1,2,3 必须是写在全局的 css 文件里的。因为是全局的,相应的 BEM 之类的命名方法肯定是要用的。
    4 写哪都行。但是要注意的是我们写任何 module,除了 close 来隔绝外界,还得 open for extension。有没有 open 的需求,怎么设计 open,看你自己的想法了。
    5 没什么通用性,写在 scoped css 里或者 style 里都是比较好的选择。这里仍然可能有复用样式的需求。css 可以用 mixin,style 就是对象,拆出来直接就能复用了。

    我想要做一个可以定制的组件怎么办?
    看你想暴露哪些接口,提供多大的定制性。css 的接口只有俩:class,css properties。
    Flands
        6
    Flands  
       2019-09-21 14:48:59 +08:00
    react 我用 css modules
    JS 入侵的写法非常不舒服
    楼上那个 tailwind 简直惊艳!
    love
        7
    love  
       2019-09-21 14:52:01 +08:00
    css modules 用 scss 的话似乎很不方便,没法象以前的在主 index.scss 里 include 一些东西然后子文件里可以直接用了

    还是建议用 styled components,用 js 管理一切才是最好的
    silaike
        8
    silaike  
       2019-09-21 14:56:57 +08:00 via iPhone
    @love 可以由 sass loader 统一引入文件的
    love
        9
    love  
       2019-09-21 15:01:22 +08:00
    @silaike 我用的是官方的 create-react-app,这货自己做不了太灵活的定制
    VDimos
        10
    VDimos  
       2019-09-21 15:02:37 +08:00 via Android
    css module 吧,style component 写起来别扭
    TheFLY
        11
    TheFLY  
       2019-09-21 15:18:56 +08:00
    @AnnatarHe 这个真的很棒诶
    wangxiaoaer
        12
    wangxiaoaer  
       2019-09-21 15:20:40 +08:00 via Android
    @AnnatarHe 这个东西粒度足够细吗?可以通过排列组合实现任意需求?

    另外,感觉跟 bootstrap 之类有点像啊
    hewelzei
        13
    hewelzei  
       2019-09-21 15:20:49 +08:00
    emotion 了解一下,我觉得比 style component 好用
    joshua7v
        14
    joshua7v  
       2019-09-21 15:21:54 +08:00
    个人项目以前 tachyons
    tailwind 出来后就用 tailwind 了
    hewelzei
        15
    hewelzei  
       2019-09-21 15:23:52 +08:00
    @love #9 原文:“@silaike 我用的是官方的 create-react-app,这货自己做不了太灵活的定制”
    ======
    回复:可以用 react-app-rewired 定制一些 create-react-app 不能修改的 webpack 配置
    df4VW
        16
    df4VW  
       2019-09-21 15:24:45 +08:00
    楼上几个开始推荐 css framework 的都是什么鬼???
    jerrry
        17
    jerrry  
       2019-09-21 17:29:51 +08:00
    @AnnatarHe 太大了
    connection
        18
    connection  
       2019-09-21 17:58:07 +08:00
    看了看 tailwind 感觉跟 tachyons 还是有点像呀。

    我个人觉得如果定下来的 css 部分已经足够多了 可以选择用 styled。我觉得其实 styled 修改也是有一点复杂度的。
    Fortnight
        19
    Fortnight  
       2019-09-21 18:11:25 +08:00
    css module + 1。 第一感觉就不喜欢 style component 那种写法,于是直接用了 css module。不过有机会也会试试 style component,搞得风风火火的,应该是有它的独到之处的。
    hyyou2010
        20
    hyyou2010  
       2019-09-21 18:18:45 +08:00
    styled-components 的好处是都在一个文件里面,看起来省事
    yuthelloworld
        21
    yuthelloworld  
       2019-09-21 18:25:57 +08:00 via Android
    jss
    newdongyuwei
        22
    newdongyuwei  
       2019-09-21 21:27:39 +08:00
    我们用的是 css modules。我觉得 styled components 一个好处是编写程序时可以避免在 js/ts 和 css/scss/less 文件间频繁切换。切换多了很耗时的,且分散注意力,阅读 /修改别人写的模块可能也要来回切换。
    newdongyuwei
        23
    newdongyuwei  
       2019-09-21 21:28:26 +08:00
    styled-jsx 看起来很不错!
    Lxxyx
        24
    Lxxyx  
       2019-09-21 22:01:00 +08:00
    styled components。
    简单,对于 React Component 友好,不必来回切换,也不用在两个地方重复书写类名。

    缺陷也有,复用性没有原始的 css 那么强,体积也比较大(毕竟是个 JS 类库)
    maomaomao001
        25
    maomaomao001  
       2019-09-21 22:26:21 +08:00
    你们用 css modules 的话怎么解决不能嵌套写的方式的,
    或者说, 如果每个组件一个 css 文件的,感觉 css 文件会居多啊,
    有没有办法写一个文件,能用在几个组件里的方案
    bertonzh
        26
    bertonzh  
       2019-09-21 22:43:26 +08:00
    @maomaomao001 一个文件用在几个组件没问题啊,这几个组件引用一个文件就可以。

    css modules 主要问题在于如何在父组件里面覆盖自组件的样式,如果有这样的需求就不得不留个口子使用传统 css 方案。
    bertonzh
        27
    bertonzh  
       2019-09-21 22:50:20 +08:00
    @df4VW 我也想不通。我简单看了一下 tailwindcss,这特么不就是很多年之前小范围流行过的 「 css 原子类」吗?
    我还以为这种方案早就被业界抛弃了呢。。
    learnshare
        28
    learnshare  
       2019-09-21 22:52:04 +08:00
    @AnnatarHe 一切都堆到 class 里的歪门邪道(苦笑
    silaike
        29
    silaike  
       2019-09-21 23:15:33 +08:00 via iPhone
    @bertonzh 父组件传一个 prop 到子组件,子组件把这个 prop 和本身的 styles 合并覆盖自己的 styles key 值
    connection
        30
    connection  
       2019-09-21 23:48:35 +08:00
    @bertonzh 原子类是降低 css 体积增长的一个很有效方式。

    总结还是选最合适 成本最低的
    ochatokori
        31
    ochatokori  
       2019-09-21 23:53:10 +08:00 via Android   ❤️ 3
    每当讨论前端技术的时候,下面就会出现一大堆我没听过的名词
    我学不动了!!
    Elmer
        32
    Elmer  
       2019-09-22 02:27:02 +08:00
    @AnnatarHe 感谢分享,看着不错
    seki
        33
    seki  
       2019-09-22 02:35:32 +08:00
    这两种方案都能解决命名冲突的问题
    不过个人觉得 css-in-js 是更便利的方案,动态生成的 css 对于一些需求,比如需要支持多套主题,或者动态变换某些元素的样式之类的,会更方便一点
    Shook
        34
    Shook  
       2019-09-22 02:49:47 +08:00
    我想知道,使用 stylus 这样的,要如何处理多套主题呢?
    KuroNekoFan
        35
    KuroNekoFan  
       2019-09-22 03:33:42 +08:00
    都不选,暂时还没发觉选用的必要,引入了反倒没法`cascade`了
    devtiange
        36
    devtiange  
       2019-09-22 06:05:45 +08:00
    都不用, 用 vue.
    invalidtoken
        37
    invalidtoken  
       2019-09-22 07:55:23 +08:00   ❤️ 1
    @AnnatarHe 看示例代码感觉...嗯?... 就像是换了种方式写内嵌样式
    ericgui
        38
    ericgui  
    OP
       2019-09-22 08:51:03 +08:00
    @devtiange 老铁你这就比较搞笑了。
    miniwade514
        39
    miniwade514  
       2019-09-22 10:51:11 +08:00
    @invalidtoken 你是想说换了个方式写行内样式?这是提供了一些 util class,和写行业样式有本质区别。

    在使用 Sass/Less 的项目里,util 可以用 mixin 代替,好处是 class 更少,坏处是编译后的重复代码更多。

    我觉得,css module 和 styled components 这种把 CSS 和 JS 揉在一起的写法,是背离“样式与逻辑”分离的设计原则的。更像是 native app 的开发方式。作用域问题,可以通过规范 class 命名解决。

    React 火了之后,像 Bootstrap 这样设计很优秀的“传统”前端组件库的关注度越来越少了,其实有很多值得学习的东西。
    attackonFourier
        40
    attackonFourier  
       2019-09-22 11:11:16 +08:00
    tailwindcss 这样的 atom class 复杂点的页面你就看你的 class 有多长吧
    zthxxx
        41
    zthxxx  
       2019-09-22 11:29:10 +08:00
    @AnnatarHe
    @Flands
    @TheFLY
    @Elmer
    @joshua7v

    各位用 tailwind 的是不是学 CSS 的时候都没学过 HTML 内联样式?
    duan602728596
        42
    duan602728596  
       2019-09-22 11:49:05 +08:00 via iPhone
    css-module,因为这个方案解决了写 css 最头疼的问题:命名,同时影响最小。其他方案不喜欢的原因是,IDE 的语法提示不友好,配合 css 预处理器会很麻烦。
    TheFLY
        43
    TheFLY  
       2019-09-22 12:25:56 +08:00
    所以现在表达赞美都这么辛苦了吗,你刚学内联的时候思路能有这么清晰?
    ericgui
        44
    ericgui  
    OP
       2019-09-22 13:10:13 +08:00
    @TheFLY what ?
    luoway
        45
    luoway  
       2019-09-22 13:14:12 +08:00   ❤️ 1
    @AnnatarHe #2
    这叫 CSS 原子类。
    其实这是错误写法,增加了记忆成本,效果和行内样式一样,仅仅是减少了需要拼写的字符数量。一般前端会以为这能够降低文件尺寸,但如果网页开启了 gzip 压缩,那这种减少不会影响网络数据传输量,因为重复的字符串会被 gzip 压缩。

    实际上,这种做法很少会被团队采用,仅有部分个人前端开发会做尝试。可读性是团队开发特别关注的问题,CSS 原子类降低了可读性,所以自概念提出后并没有取得前端社区认可。
    TheFLY
        46
    TheFLY  
       2019-09-22 16:15:58 +08:00
    @ericgui What ?
    AnnatarHe
        47
    AnnatarHe  
       2019-09-22 16:30:59 +08:00
    @zthxxx

    design system 了解一下?另外你说的 inline style 认真的吗?实习生面试能过吗?
    jin5354
        48
    jin5354  
       2019-09-22 16:44:00 +08:00   ❤️ 5
    我的天老爷,看了下你们说的 tailwindcss,这不就是 IE6 时代的 CSS 原子类?真实梦回 2012 (苦笑)
    三四年前的大厂前端面试 css 部分偶尔还会问问原子类的优劣,这东西就和 bootstrap 一样,适合不讲究时用用,比如后端随便糊出个页面;真实的前端项目都自己好好抽象 css 类,原子类怎么维护

    附远古讨论贴: https://www.zhihu.com/question/22110291
    dvaknheo
        49
    dvaknheo  
       2019-09-22 19:03:20 +08:00
    bootstrap 要配合 less 来用啊, 不要输出 boostrap 的原子类,而是语义化的 CSS
    TristanYang
        50
    TristanYang  
       2019-09-22 21:36:49 +08:00
    你说的那个组长是不是我?哈哈哈,我现在做项目首选 styled-components 也建议组员用。
    l1xnan
        51
    l1xnan  
       2019-09-22 22:31:11 +08:00 via Android
    做的几个 react 项目都是 typescript + css modules
    zthxxx
        52
    zthxxx  
       2019-09-22 23:28:14 +08:00
    @AnnatarHe

    是认真的

    认真的问你们学的时候,没有学过每个元素都只写内联样式的弊端和局限性吗?

    因为回到 CSS 原子类就基本等同于变相写 inline style 内联样式,你的 「才意识到正确的 css 写法」就和楼上说的一样梦回 2012
    dodo2012
        53
    dodo2012  
       2019-09-23 01:17:11 +08:00
    推荐 tailwind 是真的么?这种写法前两年都是不推荐的,怎么又流行起来了?要在 html 里写一堆,增加记忆和代码冗余,可以自己定义一个类不假,但都自己定义了,自己手写不更方便?
    wdhwg001
        54
    wdhwg001  
       2019-09-23 01:24:38 +08:00   ❤️ 1
    Tailwind 确实是个原子类的 CSS 框架,但实际上并不是梦回 2012,因为现在我们可以在原子类的基础上加抽象了,而这也是 Tailwind 所宣传的“Component-friendly”。

    在这个基础上,Tailwind 的思想实际上是要更有借鉴性的,即使用原子类的方式对裸 CSS 封装抽象,然后使用前缀的形式划定原子类的响应式范围,然后在组件里整合多个原子类。

    相比纯原子类的写法,Tailwind 更希望的应该是“btn btn-blue”这种,对一个元素应用这一整个“原子类、组件类”多级抽象中的一个或多个,从而实现可维护性和开发便利两者的共存。

    觉得它的写法只有"clearfix mt30"这样的上古用法的,可能连官网都没看完就喷起来了吧。
    wdhwg001
        55
    wdhwg001  
       2019-09-23 01:29:33 +08:00
    更进一步的,Tailwind 同时也遵循了“如非必要,勿增实体”的剃刀律,即如果你快速撸单页,或者需要给富文本加样式的话,完全可以用原子类一把梭,它所提供的原子类也比旧式的“mt30”要更语义化而非数值化。

    在这个基础上,要怎样抽象出组件类则基本上是开发者自行决定的,在 Tailwind 一把梭撸出来的页面上把 class 抽象出来也没那么费劲。
    find456789
        56
    find456789  
       2019-09-23 01:40:42 +08:00
    @luoway 兄台,你觉得 团队选 bulma 怎么样
    ericgui
        57
    ericgui  
    OP
       2019-09-23 02:19:29 +08:00 via Android   ❤️ 1
    @find456789 我目前就用 bulma
    acthtml
        58
    acthtml  
       2019-09-23 09:14:36 +08:00
    @AnnatarHe

    请教下,你喜欢 tailwind css 的什么特性,没有看到什么优势啊? 主要是将基础样式抽象成类目,当这个写法跟行内样式没啥区别,只方便了前期原型开发,后期不利于维护。
    luoway
        59
    luoway  
       2019-09-23 09:53:19 +08:00   ❤️ 1
    @find456789 #56 CSS 框架能够提高开发效率,只是过于细碎的原子类则因为降低了可读性,过犹不及。所以专注于提高项目开发效率的 CSS 框架是值得肯定的。
    bulma 是相较于 Bootstrap 更轻量的框架,只是中文文档很少,可能在 CSS 框架推陈出新过程中逐渐淘汰,但在选择有限的情况下仍值得一试。
    jin5354
        60
    jin5354  
       2019-09-23 09:59:54 +08:00   ❤️ 1
    @wdhwg001 实际上我不但看了官网,还因为好奇为什么 2019 还有人搞这种东西,去看了作者写的原动机 https://adamwathan.me/css-utility-classes-and-separation-of-concerns/,之后才来回复的。我很好奇你是如何揣测的,我会认为你的最后一句话是在人身攻击。

    Tailwind 作者的动机就和原子类一模一样——使用语义化 css 『起类名麻烦』『抽象复用麻烦』『抽象好之后做改动麻烦』,最后得出结论『还是实用性第一的原子类好使』『视作 HTML 依附于 CSS 』。

    这种实用性第一的写法肯定是有市场的,随便糊糊就能出页面就像『用什么 React/Vue,老夫用 jQuery 就够了』适用于你的剃刀律,适合快速出活。至于你说的组件类,作者文章表明了『你觉得能复用你就抽』,没有组件类先行的约束是不会提高可维护性的。官网和组件示例上满屏幕的『 w-4 h-4 mr-2 』已经表现了 Tailwind 鼓励 100% 正统的原子类用法,不用粉饰什么了。
    jin5354
        61
    jin5354  
       2019-09-23 10:00:42 +08:00
    dany813
        62
    dany813  
       2019-09-23 10:15:22 +08:00
    @Flands 但是这个还是要学习这个语法糖啊,不习惯
    hyy1995
        63
    hyy1995  
       2019-09-23 10:30:47 +08:00
    前端真是喜欢玩奇奇怪怪的花样。。。css modules 就行了,楼上有人推荐的 tailwindcss 我看了下,我觉得不好维护,也不利于团队开发。。。
    windyCity
        64
    windyCity  
       2019-09-23 11:06:41 +08:00
    我认为 类似 tailwindcss 或者说原子类 (包含基于原子类提取的通用样式),在项目中可以使用,但是,必须控制在在项目内通用性极高的样式,比如,按钮通用样式与按钮交互效果等,提交开发便捷性,但是要严格控制数量,避免造成记忆压力;

    团队项目中还是要考虑众人合作的开发舒适度的,不能你认为好用就行
    Flands
        65
    Flands  
       2019-09-23 11:34:51 +08:00
    确实没接触到过原子类这种写法。
    惊艳是因为 ‘组合‘ 写出 CSS,这种 ‘一个样式就是一个类’ 的写法很少做,工作项目大部分都是几个样式合并成一个类,然后在项目中复用。
    个人感觉这些不矛盾,项目中可以少量原子类以达到复用的目的。只要命名一眼能看懂,`font-size-16`这种。
    Sapp
        66
    Sapp  
       2019-09-30 16:49:24 +08:00
    我现在都是这么写的

    <span css={(ds) => ({...flexCenter(),width: 50, color: ds.color.primary)}>你瞅瞅</span>
    charlie21
        67
    charlie21  
       2020-11-05 12:59:38 +08:00
    component-friendly 本来就是表象 组件复用都是表象,html-friendly 本来就是表象,如果你只看表象,那么诶 你会感觉很不适应,让你感觉不适应的东西会有很多。真正重要的问题是什么?是你关注的是什么。如果你关注的是对于状态的抽象,对于状态的抽象、对于状态的控制、对于状态的精准控制,那么你的日子会好过很多
    chenjiangui998
        68
    chenjiangui998  
       2021-06-06 23:26:48 +08:00
    还是 Vue 和 angular 舒服, react 想搞个 CSS 样式隔离都要搞一堆方案还都不完美
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2968 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 12:47 · PVG 20:47 · LAX 04:47 · JFK 07:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.