CSS in JS

在之前的网站有一个开发原则是‘关注点分离’,这个技术的意思是,各个技术都只是负责自己的领域,不会混合在一起,形成耦合,而对于前端的开发来说,就是JavaScriptHTMLCSS的解耦。

关注点分离

对于前端开发人员,这三个概念并不陌生,那我们最后澄清一下他们各自担任的角色。

  • HTML语言:负责网页的构建任务,又被称为语义层
    -CSS语言:负责网页的样式。又被称为视觉层
  • JavaScript语言:负责网页的逻辑与交互,又被称为逻辑层和交互层

也就是说不要写内部样式和行内脚本。
但是在React出现之后,这个原则就不再适用了,React是组件结构,强制的把JavaScriptHTMLCSS写在了一起。那我们下面看一下关于React的代码

const style = {
  'color': 'red',
  'fontSize': '46px'
};

const clickHandler = () => alert('hi'); 

ReactDOM.render(
  <h1 style={style} onclick={clickHandler}>
     Hello, world!
  </h1>,
  document.getElementById('example')
);

上面的一段代码包含了JavaScriptHTMLCSS的代码,一个文件中中封装了结构、样式、逻辑,完全违背了‘关注点分离’的原则。
但是这么写,有助于组件的隔离,每一个组件都包含了要用到的所有的代码,不用依赖于外部,组件和组件之间不存在耦合关系,很方便被复用,所以我们要是使用React的话,这样的写法会渐渐的称为主流的写法。

组件的封装

我们如果简单的从结构上面看,React写法好像是将JavaScriptHTMLCSS混合的写到了一起。但是实际上并不是这样的,其实实现的方式是用JavaScript来写HTML、CSS。ReactJavaScript里面实现了对HTMLCSS的封装,我们是通过封装来操作HTMLCSS,也就是网页的结构、样式、逻辑都是通过JavaScript来实现的。
其中reactHTML的封装是JSX语言,ReactJs基础语法有进行详细的讲述,那么我们看一下啊我们是怎么实现对CSS的封装的,对于React来说,对CSS的封装,就是沿用了DOMstyle的属性。

const style = {
  'color': 'red',
  'fontSize': '46px'
};

在上面的代码中CSSfont-size属性要写成fontsize,这是JavaScript操作CSS属性的约定,这个约定在链接里面可以详细看到。
由于CSS的封装非常弱,所以导致网上出现了一些列的第三方的库,用来加强ReactCSS的操作,这些第三方的库被统称为CSS in JS,表达的意思就是用JavaScript来写CSS。现在在网上流传的CSS in JS就有47种。
有很多人会问这些库和‘CSS预处理器’(sass,less)有什么区别呢?
答案:CSS in JS使用的是JavaScript的语法,是JavaScript脚本的一部分,不需要从头学习一套专有的API,不需要再进行一次编译步骤。
那我们现在看一个CSS in JS库,叫做 polished.js,这个库将一些常见的CSS属性封装成函数,用起来比较方便,充分的体现了JavaScript 语言写CSS 的优势。
首先先进行加载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"
//  }
// }

现在我们look几个简单实用的函数。
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)',
//  }

polished.js[用法](https://polished.js.org/docs/)主要提供的其他方法如下:

  • normalize():样式表初始化
  • placeholder():对 placeholder 伪元素设置样式
  • selection():对 selection 伪元素设置样式
  • darken():调节颜色深浅
  • lighten():调节颜色深浅
  • desaturate():降低颜色的饱和度
  • saturate():增加颜色的饱和度
  • opacify():调节透明度
  • complement():返回互补色
  • grayscale():将一个颜色转为灰度
  • rgb():指定红、绿、蓝三个值,返回一个颜色
  • rgba():指定红、绿、蓝和透明度四个值,返回一个颜色
  • hsl():指定色调、饱和度和亮度三个值,返回一个颜色
  • hsla():指定色调、饱和度、亮度和透明度三个值,返回一个颜色
  • mix():混合两种颜色
  • em():将像素转为 em
  • rem():将像素转为 rem

polished.js还有一个特色:所有函数默认都是柯里化的,因此可以进行函数组合运算,定制出自己想要的函数

import { compose } from 'ramda';
import { lighten, desaturate } from 'polished';

const tone = compose(lighten(10), desaturate(10))

参考:阮一峰-CSS in JS 简介

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容