CSS-in-JS方案及实现库介绍
为什么会有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属性的两种方式
Emotion 库
emotion 库是css-in-js方案具体实施的一个库,它是一个旨在使用JavaScript编写css样式的库。
安装:
npm install @emotion/core @emotion/styled
npm install @emotion/core @emotion/styled
注意:@emotion/core 在新版本中已经更名为 @emotion/react
css属性支持
JSX Pragma
通知babel不再需要将jsx语法转换为 React.createElement() 方法,而是转换为jsx() 方法。
使用emotion |
Input |
Output |
使用前 |
|
|
使用后 |
|
|
导入emotion库并配置使用。
/** @jsx jsx */ // 这个是提供给babel做解释emotion相关代码时配置的固定的特殊格注释
import jsx from '@emotion/core'; //`@emotion/core` 现在更名为`@emotion/react`了, 所以要这样写:`import { jsx } from '@emotion/react'`.
Babel Preset (推荐使用的方式)
npm run eject 弹射出react app项目的底层配置。
安装@emotion/babel-preset-css-prop 预设模块
npm install @emotion/babel-preset-css-prop
在package.json文件中找到babel属性,加入如下内容:
"presets": ["react-app","@emotion/babel-preset-css-prop"
]
配置emotion的 babel预设集就不需要在代码中引入jsx方法以及对应的特殊注释了。
css方法的两种调用方式
String styles
const style = css`width: 100px;height: 30px;background: skyblue;
`<div css={style}>App works...</div>
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
string styles
const button = styled.button`width: 300px;height: 30px;background: skyblue;
`;// 拓展:还可以根据props属性覆盖样式
// 例如: background: ${props => props.bgColor || 'skyblue'};
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方案及实现库介绍相关推荐
- 介绍html CSS和JS的定义或引用
现在的网页设计,一般采用内容与表现相分离,即网页的组成包含:内容(HTML)+ 样式(CSS) + 脚本(JS) . 浏览器解析原理 服务器接收到HTML->解析HTML结构建DOM树-> ...
- JSS (css in js) emotion库的使用
原文链接: JSS (css in js) emotion库的使用 上一篇: webgl 左手和右手坐标系转换 下一篇: ua-parser-js 判断设备类型和版本 针对不同的机型做降级 虽然灵活, ...
- vue手机端项目php,MintUI基于Vue.js移动端组件库详解
Mint UI 包含丰富的 CSS 和 JS 组件,能够满足日常的移动端开发需要.接下来通过本文给大家分享Mint UI 基于 Vue.js 移动端组件库,需要的朋友参考下吧,希望能帮助到大家. 官网 ...
- 如何用 CSS + HTML + JS 创建桌面应用
05月 31 Node 如何用 CSS + HTML + JS 创建桌面应用 | https://h.lishaoy.net/nwjsElectronjs.html || 最近研究了一下基于 Chro ...
- 前端面试题 HTML、CSS、JS、Vue、Es6
第一部分 HTML&CSS整理答案 什么是HTML5? 答:HTML5是最新的HTML标准. 注意:讲述HTML5推出的设计目的,以及现在市场的使用情况,浏览器支持情况等.... 设计目的 H ...
- 2023前端面试题总结(html,css,js)
目录 HTML篇 1.HTML5常用的语义化标签有哪些?并写出你对语义化的理解? 2.列举HTML的block元素和inline元素 3.块元素和行内元素的区别? 4. iframe 是什么?有什么缺 ...
- 十多款优秀的Vue组件库介绍
十多款优秀的Vue组件库介绍 1. iView UI组件库 iView 是一套基于 Vue.js 的开源 UI 组件库,主要服务于 PC 界面的中后台产品.iView的组件还是比较齐全的,更新也很快, ...
- .NET 中文件嵌套,例如:cshtml文件下面嵌套css和js【机器翻译】
越来越多的我发现自己在我的一些较大的Web项目中丢失了文件.有很多内容要处理 - HTML视图,几个派生CSS页面,页面级CSS,脚本库,应用程序范围的脚本和页面特定的脚本文件等等.幸运的是,我使用R ...
- 智慧家安监控系统——用Java + html、css、js实现
目录 系统背景 系统介绍 前端 SVG 监控情况 弹出窗口 图表 后端 表格处理 Servlet类 数据处理类 前后端的数据交互内容及设计 采用Servlet技术 采用Ajax技术 前后端数据交互操作 ...
最新文章
- Windows Server 2008 R2之三十二:证书注册WEB服务(一)
- 【练习】OC语法的简单复习
- 在servlet中设置的字符编码集为什么还会出现乱码(亲测)
- Idoc学习笔记----获取查询Idoc信息
- VTK:相互作用之Assembly
- 在GridView中使用Cache
- C语言中的EOF符号常量
- 快学好这个去给学妹修热水器
- 小艾k个人发卡网PHP源码
- CCF 201503-1 图像旋转
- android studio下生成aar文件,本地调用
- 使用jsoncpp解析生成json
- 黑客利用 Gatekeeper 0day 攻击 MacOS 计算机
- maxdea如何计算指数_10分钟计算出指数温度,开始基金定投之旅~
- 女生学Java软件开发好就业吗
- 汉诺塔的图解递归算法
- 广域网宽带接入技术八ADSL技术
- docker 定时重启脚本_定时启动docker容器
- python筛选出csv满足某条件的行_Python之根据条件筛选特定行
- 国内百兆独立服务器哪里的比较便宜镇江电信好吗