现代 React Web 开发实战
宋一玮
FreeWheel 中国研发中心前端架构师
16115 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 31 讲
现代 React Web 开发实战
15
15
1.0x
00:00/00:00
登录|注册

07|组件样式:聊聊CSS-in-JS的特点和典型使用场景

你好,我是宋一玮,欢迎回到 React 组件的学习。
上节课我们稍微深入了解了 React 组件的渲染机制,讲到虚拟 DOM 是真实 DOM 的抽象,React 开发者通过 JSX 等 API 声明组件树,React 内部则会生成对应的虚拟 DOM;组件 props、state、context 有变化时会触发协调过程,通过 Diffing 算法比对新旧虚拟 DOM,最终只针对差异部分调用 DOM API 改变页面。
这节课我们来学习一项比较轻松的内容:组件样式。Web 前端需要 CSS 来定义样式,应用拆分成组件后,CSS 也需要组件化。
oh-my-kanban 项目中,你已经见识到了在 JS(JSX)文件中导入 CSS 文件,你可能会好奇,一个 JSX 文件对应一个 CSS 文件,这不就是 CSS 的组件化了吗?其实这还远不够。CSS 与 JS 天生就是异构的,对于 React 的组件层次结构,CSS 很难做到一一对应。此外,不同组件中样式的隔离也是必须的。
那么我们就有下面这些问题需要解决:
如何为 React 组件定义样式,才能做到样式与组件的共生?
如何防止不同组件的 CSS 互相影响?
如何在 CSS 里使用 props 或 state 值?
前端尤其是 React 社区,先后推出了许多 CSS-in-JS 框架来解决这些问题。在这节课我会以流行度较高的 emotion 为例,介绍 CSS-in-JS 的特点和使用中的注意事项。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

