为什么会有css-in-js。

它是一种将css代码捆绑在JavaScript 代码中的解决方案。旨在解决css的局限性,例如缺乏动态功能,作用域和可移植性。

  • 主要是体现在开发方式上,因为是组件化的开发方式,区别于以前的页面开发,对于css文件的引入,我们更多的是希望对应组件开发时所写的css代码仅在当前组件范围内引进使用生效,这就需要css模拟实现作用域概念。

  • 可移植性主要是体现在我们希望在不同组件当中共用公共部分的css样式,所以可以把公共部分的代码抽离出来写到一个js文件内,在需要的地方引入使用即可,而不必复制文件内容,减少操作错误。

  • css本身缺乏动态功能,不能根据条件来决定给某一个元素添加什么样的样式。如果我们将css代码写在了JavaScript文件当中,我们就可以利用js的动态功能为元素去动态添加样式。

css-in-js 方案的优缺点

优点:

  • 让css代码拥有独立的作用域,防止css代码泄漏到组件的外部,防止样式冲突。

  • 让组件更具可移植性,实现开箱即用,轻松创建松耦合的应用程序。

  • 让组件更具可重用性,只需编写一次即可,可以在任何地方运行。不仅可以在同一应用程序中重用组件,而且可以在使用相同框架构建的其他应用程序中重用。

  • 让样式具有动态功能,可以将复杂的逻辑应用于样式规则,如果需要创建动态功能的复杂UI,它是理想的解决方案。

缺点:

  • 为项目增加额外的复杂性;

  • 自动生成的选择器大大降低了代码的可阅读性。主要是在于调试时,自动生成的都是随机的字符串。

综合而言,css-in-js方案的优点大于缺点。

babel配置以支持css属性的两种方式

  1. Emotion 库

emotion 库是css-in-js方案具体实施的一个库,它是一个旨在使用JavaScript编写css样式的库。

安装:

npm install @emotion/core @emotion/styled

npm install @emotion/core @emotion/styled

注意:@emotion/core 在新版本中已经更名为 @emotion/react

  1. css属性支持

  1. JSX Pragma

通知babel不再需要将jsx语法转换为 React.createElement() 方法,而是转换为jsx() 方法。

使用emotion

Input

Output

使用前

<img src="avatar.png"/>
React.createElement('img', {src: 'avatar.png'})

使用后

<img src="avatar.png"/>
jsx('img', {src: 'avatar.png'})

导入emotion库并配置使用。

/** @jsx jsx */  // 这个是提供给babel做解释emotion相关代码时配置的固定的特殊格注释
import jsx from '@emotion/core'; //`@emotion/core` 现在更名为`@emotion/react`了, 所以要这样写:`import { jsx } from '@emotion/react'`.
  1. Babel Preset (推荐使用的方式)

  1. npm run eject 弹射出react app项目的底层配置。

  1. 安装@emotion/babel-preset-css-prop 预设模块

npm install @emotion/babel-preset-css-prop
  1. 在package.json文件中找到babel属性,加入如下内容:

"presets": ["react-app","@emotion/babel-preset-css-prop"
]

配置emotion的 babel预设集就不需要在代码中引入jsx方法以及对应的特殊注释了。

  1. css方法的两种调用方式

  1. String styles

const style = css`width: 100px;height: 30px;background: skyblue;
`<div css={style}>App works...</div>
  1. object styles

const style = css({width: "100px",height: "30px",background: "skyblue"
})<div css={style}>App works...</div>

此时的css方法会帮我们把css样式转换成js模块嵌入到组件代码中。

