记录--记一次前端CSS升级

news2024/11/30 5:02:03

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

目前平台前端使用的是原生CSS+BEM命名,在多人协作的模式下,容易出现样式冲突。为了减少这一类的问题,提升研效,我调研了业界上主流的7种CSS解决方案,并将最终升级方案落地到了工程中。

样式冲突的原因

目前遇到的样式冲突的原因,其实根本原因还是css样式混乱使用导致的:

  1. 多人协作,样式互相污染,这是项目中的主要问题。用开发规范来限定、用CR流程来保障,并不可靠
  2. 引用大量第三方组件库,组件库对CSS的使用不规范。比如bee.css中使用了大量!important,破坏了项目中的样式优先级;rsuit是前端非常强大的表格组件库,他的css文件中也有直接覆盖底层样式的写法label{ marign:2px }
  3. 直接使用组件库引入的css文件,比如import material-icons.css,如果引用顺序靠后,这些文件可能会覆盖开发人员手写的样式。
  4. ...

调研方案

CSS作为前端三剑客之一,几乎是所有前端同学最先学习的样式表语言。在生产环境的项目工程中,很少见到直接原生使用CSS的。但目前业界还没有通用的CSS工程化方案。这篇文章先简单介绍下7种在React/Next.js中较为流行使用CSS的方式,并说说他们的优缺点。

原生 CSS

这是一种用选择器来划分css作用域的方式。

  • 缺点:
  1. 作用域问题 CSS样式之间会层叠覆盖,需要用大量的classname来指定选择器,来限定CSS的作用域范围。频繁的命名给开发人员增加不少心智负担,而且容易搞错搞重复。
// pure css example
.card {
	/* styles */
}
.card__header {
	/* styles */
}
.card--focus {
	/* styles */
}

采用BEM规则来进行命名或许会简单些。 但在需要维护特别多样式的时候,BEM还是不够用。尤其是当代码中开始大量出现!important这种破坏优先级的东西的时候。

// css with !important
.card {
	color: blue !important;
}
.card {
	color: red;
}
  1. 打包体积大 使用大量冗长的原生CSS,可能会导致 打出来的包变大。包越大,项目自然跑的就越慢。

CSS MODULES

这是一种在原生CSS的基础上,通过modules(也可以理解为文件)来划分CSS的作用域。

首先先建一些以.module.css结尾的文件,这些文件里的样式可以只针对某个组件(某个module)生效。这种做法在Next.js尤为常见,因为CSS modules在Next.js是可以开箱即用的。

下面是一个例子,在Home.module.cssother.module.css同样的类名书写样式,也不会产生冲突。

@file Home.module.css
.page {
	color: bule;
}
@file other.module.css
.page {
	color: yellow;
}
// 只会生效这里import的样式
import styles from '../styles/Home.module.css';
export default function Home(){
	return (
		// 蓝色
		<div className={styles.page}>
			<h1> Home Page </h1>
		<div>
	)
}
  • 优势:
  1. 当需要复用样式的时候,不同的组件可以import同一份样式文件,减少很多重复样式代码,减轻打包体积~
  2. 说到样式复用,CSS modules还有个特殊的composes属性,能引入别的module的css样式,也能重写(override)。
.page {
	composes: className from "./shared.css"
}
  • 缺点:
  1. 不够“程序化” CSS modules在原生CSS的基础上增加了以modules(文件)划分的作用域,解决了作用域问题,但仍逃不过在单个module内以原生的方式书写CSS。原生的CSS只能纯纯的枚举出每一条样式,如果能在书写CSS的时候也支持一些程序特性岂不是更好?比如最常用的循环、遍历、函数、继承...

CSS PREPROCESSOR 预处理器

Sass、Less、Stylus... 这些预处理器就是为了解决CSS不够“程序化”而诞生的。他们允许你用一种不一样的语法来写CSS,之后再经过编译转化成原生CSS。

这里是一个例子:

// 只需一键安装sass
$ npm install sass
// 然后把原本的css后缀文件改成scss
// 就可以直接使用sass的方式来编写css啦,比如变量名、循环、... @ file Home.module.scss $ primary-color: red; $ font-stack:Helvetica body { font: 100% $font-stack; color: $primary-color; }
  • 优势:
  1. 可以用变量、继承、循环、函数、...等程序特性
  • 缺点:
  1. 学习成本 每种预处理器都有各自特定的语法,虽然是用一种类CSS的语言来编写,但总有有些差异。这意味着开发人员必须配合工具掌握新的语法。
  2. 样式和项目代码微微割裂 在解决完作用域、程序化问题后,样式在前端项目中完完全全的独立出来了,似乎少了一些联动能力。既然我们有JSX这样整合JS和HTML的合体语言,为什么不能把CSS也合体进来呢?