CSS-in-JS技术是一种在组件化开发中解决CSS样式不足的新兴技术。本文通过介绍CSS-in-JS的基本概念和`emotion`框架的具体应用,为读者提供了对CSS-in-JS技术的全面了解和实际操作指导。文章首先解释了CSS-in-JS的基本实现方式,包括通过DOM API设置元素样式、动态插入CSS规则等。重点介绍了`emotion`框架,该框架相对于其他CSS-in-JS框架更注重开发者体验,功能相对完整。文章还详细讲解了使用`emotion`框架的基本用法,包括安装和基本样式定义,并展示了其在实际项目中的应用。此外,还介绍了`emotion`框架的自动浏览器兼容性处理以及在VSCode中使用相关扩展插件的方法。通过实例演示了嵌套选择器、样式组合与复用、伪类选择器以及在样式中使用组件数据等方面的应用。最后,还介绍了CSS-in-JS的其他选择,如`Styled-components`和`CSS Modules`。总之,本文通过深入浅出的方式,全面介绍了CSS-in-JS技术及其在实际项目中的应用,为读者提供了宝贵的学习和实践指导。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《现代 React Web 开发实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(14)

  • 最新
  • 精选
  • 🐑
    置顶
    你好,我是《现代React Web开发实战》的编辑辰洋,这是👇项目的源代码链接,供你学习与参考:https://gitee.com/evisong/geektime-column-oh-my-kanban/releases/tag/v0.7.1
    2022-09-14归属地:北京
  • 大海
    【原有KanbanBoard和KanbanColumn之间插入了一层名为 EmotionCssPropInternal 的组件,与 KanbanColumn 平级还插入了一个 Insertion 组件】这样会导致Developer Tools 几乎无法使用吧。因为页面有大量多余的组件,影响调试,特别是大型页面

    作者回复: 你好,大海,你提的这个问题切中要害。我和我的同事们在使用emotion的初期也对这个问题很苦恼。但后来发现React Developer Tools从哪个版本开始就可以过滤组件树的组件了,这个问题就没再困扰过我们。 请在React Developer Tools的设置(小齿轮)中,切换到“组件”页签,在底部的“隐藏组件…”中新加两条规则:name: Emotion, name: Insertion,然后刷新页面,你的组件树就清净了。

    2022-09-11归属地:内蒙古
    12
  • Custom_DOM
    为什么要做css in js啊,我觉得我可能有点难以接受,我觉得预编译scss 和less分离开单独做一个文件,更好维护样式呀,而且一个页面存js突然混入写css,让我看本js文件代码特别难受,会多出一些代码,比如可能是强迫症,我甚至通常情况下不愿意写style,我通常终是优先选择使用className,结合各种类选择器的合理规划,一个组件,我通常也写不了几个css类的感觉,更好维护与修改,可以说一下css In js可以具体解决开发中哪些痛点吗?

    作者回复: 你好,Custom_DOM,我非常能理解你对CSS-in-JS的看法。我自己也是从table到div+css、从BEM到SCSS一路写过来的,一直以来也认为HTML写结构、CSS写样式、JS写逻辑。 但当我熟悉React、习惯JSX语法后,我不再纠结是否一定要把HTML和JS隔离开——在前端组件开发这个领域里,HTML和JS只是具体的内部实现技术,在组件与组件之间、组件与整体应用之间起更关键作用的,还是“接口”。这层抽象隐藏了细节,更有利于复杂应用的开发。这个思路我在第13节课也有介绍。 那么,在前端组件这个体系下,我们该如何看待样式?它是组件接口的一部分,还是内部实现的一部分? 然后就来到我在这节课开篇里提到的,CSS技术在前端组件开发中的不足:……领域不同,CSS(截止到目前标准化的)尚不具备现代前端组件化开发所需要的部分领域知识和能力,所以需要其他技术来补足。这些知识和能力主要包括四个方面: * 组件样式的作用域需要控制在组件级别; * 组件样式与组件需要在源码和构建层面建立更强的关联; * 组件样式需要响应组件数据变化; * 组件样式需要有以组件为单位的复用和扩展能力。 举个稍微具体的例子,当我们在组件树中使用了<KanbanCard />,如何能保证KanbanCard对应的CSS一定会被加载?(哪怕开发者忘记了) 另外,这节课主要还是介绍CSS-in-JS的概念和Emotion的基本使用,至于如何让组件和样式代码更整洁的最佳实践,在第12节课的重构中会涉及到,第24节课的项目中也会有例子。

    2022-10-28归属地:北京
    7
  • 右耳漏风
    宋老师,您可以展开说一下选择 emotion 而不是 styled-components 的原因吗?谢谢

    作者回复: 你好,右耳漏风,emotion和styled-components都是很成熟的CSS-in-JS框架,在各类React应用项目中都有广泛使用。 说来我当时的选型,还是偏向我个人的taste。两者实现机制类似,都是动态生成class样式,然后在DOM中插入<style>,性能不会有太大差异。在我看来,styled-components中 styled.div 这样的API对React组件代码整体侵入性比较高,相较而言,emotion的css prop直接依附在了React内建的HTML元素tag上,侵入性低些,万一以后有整体剥离或替换CSS技术栈的需要,成本风险更加可控。 当然后来我被打脸了,styled-components从V4开始也利用babel plugin实现了 css prop,emotion也提供了styled API。

    2022-09-09归属地:内蒙古
    5
  • .
    老师可以在下一节课的开头,讲讲上一节课留下的思考题吗?

    作者回复: 你好,(点),这是个好建议,谢谢。专栏编辑也和我做过相关的设计,会不定期安排课程加餐,里面会讨论留言区的热点问题和思考题。

    2022-09-07归属地:内蒙古
    2
    5
  • 东方奇骥
    感觉还是更喜欢Svelte、Vue这类前端框架。 React把html, js, css都合在一起了,感觉更像在写后端代码,不知道React作者是不是后端出身转前端的。

    作者回复: 你好,东方奇骥,虽然没机会在工作中使用,但我个人也很喜欢Svelte框架,它的API和用法都给我带来亲切感。其实这两年的主流框架之间都有互相借鉴一些别家的优点,比如JSX、虚拟DOM、组件组合和嵌套、利用编译工具等。 HTML、JS、CSS是写在一起或是分开来写,都有各自的利弊。但正因为这三个框架的用户基数大、社区活跃,每种写法均有一定的用户基础,所以无论哪种都算是开发者(或团队)的“taste”,无所谓优劣。 不过毕竟这个专栏是在讲React,我多少也为React澄清一下 :) 在React中,HTML、JS、CSS也可以分开来写: 1. 这节课里的emotion这项CSS-in-JS技术是独立于React以外的,也可以用于Vue框架;而React里也可以利用最基础的CSS Modules技术分开写独立的CSS文件; 2. 在React组件中,可以把多个Hooks抽取成自定义Hook写在独立的JS文件中,也可以把一些公共逻辑抽象成高阶组件,这样就可以得到尽可能“纯净”的JSX文件,这部分内容后面的课程会讲到; 3. 虽然很少见,但开发者也可以选择把React技术仅作为View来使用,将React的JSX和事件处理整合进其他JS框架,比如Backbone.js中:https://zh-hans.reactjs.org/docs/integrating-with-other-libraries.html#embedding-react-in-a-backbone-view 。

    2022-09-06归属地:北京
    3
  • 杨永安
    Styled-components的例子中,没太明白srtled.button是如何应用到Button组件的

    作者回复: 你好,杨永安,styled.button 是一个函数,后面跟着 ` ` 是前面讲到的“带标签的模版字符串”语法,可以认为是在调用 styled.button 函数,` ` 内是传给它的参数,而 styled.button 函数的返回值是一个类似这样的自定义组件: const Button = ({ cssStyles, children, ...restProps }) => { // 处理 cssStyles return ( <button className="动态生成的类名" {...restProps}> {children} </button> ); }; 请注意这段代码是根据我自己的理解拼出来的,肯定少了不少细节,但原理是类似的。 然后你就可以在其他JSX中使用这个Button组件了。

    2022-09-07归属地:北京
    2
    2
  • 大海
    在 jsx 里边写 css 样式,可读性变差了

    作者回复: 你好,大海,我很赞同你说的,本身css与js就是异构代码,尤其是在样式复杂的时候,css行数比较多,会影响代码可读性。 这节课的目标主要还是让大家了解CSS-in-JS的原理和用途。在后面的第12~13节课,我们会对oh-my-kanban项目做一次重构,那时会把css属性都抽取成独立的变量,提高可读性。敬请期待。

    2022-09-11归属地:内蒙古
    1
  • 超级读书郎
    这一节整理的真好,包含了几种方案,并且深入讲解了emotion方案的几种开发中常见的case。另外稳文中的各种外链也很有用处。受益匪浅。

    作者回复: 你好,超级读书郎,感谢你对这节课内容的认可。后面的课程也尽可能地为各类技术点加入了典型用例,希望能帮到大家。

    2022-11-09归属地:北京
  • 大海
    【你可能对 cssargs 这样的函数写法感到陌生】文中代码并没有这个函数啊

    作者回复: 你好,大海,感谢你的抓虫。抱歉这里由于录入问题丢失了字符,正确内容应为: css`args` 其中css是函数名,args可以是任意字符串或模版字面量。

    2022-09-11归属地:内蒙古
    2
收起评论
显示
设置
留言
14
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部