CSS in JS 简介
1、
以前,网页开发有一个原则,叫做"关注点分离"(separation of concerns)。
它的意思是,各种技术只负责自己的领域,不要混合在一起,形成耦合。对于网页开发来说,主要是三种技术分离。
- HTML 语言:负责网页的结构,又称语义层
- CSS 语言:负责网页的样式,又称视觉层
- JavaScript 语言:负责网页的逻辑和交互,又称逻辑层或交互层
简单说,就是一句话,不要写"行内样式"(inline style)和"行内脚本"(inline script)。比如,下面代码就很糟糕(查看完整代码)。
<h1 style="color:red;font-size:46px;" onclick="alert('Hi')"> Hello World </h1>
2、
React 出现以后,这个原则不再适用了。因为,React 是组件结构,强制要求把 HTML、CSS、JavaScript 写在一起。
上面的例子使用 React 改写如下(查看完整代码)。
const style = { 'color': 'red', 'fontSize': '46px' }; const clickHandler = () => alert('hi'); ReactDOM.render( <h1 style={style} onclick={clickHandler}> Hello, world! </h1>, document.getElementById('example') );
上面代码在一个文件里面,封装了结构、样式和逻辑,完全违背了"关注点分离"的原则,很多人不适应。
但是,这有利于组件的隔离。每个组件包含了所有需要用到的代码,不依赖外部,组件之间没有耦合,很方便复用。所以,随着 React 的走红和组件模式深入人心,这种"关注点混合"的新写法逐渐成为主流。
3、
表面上,React 的写法是 HTML、CSS、JavaScript 混合在一起。但是,实际上不是。现在其实是用 JavaScript 在写 HTML 和 CSS。
React 在 JavaScript 里面实现了对 HTML 和 CSS 的封装,我们通过封装去操作 HTML 和 CSS。也就是说,网页的结构和样式都通过 JavaScript 操作。
4、
React 对 HTML 的封装是 JSX 语言 ,这个在各种 React 教程都有详细介绍,本文不再涉及了,下面来看 React 对 CSS 的封装。
React 对 CSS 封装非常简单,就是沿用了 DOM 的 style 属性对象,这个在前面已经看到过了。
const style = { 'color': 'red', 'fontSize': '46px' };
上面代码中,CSS 的font-size
属性要写成fontSize
,这是 JavaScript 操作 CSS 属性的约定。
由于 CSS 的封装非常弱,导致了一系列的第三方库,用来加强 React 的 CSS 操作。它们统称为 CSS in JS,意思就是使用 JS 语言写 CSS。根据不完全统计,各种 CSS in JS 的库至少有47种。老实说,现在也看不出来,哪一个库会变成主流。
你可能会问,它们与"CSS 预处理器"(比如 Less 和 Sass,包括 PostCSS)有什么区别?回答是 CSS in JS 使用 JavaScript 的语法,是 JavaScript 脚本的一部分,不用从头学习一套专用的 API,也不会多一道编译步骤。
5、
上周,我看到一个新的 CSS in JS 库,叫做 polished.js。它将一些常用的 CSS 属性封装成函数,用起来非常方便,充分体现使用 JavaScript 语言写 CSS 的优势。
我觉得这个库很值得推荐,这篇文章的主要目的,就是想从这个库来看怎么使用 CSS in JS。
首先,加载 polished.js。
const polished = require('polished');
如果是浏览器,插入下面的脚本。
<script src="https://unpkg.com/polished@1.0.0/dist/polished.min.js"> </script>
polished.js
目前有50多个方法,比如clearfix
方法用来清理浮动。
const styles = { ...polished.clearFix(), };
上面代码中,clearFix
就是一个普通的 JavaScript 函数,返回一个对象。
polished.clearFix() // { // &::after: { // clear: "both", // content: "", // display: "table" // } // }
"展开运算符"(...
)将clearFix
返回的对象展开,便于与其他 CSS 属性混合。然后,将样式对象赋给 React 组件的style
属性,这个组件就能清理浮动了。
ReactDOM.render( <h1 style={style}>Hello, React!</h1>, document.getElementById('example') );
从这个例子,大家应该能够体会polished.js
的用法。
6、
下面再看几个很有用的函数。
ellipsis
将超过指定长度的文本,使用省略号替代(查看完整代码)。
const styles = { ...polished.ellipsis('200px') } // 返回值 // { // 'display': 'inline-block', // 'max-width': '250px', // 'overflow': 'hidden', // 'text-overflow': 'ellipsis', // 'white-space': 'nowrap', // 'word-wrap': 'normal' // }
hideText
用于隐藏文本,显示图片。
const styles = { 'background-image': 'url(logo.png)', ...polished.hideText(), }; // 返回值 // { 'background-image': 'url(logo.png)', 'text-indent': '101%', 'overflow': 'hidden', 'white-space': 'nowrap', }
hiDPI
指定高分屏样式。
const styles = { [polished.hiDPI(1.5)]: { width: '200px', } }; // 返回值 //'@media only screen and (-webkit-min-device-pixel-ratio: 1.5), // only screen and (min--moz-device-pixel-ratio: 1.5), // only screen and (-o-min-device-pixel-ratio: 1.5/1), // only screen and (min-resolution: 144dpi), // only screen and (min-resolution: 1.5dppx)': { // 'width': '200px', //}
retinaImage
为高分屏和低分屏设置不同的背景图。
const styles = { ...polished.retinaImage('my-img') }; // 返回值 // backgroundImage: 'url(my-img.png)', // '@media only screen and (-webkit-min-device-pixel-ratio: 1.3), // only screen and (min--moz-device-pixel-ratio: 1.3), // only screen and (-o-min-device-pixel-ratio: 1.3/1), // only screen and (min-resolution: 144dpi), // only screen and (min-resolution: 1.5dppx)': { // backgroundImage: 'url(my-img_2x.png)', // }
7、
polished.js
提供的其他方法如下,详细用法请参考文档。
-
normalize()
:样式表初始化 -
placeholder()
:对 placeholder 伪元素设置样式 -
selection()
:对 selection 伪元素设置样式 -
darken()
:调节颜色深浅 -
lighten()
:调节颜色深浅 -
desaturate()
:降低颜色的饱和度 -
saturate()
:增加颜色的饱和度 -
opacify()
:调节透明度 -
complement()
:返回互补色 -
grayscale()
:将一个颜色转为灰度 -
rgb()
:指定红、绿、蓝三个值,返回一个颜色 -
rgba()
:指定红、绿、蓝和透明度四个值,返回一个颜色 -
hsl()
:指定色调、饱和度和亮度三个值,返回一个颜色 -
hsla()
:指定色调、饱和度、亮度和透明度三个值,返回一个颜色 -
mix()
:混合两种颜色 -
em()
:将像素转为 em -
rem()
:将像素转为 rem
目前,polished.js
只是1.0版,以后应该会有越来越多的方法。
8、
polished.js
还有一个特色:所有函数默认都是柯里化的,因此可以进行函数组合运算,定制出自己想要的函数。
import { compose } from 'ramda'; import { lighten, desaturate } from 'polished'; const tone = compose(lighten(10), desaturate(10))
上面代码使用 Ramda 函数库完成组合运算。Ramda 的用法可以参考我写的教程。
(正文完)
==========
- .Net 转战 Android 4.4 日常笔记(9)--常用组件的使用方法[附源码]
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(38)-Easyui-accordion+tree漂亮的菜单导航
- .Net 转战 Android 4.4 日常笔记(8)--常见事件响应及实现方式
- silverlight于javascript通信
- 微信上线小游戏:对流量基础入口应用商店革命
- Appium Desktop 使用
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(36)-文章发布系统③-kindeditor使用
- Windows Server 2008 R2 下配置证书服务器和HTTPS方式访问网站
- .Net 转战 Android 4.4 日常笔记(7)--apk的打包与反编译
- 丰富的silverlight控件
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(35)-文章发布系统②-构建项目
- .Net 转战 Android 4.4 日常笔记(6)--Android Studio DDMS用法
- 机器学习加密货币IOTA在机构支持下跃起
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(34)-文章发布系统①-简要分析
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Centos环境下安装Zend optimizer 3.3.9的方法
- Linux curl表单登录或提交与cookie使用详解
- Linux磁盘设备与LVM管理命令示例详解
- Ubuntu基础教程之apt-get命令
- Ubuntu18.04.2下安装 RTX2080 Nvidia显卡驱动的方法
- linux进程监控与自动重启的简单实现方法
- Linux 解决Deepin无法在root用户启动Google Chrome浏览器的问题
- 在Linux上安装和使用Docker的方法
- centOS7 NET模式设置静态Ip的方法步骤
- CentOS搭建PHP服务器环境简明教程
- CentOS7.2安装MySql5.7并开启远程连接授权的教程
- linux查看防火墙状态与开启关闭命令详解
- linux防火墙iptables规则的查看、添加、删除和修改方法总结
- Linux expect实现自动登录脚本实例代码
- scRNA-seq marker identification(一)