摘要:缺乏高级编程特性影响同样深远,社区发展的预处理器能够有效缓解,,,殊途同归,异军突起,基本实现变量嵌套变量混合扩展和逻辑等。
前言
关注点分离(separation of concerns)原则多年来大行其道,实践中一般将 HTML、CSS、JavaScript 分开编写维护,早期框架 angularjs 即是如此,直到 React 争议中问世,引领关注点混合趋势,驱使开发者重新审视 CSS 工程化发展。
尴尬的CSS相对于 JavaScript 的突飞猛进,CSS 的发展缓慢,相对止步不前。随着前端职能扩大化成为常态,前端工程化日趋成熟,CSS 先天缺陷愈发明显:
全局作用域
缺乏高级编程特性
代码冗余
极限压缩
依赖管理
最大的缺陷 来自于全局作用域,class name 全局生效,多人协作中的风格不一致,随时可能引发蝴蝶效应。为规避多人协作的风格冲突,社区提出 OOCSS,BEM 等方法论,但实践中完全取决于团队执行力度,笔者也曾苦恼于合理的命名,为避免冲突,导致类名冗长,无聊且痛苦。
缺乏高级编程特性 影响同样深远,社区发展的预处理器能够有效缓解,sass,less,stylus殊途同归,postcss 异军突起,基本实现变量、嵌套、变量、混合、扩展和逻辑等。随着 CSS 规范逐步推进,高级编程特性完全可期。笔者大胆断言,前端工程化的推进,已经基本解决 CSS高级编程特性缺乏 的问题。
代码冗余,极限压缩对开发的影响相对很小,经典的 bootstrap 就包含大量的冗余代码,但丝毫不影响其流行程度。
目前难以解决的是依赖管理,NPM 已经成为事实上的 JavaScript 包管理工具,而 CSS 始终没有发展出可用的管理模式,sass 的浅尝辄止,例如 bootstrap-sass, Bourbon等,显然无法满足需求。随着 React 引领的关注点混合,以组件为核心的开发模式,有效规避了 CSS 缺乏依赖管理的缺陷,笔者认为,依赖管理弊端完全可控,未来的发展,留给未来述说。
新锐的组件化前端发展日新月异,React 在众人争议中进入视野,典型的 React 组件同时包含结构、样式、行为,示例如下:
/** * @description - lite component * @author - huang.jian*/ export class Counter extends Component { constructor(props) { super(props); this.state = { timestamp: Date.now() }; } render() { return ( ); } }
前端应用由组件聚合而成,组件层面对 CSS 进行抽象,从而解决大型应用的 CSS 维护难题。社区出现的 CSS IN JS 解决方案,目前看来就是可行解决方案,其本质在于通过 JavaScript 来声明,维护样式,以 styled-components 举例:
const Button = styled.button` border-radius: 3px; padding: 0.25em 1em; color: palevioletred; border: 2px solid palevioletred; `; function Buttons() { return ( ); }
样式寄生组件之中,组件挂载时,动态插入样式,实现按需加载,动态生成类名,隔离作用域。另外一种思路,通过 style 属性传入内嵌样式,完全规避选择器全局作用域的问题。
// 官方示例有删减 var Radium = require("radium"); var React = require("react"); var color = require("color"); // You can create your style objects dynamically or share them for // every instance of the component. var styles = { base: { color: "#fff", }, primary: { background: "#0074D9" }, warning: { background: "#FF4136" } }; @Radium class Button extends React.Component { render() { return ( ); } }
面向组件开发,为样式管理提供更多的可能性,完全使用 JavaScript 抽象,管理,维护样式,略显激进,但也不失为一种解决方案。
客观的分析目前主流的 CSS IN JS 方案与传统的方式对比如下:
优势:
隔离作用域 -- 样式生效通过内嵌,或者生成独一无二的类名,避免出现选择器冲突;
高级编程特性 -- 充分利用 JavaScript 的能力增强对样式的控制;
样式按需挂载 -- 页面需要的样式才会加载,有效避免样式冗余;
依赖管理 -- 寄生于组件,利用现存的 NPM 生态进行包管理;
动态样式 -- 能够更加简单,直接的修改样式
劣势:
无法复用现有生态,特性完全依赖于库的实现;
编辑器代码补全,语法检查,语法高亮等需要插件支持;
伪类选择器(disabled、:before、:nth-child)支持诡异;
样式属性骆驼式命名;
独辟蹊径笔者并不完全认同 CSS IN JS 的理念,也不反对将其应用于生产项目。CSS 中最严重的问题,不通过 CSS-in-JS 也能
有其他解决方案,也就是笔者当前使用的 CSS Module 方案。通过工程化的方式,将选择器编译为独一无二的类名,使用 JavaScript 管理选择器与元素的关联,仅此而已。
// Header.jsx import style from "./Header.css" // { header: "Header__header--3kSIq_0" } export default function Header() { return (Header!!!); }
优势:
隔离作用域 -- 类名编译生成,有效避免选择器冲突;
样式按需加载 -- 利用 tree-shaking 机制,仅保留存在引用的选择器,有效避免样式冗余;
依赖管理 -- 关联组件,利用现存的 NPM 机制进行包管理;
充分利用现有生态 -- 编辑器高亮,自动补全,sass,postcss高级编程特性;
劣势:
欠缺动态样式特性 -- 无法充分利用 JavaScript 的能力增强对样式的控制;
主观的感悟本文未涉及的 单文件组件 也是可行方案之一,目前 Vue,Angular 等框架采用。笔者始终认为,与其创造更多抽象的技术让前端学习曲线更加陡峭,不如通过工程化的手段来修复存在的缺陷,理念上求同存异。面对各种技术方案,适合实际项目的方案才是最好的方案,选用预处理器 PostCSS,BEM,亦或动态编译,都需要结合业务场景、团队习惯等因素决策。
关注公众号,获取动态,支持作者。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/112891.html
摘要:前端杂谈权重权重想必大家都听说过一些简单的规则大部分人也都知道较长的权重会大于较短的权重高于但是具体规范是什么浏览器是按照什么标准来判定不同选择器的权重的呢让我们来看一下官方文档是怎么说的第一个关键词官方文档中用特异性来表示一个和其元素的相 前端杂谈: CSS 权重 (Specificity) css 权重想必大家都听说过, 一些简单的规则大部分人也都知道: 较长的 css sele...
摘要:引言作为服务器的优势就在于适合处理高并发的请求,对于网站后台这种密集型的后台尤其有优势,其核心就在于是一个异步非阻塞模型。关于异步,同步,阻塞,非阻塞这些概念,本文不做讨论。另外两个的调用时间需要判断是否都在主线程中被执行。 引言 node作为服务器的优势就在于适合处理高并发的请求,对于web网站后台这种I/O密集型的后台尤其有优势,其核心就在于node是一个异步非阻塞模型。关于异步,...
阅读 2904·2021-11-15 18:02
阅读 3798·2021-10-14 09:43
阅读 3731·2021-09-08 10:41
阅读 2518·2019-08-30 15:53
阅读 1801·2019-08-30 14:14
阅读 1942·2019-08-29 16:12
阅读 3137·2019-08-29 14:03
阅读 1278·2019-08-29 13:46