CSS IN JS

这是一种把CSS写进JS的解决方案,就像把HTML写进JS后就有了JSX。这一类的库有styled components、emotion、jss、style tron、...

举个使用styled jsx的例子:

import styles from '../styles/Home.module.css';

export default function Home(){
	const [color, serColor] = useState('orange');
	return (
		<div className={styles.page}>
			<style jsx>{`
				h1 {
					// 取的是组件state,可以随state变化!
					color: ${color};
				}
			`}</style>
			<h1> Home Page </h1>
		<div>
	)
}
  • 优势:
  1. 轻松能实现的程序化能力 在sass里的程序化能力,CSS in JS都能做到,甚至更强,这种方式可以直接使用JS书写这种程序化语言,也不需要额外学习成本。
  2. 创建动态样式 在sass里,程序代码或许和样式文件是完全独立开来的。而使用CSS in JS,样式和JS强绑定,我们的样式能够跟着代码、跟着组件的state等特性实现动态样式,特别灵活!
  3. 不会有作用域问题 类似module,CSS in JS的样式只会绑定在样式定义的组件内,不会污染全局样式~
  • 缺点:
  1. CSS和JS混写,代码管理困难。

UTILITY CLASSES 原子类

时下最火的新概念就是tailwindcss、windi css这些原子类CSS库,能够提供大量的原子类样式,帮助我们快速构建样式。

// 配置好tailwind之后
export default function Home(){
	return (
		// 在这里写上tailwind的原子类classname,而不需要写样式
		<div className="text-5xl font-bold">
		<h1> Home Page </h1>
		<div>
	)
}
  • 缺点
  1. 需要比较麻烦的额外配置
  2. 打包后,生成的HTML文件可读性非常非常低
  3. image.png
  4. 没有任何的内置组件
  • 优势
  1. 打包时,能自动优化,去除没有使用的css样式,减轻打包产物体积。

CSS FRAMEWORK

bootstrap、bulma、这一类库既能提供特定的样式主题,又有内置的组件,比如bottom、cards、...等等。我个人在自己倒腾东西的时候非常喜欢用这一类框架,因为实在是太方便啦!这种方式在生产上几乎很少采用,因为开发人员往往需要根据产品原型来绘制前端界面,而不是这些框架固定的样式。另外采用这种方式,也容易对线上性能造成比较大影响。

// 想使用这一类框架,只用一键安装上
$ npm install bootstrap

// 引入框架的样式文件
import 'bootstrap/dist/css/bootstrap.css'

export default function Home(){
	return (
		// 想要使用的样式都在bootstrap中用各种classname封装好啦,直接调用boostrap的预留classname,搞定
		<div className="alert alert-primary">
		<h1> Home Page </h1>
		<div>
	)
}
  • 缺点:
  1. 在只使用bootstrap来搭建组件和修改样式的话,会不太方便 由于这类框架已经自带了许多预留组件,而bootstrap的样式又是用classname来获取的。假设我需要频繁使用<Bottom />组件,却又不想在每次使用的时候,都重复的写相同的classname,那么就会将他们封装成<CustomButtom />。这么做的话,项目代码中就可能会有大量的仅仅是为了封装classname而存在的组件。
  2. 打包文件过大 整个bootstrap文件是直接import进来的。因此在打包时,会把大量没使用到的classname也打包进来,会造成打包产物较大~

组件库

这是大家最熟悉的方式啦,ant design、material design、t design、rebase、....

最终落地的升级方案

不同的CSS处理方式各有优劣,在实际开发中,可以自行选择和搭配合适的CSS处理手段。

在我目前工作中,是将项目的原生CSS,升级成css module + less 的组合,这样既能解决当前项目的核心矛盾:作用域和样式污染问题,又能让CSS的编写过程变得更“程序”,比如使用变量、继承等特性。

没有使用css in js 是因为当前项目没有主题切换和动态样式这样场景,此外css in js 会让一个组件文件变得非常冗长,尤其是目前我的工作特别多复杂图表的封装,仅jsx部分代码行数已经非常长,再引入CSS代码容易变得更混乱。我个人也更加偏向能用独立文件区分出CSS代码的方式,这样展示出更好的项目分层。