{"name": "2h52qn-objectStyle","styles": "width:100px;height:30px;background:skyblue;label:objectStyle;","map": "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9odWlxdWFuZGVuZy9wcm9qZWN0cy9sZy1mZWQtbHAvbXktbW9kdWxlL3JlYWN0LXRlc3Qvc3JjL2NvbXBvbmVudHMvQ291bnRlci9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFlc0IiLCJmaWxlIjoiL1VzZXJzL2h1aXF1YW5kZW5nL3Byb2plY3RzL2xnLWZlZC1scC9teS1tb2R1bGUvcmVhY3QtdGVzdC9zcmMvY29tcG9uZW50cy9Db3VudGVyL2luZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0J1xuLy8gLyoqIEBqc3gganN4ICovXG4vLyBpbXBvcnQgeyBqc3ggfSBmcm9tICdAZW1vdGlvbi9yZWFjdCdcbmltcG9ydCB7IG9ic2VydmVyIH0gZnJvbSAnbW9ieC1yZWFjdC1saXRlJ1xuaW1wb3J0IHsgdXNlUm9vdFN0b3JlIH0gZnJvbSAnLi4vLi4vc3RvcmUnXG5pbXBvcnQgeyBjc3MgfSBmcm9tICdAZW1vdGlvbi9yZWFjdCdcblxuZnVuY3Rpb24gQ291bnRlciAocHJvcHMpIHtcbiAgY29uc3QgeyBjb3VudGVyU3RvcmUgfSA9IHVzZVJvb3RTdG9yZSgpXG4gIGNvbnN0IHsgY291bnQsIGluY3JlbWVudCwgZGVjcmVtZW50IH0gPSBjb3VudGVyU3RvcmVcbiAgY29uc3Qgc3RyaW5nU3R5bGUgPSBjc3NgXG4gICAgd2lkdGg6IDEwMHB4O1xuICAgIGhlaWdodDogMzBweDtcbiAgICBiYWNrZ3JvdW5kOiBza3libHVlO1xuICBgXG4gIGNvbnN0IG9iamVjdFN0eWxlID0gY3NzKHtcbiAgICB3aWR0aDogMTAwLFxuICAgIGhlaWdodDogMzAsXG4gICAgYmFja2dyb3VuZDogJ3NreWJsdWUnXG4gIH0pXG4gIGNvbnNvbGUubG9nKHN0cmluZ1N0eWxlLCBvYmplY3RTdHlsZSlcbiAgcmV0dXJuIChcbiAgICA8c2VjdGlvbj5cbiAgICAgIDxkaXYgY3NzPXtzdHJpbmdTdHlsZX0+QXBwIHdvcmtzLi4ud2l0aCBzdHJpbmcgU3R5bGVzPC9kaXY+XG4gICAgICA8ZGl2IGNzcz17b2JqZWN0U3R5bGV9PkFwcCB3b3Jrcy4uLndpdGggb2JqZWN0IFN0eWxlczwvZGl2PlxuICAgICAgPGg0IHN0eWxlPXt7IHdpZHRoOiAxMDAsIGJhY2tncm91bmQ6ICdibHVlJyB9fT7orqHmlbDlmajmoYjkvos8L2g0PlxuICAgICAgPGJ1dHRvbiBvbkNsaWNrPXsoKSA9PiBkZWNyZW1lbnQoKX0+LTE8L2J1dHRvbj5cbiAgICAgIDxzcGFuXG4gICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgd2lkdGg6ICcxMDBweCcsXG4gICAgICAgICAgZGlzcGxheTogJ2lubGluZS1ibG9jaycsXG4gICAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgICBmb250U2l6ZTogJzIwcHgnXG4gICAgICAgIH19XG4gICAgICA+XG4gICAgICAgIHtjb3VudH1cbiAgICAgIDwvc3Bhbj5cbiAgICAgIDxidXR0b24gb25DbGljaz17KCkgPT4gaW5jcmVtZW50KCl9PisxPC9idXR0b24+XG4gICAgPC9zZWN0aW9uPlxuICApXG59XG5cbmV4cG9ydCBkZWZhdWx0IG9ic2VydmVyKENvdW50ZXIpXG4iXX0= */"
}

并且会通过类的方式来使用。

<div class="css-2h52qn-objectStyle">App works...with object Styles</div>

emotion中css属性优先级

props对象中的css属性优先级高于组件内部的css属性。

在调用组件时可以覆盖

覆盖组件默认样式。

