最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 2021年的css周边:preprocessor、css-in-js等解决方案与methodology

    正文概述 掘金(卖油条的。)   2020-12-10   610

    本文包含以下子部分,因涉及内容较多,遂单开讲述,对应部分会再次提及相关链接

    • 2020年的css周边之sass使用指南
    • 2020年的css周边之styled-components原理及使用指南

    本文内容是,通过css开发过程中遇到的问题,引出以下解决方案,并对每种解决方案举例并详细解读:

    • preprocessor
    • post-css
    • css-in-js
    • css-module

    然后推荐几个编写css时的风格指南(style guides),以更好的组织代码:

    • BEM
    • OOCSS

    最后结合vue-cli和create-react-app,对其预设的css方案进行分析,推荐出我们在日常项目中可以采用的较好方案。

    正文开始了 ?


    css作为前端三件套之一,我们在实际的开发使用中会遇到一些问题:

    1. css简单的语法难以实现代码复用和复杂逻辑;
    2. 不同浏览器对新的css特性的实现不一;
    3. 缺少模块化,全局的选择器因其级联特性会造成样式映射不易维护。

    解决方案

    • 对第一个问题,可以用preprocessorpost-css等方式先用另一种语法编写再编译成原生css的方式解决,也可以用css-in-js直接用js控制样式的生成。
    • 为了兼容最新特性,我们可以使用post-csscss-in-js为样式自动添加浏览器前缀或添加polyfill。
    • 为css添加模块化特性,本质上是对不同模块的选择器添加独一无二的标记,可以使用css-modulecss-in-js自动为各种元素添加唯一的class name。

    解决方案

    preprocessor

    css预处理器是在css基础上扩展而来的各种新语言,为在css原有基础上添加了变量、嵌套、mixins和函数等功能,通过编译生成css。特定的预处理器比如sass,其之于css,就相当于ts)(想了解ts更多可以参考按照新的思路再学一遍typescript)之于js
    常见的css预处理器包括

    • sass官网
    • less官网
    • stylus官网

    三种预处理器的功能重复度很高,相关语法的区别(具体区别请参考再谈 CSS 预处理器),本质是一样的,学会了其中一种可以向其他预处理器无痛切换。

    关于sass的使用参考这篇文章 2020年的css周边之sass使用指南

    postcss

    postcss经常也被归为预处理器,但这里并不是。它和预处理器的本质区别是不会引入第三方类型的文件,输入css文件输出的依然是css文件。其之于css相当于babel(想了解babel更多可以参考babel是怎么解决我们问题的)之于js

    更准确得讲,postcss像babel中的@babel/core,接收一个css文件将其转化成抽象语法树,这时候可以引入一些插件做任何想做的事(比如验证语法或增加浏览器特定的前缀),再根据修改后的抽象语法树生成新的css。没有插件的postcss可以表示为

    const postcss = code => code
    

    插件

    要想实现postcss的价值最终要看使用的插件,可以在插件列表中挑选,同时也可以根据提供的api自定义插件,实现自己定制化的功能,更多细节请参考开发 PostCSS 插件。
    这里介绍几种比较常用的。

    • Autoprefixer 即使没用过postcss这个插件恐怕也听过,用来为相关属性添加不同浏览器推荐的前缀。比如
    //处理前
    ::placeholder {
      color: gray;
    }
    
    //处理后
    ::-moz-placeholder {
      color: gray;
    }
    :-ms-input-placeholder {
      color: gray;
    }
    ::placeholder {
      color: gray;
    }
    
    
    • cssnext和postcss-preset-env 前面提到babel的时候不知道大家有没有想到css中能不能将浏览器未实现的新版本写法转化为旧版本写法,没错,这里介绍的插件就是可以转换新语法和提供polyfill。这两个插件中后者替代了前者,前者已废弃。
    • precss 可以实现sass等预处理器的功能(语法和sass很像),并且依赖了postcss-preset-env,因此一定程度上可以替代预处理器。

    想了解postcss更多,可以参考PostCSS Deep Dive

    css-in-js

    说起css-in-js,有人可能会想到html-in-js,前端三大件此刻都归于js,即all-in-js。

    在js中写html就是我们经常用的jsx,jsx是ECMAScript的语法扩展,需要一个编译过程才能成为标准的ECMAScript语法,然后进一步生成dom。

    而css-in-js虽然也实现了在js中写其他语言的功能,但是它的思路只是一层包装,即在jsx的基础上(比如styled-component使用React.createElement方法)将接收到的元素或组件进一步添加常规属性和独特的className,并且生成对应的stylesheet,以达到模块化等效果。

    css-in-js的解决方案也有若干轮子可以开箱即用,比如

    • styled-components
    • styled-jsx
    • emotion

    还是和预处理器一样,这里以styled-components为例对其详细介绍,其他实现类似。

    关于styled-components的进一步讲解参考这篇文章 2020年的css周边之styled-components原理及使用指南

    和jsx一样,css-in-js主要和react一起使用。

    css-module

    产生背景

    css-in-js将部分或者所有样式代码放进了js,在实现了代码复用的同时,也造成了css和js的强耦合,有什么实现css模块化更好的办法呢?

    先看js是怎么解决模块化问题的,其中一个思路就是使用命名空间(可以参考ts中namespace的用法),即将一系列命名空间内部属性等挂载到同一个全局变量上,使项目方便维护也减少了命名冲突的概率。从各种第三方实现(比如AMD)发展到现在,js已经有了语言层面的模块化:esModule。

    css的模块化是要解决全局作用域下的选择器冲突问题,在有第三方实现之前,我们可以通过后面介绍的一系列命名规范(比如BEM)来保证选择器指代的唯一性,但随之带来的是因遵守严格的规范造成的开发成本的提升。
    直到在css社区有了自己的模块化规范:CSS Modules(css module的相关背景可以参考The End of Global CSS)。

    基本用法

    编写正常的css样式

    /* style.css */
    .className {
      color: green;
    }
    

    然后从js中将其导入

    import styles from "./style.css";
    // import { className } from "./style.css";
    
    element.innerHTML = '<div class="' + styles.className + '">';
    

    也可以通过composes复用其他样式声明或者使用:global:local切换作用域,具体用法参考官方文档和Interoperable CSS。

    原理

    css module处理下的css文件会被编译成一种标准的低级可交换格式文件:ICSS
    比如

    :export {
      className: _className_97fd867fsfg;
    }
    ._className_97fd867fsfg { 
     color: green;
    }
    

    该文件会被其他cssmodule文件或者js文件引入,其中本地的className被映射成全局的_className_97fd867fsfg,实现了模块化。另外导入等实现也类似,这里不赘述。

    实现情况

    webpack的css-loader和browserify的css-modulesify等对其进行了实现,通过相关配置可以实现相关特性。

    methodology

    css方法论指的是为了提高开发效率在组织代码时推荐遵守的一些规范,比如

    BEM

    BEM 是一种class命名规范,bem分别代表Blocks, Elements and Modifiers,class name命名规则为block--modifier-value

    • block代表一个独立的实体,可以理解为一个模块,比如header, container, menu, checkbox, input
    • Elements指的是块中的一部分,比如menu item, list item, checkbox caption, header title
    • Modifier指的是block或Elements的一种展示或行为,比如disabled, highlighted, checked, fixed, size big, color yellow

    OOCSS

    OOCSS,意为面向对象的css(Object Oriented CSS) ,一个css对象是指可重复使用的视觉模式,可以抽象为一块独立的代码块(特定结构的html元素和对应类名),会在整个网站重复使用。比如一个图片旁边有一些描述,其中包含固定(或可选的)的结构。

    <div class="media">//media是对象最外层class
    	<a href="http://twitter.com/stubbornella" class="img">
    		<img src="https://img.qiyuandi.com/images/5/2021nuyqycfkykrb.jpg"  />
    	</a>
    	<div class="bd">
    		<a href="http://twitter.com/stubbornella">@Stubbornella</a> <span class="detail">14 miniutes ago</span>
    	</div>
    </div>
    

    两个设计原则

    • Separate structure and skin 将重复的视觉定义成皮肤,结构要用通用的class name表示,而不是特定的某类元素,比如img,方便将结构对应部分替换。
    • Separate container and content 将容器和内容分开,即内容的一个部分无论放在哪里都是一样的,具体区别用class name来区分,比如不能给.myObject>h2设置样式,否则其他位置h2将有不同效果。

    其他

    其他常见的还有SMACSSMACSS、SUITCSS和Atomic等。

    总结

    就像在css module部分说的,这些规则会增大开发成本,在有众多更好用的解决方案的情况下,这些规则可以作用辅助手段为我们使用。

    最佳实践

    我们现在来到了最后一部分,看过了这么多理论,在项目中怎么使用呢?

    在回答这个问题之前,我们先看两个比较优秀的项目采用了哪些方案。

    vue-cli

    vue-cli是vue官方的脚手架

    • 使用使用了CSS Modules解决模块问题
    • 采用了PostCSS,并默认开启autoprefixer,添加css属性浏览器特定前缀
    • 可以在初始化项目时选用 Sass、Less、Stylus任何一种预处理器

    create-react-app

    create-react-app是react官方的脚手架

    • 使用使用了CSS Modules解决模块问题
    • react推荐不要跨组件复用class,这样会使预处理器用处不大,即可以用预处理器但不推荐
    • 使用PostCSS Normalize对浏览器默认样式进行重置,避免跨浏览器的差异
    • 采用了PostCSS,并默认开启autoprefixer,添加css属性浏览器特定前缀

    总结

    这里大概做一下推荐

    • 对于解决模块化问题使用CSS Modules
    • 兼容问题使用PostCSS
    • 代码复用和复杂逻辑选择一个喜欢的预处理器,比如sass

    具体怎么选择可以根据自身情况,并可以添加适当的约定。

    当我们对css相关方案有了全局的了解后,这应该已经不是问题了,对吧。?


    起源地下载网 » 2021年的css周边:preprocessor、css-in-js等解决方案与methodology

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元