没有使用原子类的理由就更简单了,配置麻烦,可读性低,而且对团队内每个人都有较高的学习成本,不方便团队管理,直接pass了。

在前端工程开发的过程中,面对多人协作的场景,建立标准和团队内的规范是非常重要的一个环节。尤其当前业界的前端,就是没有通用标准的情况下,影响项目工程稳健性的往往是缺乏规范和标准,而不是开发人员的水平。在我工作的项目中,最初就是因为大量人员流动,大家在项目中各按各自的方式写CSS,导致在一个项目中存在3种以上CSS写法,非常难维护,也出现了样式互相污染、互相冲突的情况,所以才有了这次对CSS的调研,以及对项目进行升级和改造的工作。

本文转载于:

https://juejin.cn/post/7171413795938500639

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/84931.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java基于springboot+vue 的传统乐器培训管理系统 elementUI

此网站系统的开发方式和信息管理方式&#xff0c;借鉴前人设计的信息和研发。以在线乐器培训管理为主&#xff0c;以乐器培训管理为核心功能来进行设计和研发&#xff0c;把网站信息和技术整合&#xff0c;开发出一套网上乐器培训管理系统。主要运用现在社会公司中最新的技术框…

rocketmq源码学习-nameServer

前言 最近看了下rocketmq的源码&#xff0c;计划针对最近的学习&#xff0c;做一个笔记&#xff0c;先从nameServer启动的逻辑开始记录吧 在rocketmq中&#xff0c;有四个关键的组件 nameServerbrokerproducerconsumer 这四个组件之间的关系是这样的 关于nameSrv namese…

[附源码]Python计算机毕业设计钓鱼爱好者交流平台Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

老照片修复清晰?父母以前的老照片还能修复吗?

父母结婚时拍摄的结婚照片&#xff0c;现在大概快四十年了&#xff0c;因为保存不善&#xff0c;导致照片泛黄&#xff0c;严重模糊。因为这是父母年轻的时候唯一保留下来的&#xff0c;对我们来说意义重大&#xff0c;所以想要修复照片可以实现吗&#xff1f; 有些照相馆是提…

论文投稿指南——中国(中文EI)期刊推荐(第6期)

&#x1f680; EI是国际知名三大检索系统之一&#xff0c;在学术界的知名度和认可度仅次于SCI&#xff01;&#x1f384;&#x1f388; 【前言】 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊。其中&#xf…

ADI Blackfin DSP处理器-BF533的开发详解51:Bin_Conver (图像二值变换处理)(含源码)

硬件准备 ADSP-EDU-BF533&#xff1a;BF533开发板 AD-HP530ICE&#xff1a;ADI DSP仿真器 软件准备 Visual DSP软件 硬件链接 功能介绍 代码实现了图像二值变换处理&#xff0c;代码运行时&#xff0c;会通过文件系统打开工程文件根目下" …/ImageView"路径中的…

阿里云DataWorks荣获DAMA中国数据治理优秀产品奖

DAMA&#xff08;国际数据管理协会&#xff09;是一个全球性的专业组织&#xff0c;协会自1980年成立以来&#xff0c;一直致力于数据管理和数字化的研究、实践及相关知识体系的建设&#xff0c;先后发行了《DAMA 数据管理字典》和《DAMA数据管理的知识体系》等&#xff0c;该知…

C/C++程序的断点调试 - Visual Studio Code

本文以Visual Studio Code为例&#xff0c;简述C/C程序断点调试的基本方法和过程。其它的IDE环境&#xff0c;大同小异。 本文引用自作者编写的下述图书; 本文允许以个人学习、教学等目的引用、讲授或转载&#xff0c;但需要注明原作者"海洋饼干叔 叔"&#xff1b;本…

视频特效如何制作?快把这些方法收好

小伙伴们平时刷短视频的时候&#xff0c;有没有发现一些短视频的效果很惊艳。这些惊艳的效果&#xff0c;大部分都是在视频中添加的一些动画特效。那你们知道手机视频怎么添加特效吗&#xff1f;为了帮助大家解决这个问题&#xff0c;接下来我就将为大家分享几种添加特效的方法…

架构高可用之限流-抽刀断水水更流