styled components 样式话化组件

样式话化组件就是用来构建用户界面的,是emotion库听过库提供的另一种为元素添加样式的方式。

1. 创建样式化组件(styled.xxx)

使用前需要引入styled 支持库@emotion/styled

  1. string styles

const button = styled.button`width: 300px;height: 30px;background: skyblue;
`;// 拓展:还可以根据props属性覆盖样式
// 例如: background: ${props => props.bgColor || 'skyblue'};
  1. object styles

const button = styled.button(props => ({color: props.color || 'red',width: 300,height: 30,background: 'pink'
}))

2. 为任何组件添加样式

同样有string styles和object styles的区别。

const Demo = ({className}) => <div className={className}> </div>const Fancy = styled(Demo)`color: red;
`

3. 为特定父级下的子组件添加样式

通过父组件设置子组件样式

同样有string styles和object styles的两种方式。

const Child = styled.div`color: red
`const Parent = styled.div`${Child}{color: green}
`<Parent><Child/></Parent>
const Child = styled.div({color: 'red'
})const Parent = styled.div({[Child]:{color: 'yellow'}
})<Parent><Child/></Parent>

4. css选择器&:嵌套选择器

& 表示组件本省。

const Container = styled.div`color: red;& > a {color: pink;}
`

5. 样式化组件的as 属性

要使用组件中的样式,但要改变呈现的元素,可以使用as 属性。

const Button = styled.button`color: red
`<Button as="a" href="/#">Click me</Button> 

6. 样式组合

在样式组合中,后调用的样式优先级高于先调用的样式。

const base = css`color: skyblue;
`
const danger = css`color: red;
`<button css={[base, danger]}>样式组合的button</button> 

7. 全局样式Global

全局样式的应用需要使用到emotion当中的Global组件,及其 styles属性。

const styles = css`body: {margin:0; background: tomato; color: skyblue;}
`
function App() {return <><Global styles={styles}>app is working...</>
}

8. 使用keyframes方法定义关键帧动画

在emotion中定义帧动画需要用到keyframes 方法。


const move = keyframes`0% {background: skyblue;left: 0;top: 0;font-size: 1rem;}100% {background: green;left: 600px;top: 300px;font-size: 2rem;}
`
const box = css`color: red;width: 200px;height: 200px;position: absolute;animation: ${move} 2s ease;
`<div css={box}>animate box</div>

9. emotion 主题

  • 下载模块:

npm install emotion-theming

  • 引入ThemeProvider

import {ThemeProvider} from 'emotion-theming' // 现在也合并到了@emotion/react中
  • 添加主题内容

ThemeProvider应该放在所有组件的最外层。

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
// import { Provider } from 'react-redux'
// import store from './store'import { Global } from '@emotion/react'
import styles from './styles'
import { ThemeProvider } from '@emotion/react'const theme = {color: {primary: 'tomato'}
}ReactDOM.render(<ThemeProvider theme={theme}><App /></ThemeProvider>,document.getElementById('root')
)
  • 获取主题内容

在内部组件中可以通过一下方式获取主题theme的内容。

const primaryColor = props => css`color: ${props.color.primary};
`<div css={primaryColor}></div>
  • 也可以使用钩子函数useTheme() 的方式来获取主题内容

import { useTheme } from '@emotion/react'
function Demo() {const theme = useTheme()console.log(theme)
}