上图中是一个水坝泄洪的图&#xff0c;那么&#xff0c;对于软件系统&#xff0c;如何使用最方便的可编程的方式增加服务限流能力呢&#xff1f; 下面我结合一个常规的springCloud项目实践了一把&#xff0c;希望他山之石可以攻玉。 背景 简单使用jmeter&#xff0c;压20个并…

FL Studio21.0.0完整版最高版本升级功能有哪些?

支持苹果 Silicon 芯片 – 对苹果 Silicon 芯片&#xff08;M1 芯片以及相关 CPU&#xff09;的原生 ARM 代码支持&#xff0c;但请注意&#xff1a; NewTime、NewTone 和一些 DirectWave 采样格式的导入功能尚未完全重构可能会有问题。 FL Studio-win21中文更新下载如下: htt…

新通药物被暂缓审议:科创属性遭质疑,招股书“数据打架”

12月12日&#xff0c;上海证券交易所披露的信息显示&#xff0c;西安新通药物研究股份有限公司&#xff08;下称“新通药物”&#xff09;的首发申请被暂缓审议。据贝多财经了解&#xff0c;新通药物于2021年12月6日在科创板递交招股书&#xff0c;计划募资12.79亿元。 科创板上…

识破贷后资金归集——关联网络

近几年&#xff0c;金融机构为了扩大信贷规模&#xff0c;抢占市场份额&#xff0c;通过贷款将贷款发放给无法直接通过金融机构获得贷款的个人或者企业&#xff0c;但这也给金融机构带来了多重风险。 首先&#xff0c;我们来看下资金归集是什么。所谓资金归集&#xff0c;是银…

GCSE英语语言考试-语言和结构

Language语言 Example of a simile from The Hunger Games, Suzanne Collins 《饥饿游戏》中的比喻例子&#xff0c;苏珊娜-柯林斯的作品 When talking about language in prose fiction, there are a number of things you could look for: 在谈论散文小说的语言时&#xff0c…

如何在XMLMap端口修改字段映射?

在使用知行EDI系统的过程中&#xff0c;我们经常会用到XMLMap端口进行数据转化&#xff0c;XMLMap端口可以通过拖拽方式进行字段取值映射&#xff0c;同时也可以写代码添加字段对应的取值及判断条件。有时在完成映射后&#xff0c;发现源文件/目标文件待映射的字段和段落需要添…

安卓玩机搞机技巧综合资源-----闲置手机当摄像头 当监控 上网课必备 多软件评测【十四】

接上篇 安卓玩机搞机技巧综合资源------如何提取手机分区 小米机型代码分享等等 【一】 安卓玩机搞机技巧综合资源------开机英文提示解决dm-verity corruption your device is corrupt. 设备内部报错 AB分区等等【二】 安卓玩机搞机技巧综合资源------EROFS分区格式 小米红…

为什么不能使用bigdecimal的equals比较大小

BigDecimal&#xff0c;相信对于很多人来说都不陌生&#xff0c;很多人都知道他的用法&#xff0c;这是一种 java.math 包中提供的一种可以用来进行精确运算的类型。 很多人都知道&#xff0c;在进行金额表示、金额计算等场景&#xff0c;不能使用 double、float 等类型&#…

一键登陆了解一下

我们先来看一下目前的一些登录方式&#xff1a; 账号、密码登陆 使用账号加密码是最传统的登录方式&#xff0c;可以说是简单粗暴的&#xff0c;一般也不会出现什么问题。 缺点 但这种方式要求用户要记住自己的账号和密码&#xff0c;也就是有一个记忆成本。用户为了降低记忆…

【Tryhackme】KoTH Food CTF(前端验证绕过,图片隐写,SUID提权:vim.basic)

免责声明 本文渗透的主机经过合法授权。本文使用的工具和方法仅限学习交流使用&#xff0c;请不要将文中使用的工具和渗透思路用于任何非法用途&#xff0c;对此产生的一切后果&#xff0c;本人不承担任何责任&#xff0c;也不对造成的任何误用或损害负责。 服务发现 ┌──(r…

学习管理系统五大好处

正如我们先前提到过的&#xff0c;对于公司来说&#xff0c;建立“学习型文化”可以带来许许多多的好处。然而&#xff0c;企业规模会越来越大&#xff0c;员工的培训学习需求并不会减少&#xff0c;这也会为企业的员工培训带来压力。学习管理系统&#xff08;LMS&#xff09;可…