CSS-in-JS方案及实现库介绍相关推荐

  1. 介绍html CSS和JS的定义或引用

    现在的网页设计,一般采用内容与表现相分离,即网页的组成包含:内容(HTML)+ 样式(CSS) + 脚本(JS) . 浏览器解析原理 服务器接收到HTML->解析HTML结构建DOM树-> ...

  2. JSS (css in js) emotion库的使用

    原文链接: JSS (css in js) emotion库的使用 上一篇: webgl 左手和右手坐标系转换 下一篇: ua-parser-js 判断设备类型和版本 针对不同的机型做降级 虽然灵活, ...

  3. vue手机端项目php,MintUI基于Vue.js移动端组件库详解

    Mint UI 包含丰富的 CSS 和 JS 组件,能够满足日常的移动端开发需要.接下来通过本文给大家分享Mint UI 基于 Vue.js 移动端组件库,需要的朋友参考下吧,希望能帮助到大家. 官网 ...

  4. 如何用 CSS + HTML + JS 创建桌面应用

    05月 31 Node 如何用 CSS + HTML + JS 创建桌面应用 | https://h.lishaoy.net/nwjsElectronjs.html || 最近研究了一下基于 Chro ...

  5. 前端面试题 HTML、CSS、JS、Vue、Es6

    第一部分 HTML&CSS整理答案 什么是HTML5? 答:HTML5是最新的HTML标准. 注意:讲述HTML5推出的设计目的,以及现在市场的使用情况,浏览器支持情况等.... 设计目的 H ...

  6. 2023前端面试题总结(html,css,js)

    目录 HTML篇 1.HTML5常用的语义化标签有哪些?并写出你对语义化的理解? 2.列举HTML的block元素和inline元素 3.块元素和行内元素的区别? 4. iframe 是什么?有什么缺 ...

  7. 十多款优秀的Vue组件库介绍

    十多款优秀的Vue组件库介绍 1. iView UI组件库 iView 是一套基于 Vue.js 的开源 UI 组件库,主要服务于 PC 界面的中后台产品.iView的组件还是比较齐全的,更新也很快, ...

  8. .NET 中文件嵌套,例如:cshtml文件下面嵌套css和js【机器翻译】

    越来越多的我发现自己在我的一些较大的Web项目中丢失了文件.有很多内容要处理 - HTML视图,几个派生CSS页面,页面级CSS,脚本库,应用程序范围的脚本和页面特定的脚本文件等等.幸运的是,我使用R ...

  9. 智慧家安监控系统——用Java + html、css、js实现

    目录 系统背景 系统介绍 前端 SVG 监控情况 弹出窗口 图表 后端 表格处理 Servlet类 数据处理类 前后端的数据交互内容及设计 采用Servlet技术 采用Ajax技术 前后端数据交互操作 ...

最新文章

  1. Windows Server 2008 R2之三十二:证书注册WEB服务(一)
  2. 【练习】OC语法的简单复习
  3. 在servlet中设置的字符编码集为什么还会出现乱码(亲测)
  4. Idoc学习笔记----获取查询Idoc信息
  5. VTK:相互作用之Assembly
  6. 在GridView中使用Cache
  7. C语言中的EOF符号常量
  8. 快学好这个去给学妹修热水器
  9. 小艾k个人发卡网PHP源码
  10. CCF 201503-1 图像旋转
  11. android studio下生成aar文件,本地调用
  12. 使用jsoncpp解析生成json
  13. 黑客利用 Gatekeeper 0day 攻击 MacOS 计算机
  14. maxdea如何计算指数_10分钟计算出指数温度,开始基金定投之旅~
  15. 女生学Java软件开发好就业吗
  16. 汉诺塔的图解递归算法
  17. 广域网宽带接入技术八ADSL技术
  18. docker 定时重启脚本_定时启动docker容器
  19. python筛选出csv满足某条件的行_Python之根据条件筛选特定行
  20. 国内百兆独立服务器哪里的比较便宜镇江电信好吗

热门文章

  1. 收支系统php,财务收支管理软件系统
  2. cc视频直播的SDK集成
  3. Tensorflow执行PB模型问题
  4. 波比的w可以挡机器人的q_LOL波比W可以挡哪一些英雄技能
  5. Python 千猫图,简单技术满足你的收集控
  6. 微信公众号,服务号,小程序,微信支付对接需要注册哪些账号
  7. 女朋友背着我,用 Python 偷偷隐藏了她的行踪
  8. python取列表前几个元素_python list输出最后10个元素
  9. 转 超棒的动效设计工具及讲解
  10. Linux固态硬盘 设置写入缓存,固态硬盘性能的背后:浅论写入缓存设置