一种写css的新思路 —— ICSS

1,478 阅读6分钟

现象:

不知道大家有没有一种感觉,有时候开发一个前端页面,看起来很简单,但是需要花费我们很久的时间才能做完。

原因

被打断是阻碍效率提高的主要原因。

问题分析:

Vue 官网的链接:v3.cn.vuejs.org/guide/singl…

下列信息是vue官网的原话:

关注点分离怎么样? 一些来自传统 Web 开发背景的用户可能会担心 SFC 在同一个地方混合了不同的关注点——HTML/CSS/JS 应该分开! 要回答这个问题,我们必须同意关注点分离不等于文件类型分离。工程原理的最终目标是提高代码库的可维护性。关注点分离,当墨守成规地应用为文件类型的分离时,并不能帮助我们在日益复杂的前端应用程序的上下文中实现该目标。 在现代 UI 开发中,我们发现与其将代码库划分为三个相互交织的巨大层,不如将它们划分为松散耦合的组件并进行组合更有意义。在组件内部,它的模板、逻辑和样式是内在耦合的,将它们搭配起来实际上可以使组件更具凝聚力和可维护性。 注意,即使不喜欢单文件组件的想法,仍然可以通过使用 src导入 将 JavaScript 与 CSS 分离到单独的文件中来利用其热重载和预编译功能。

这里提到了:应该讲模版,逻辑和样式进行耦合,不应该分离。

vue3 composition api 提出新概念

链接1:24kcs.github.io/vue3_study/… 链接2:morioh.com/p/2feca181b…

Option API的问题

在传统的Vue OptionsAPI中,新增或者修改一个需求,就需要分别在data,methods,computed里修改 ,滚动条反复上下移动

image.png

下面这张图可能更清楚些: image.png

总结: 从上面的信息分析,不管是从开发效率,和代码的工整性来说,CompositonAPI 的优点,远远好于OptionsAPI;

vue3 官网还提出了人体工程学的概念

image.png

结论分析

vue3 也在从代码层面提高每位开发者的开发感受,和开发效率。其本质致力于解决被自己打断的而降低效率的问题——进过深入分析,被自己打断主要原因是因为逻辑不连贯,需要分别在data,methods,computed里修改 ,滚动条反复上下移动,或者不停的切换文件。

如何继续提升开发效率

除了开源社区提供给我们的帮助,我们还能怎么提高开发下来呢?

提升效率的新方法:

html 和 css 耦合。

问题分析

实现下图的页面效果: image.png

实现方案一:采用BEM规范

BEM

最流行的命名规则之一就是BEM(block:块,Element:元素,Modifier:修饰符)。通过给每个元素添加它的父级block模块作为前缀,使得目标的安全性变得更加简单了。BEM还有助于消除页面和body类对嵌套或者附加样式依赖。 规则:下划线(__)被用来区分元素,而用连字符(--)是用来修饰元素的。下面是一个现实世界的例子...

<template>
	<div class="list">
		<div class="item">
			<img src="" alt="" class="item-img" />
			<div><span class="item-brand">三星</span><span class="item-name">p600</span></div>
			<div class="item-price">
				<span class="item-price__text">价格:</span><span class="item-price__value">¥600</span>
			</div>
		</div>
	</div>
</template>

<style lang="less" scoped>
	.item {
		.item-img {
		}
		.item-name {
		}
		.item-price {
			.item-price__text {
			}
			.item-price__value {
			}
		}
	}
</style>

这种方式虽然很友好的定义了class使用的规则,但是还是写代码的时候容易产生逻辑上的割裂。

实现方案二:采用ACSS规范

ACSS

考虑如何设计一个系统的接口。原子(Atoms)是创建一个区块的最基本的特质,比如说表单按钮。分子(Molecules)是很多个原子(Atoms)的组合,比如说一个表单中包括了一个标签,输入框和按钮。生物(Organisms)是众多分子(Molecules)的组合物,比如一个网站的顶部区域,他包括了网站的标题、导航等。而模板(Templates)又是众多生物(Organisms)的结合体。比如一个网站页面的布局。而最后的页面就是特殊的模板。 image.png

举例说明:

<!-- HTML --> 
<fieldset> 
  <label for="field" class="arial-font-family larger-font-size text-color mbm">
    Form Label
  </label>
</fieldset>

/*CSS*/ 
<style>
.label-font-family { font-family: arial; } 
.larger-font-size { font-size: 150%; } 
.text-color { color: #313131; } 
.mbm, .mvm, .mam { margin-bottom: 10px !important; }
</style>

// 恶心
<span class="display-block blue-box font-arial padding-20">Party like it’s 1999!</span> 
<span class="display-block blue-box font-arial padding-20">Hey, havelately?</span> 
<span class="display-block blue-box font-arial padding-20">Wassuuuuuuup!</span>

优点:

  • 代码复用率极高,几乎达到100%,不会写多的css
  • 见名知意。class 名,就知道里面的css 是什么了。

缺点:

  • 定义原子结构复杂,想把所有的原子结构定义好,并且可以不复用,是一件很难的事情。但是有一个css库给我们做好了。
  • 由于class 是由于css拼装而成,你会发现css 写的又臭又长。但是真的有被在使用:Twitter Bootstrap按钮生成器

使用ACSS最大的问题在于现实的开发过程中,有些属性是无法原子化的,如字体颜色,字体大小,背景颜色等,所以还需要写css,无法达到真正的原子化。

问题

那么有什么方法可以减少写html,css的割裂的问题呢?

方式三: ICSS

根据上述情况,我自己想到了第三种书写方式,可以先看下案例(还是以上面的案例为demo)

<template>
	<div class="list">
		<div class="item">
			<img src="" alt="" class="auto" style="width: 300px; height: 150px" />
			<div><span class="bold">三星</span><span>p600</span></div>
			<div class="flex" style="font-size: 12px">
				<span style="color: #999">价格:</span><span style="color: red">¥600</span>
			</div>
		</div>
	</div>
</template>

<style lang="less" scoped>
	//@import url(); 引入公共css类
	.auto {
		margin: 0 auto;
	}
	.bold {
		font-weight: bolder;
	}
	.flex {
		display: flex;
	}
	.relative {
		position: relative;
	}
</style>

我们可以把css分成两类,一部分是可以被穷举出来的,一部分是无法被穷举出来的。我们把可穷举的css可以预先定义出来,不可穷举的,采用行内样式书写。

由于主要使用了ACSS的模式 + 行内样式 inline ; 所以我把他命名为:IASS;

优缺点:

优点:

  1. 可以减少css冗余,减少css 体积。
  2. 在写复杂页面时,减少滚动条反复滚动,提高开发效率。
  3. 不用在为取class名称而头疼。
  4. 由于不用取class名字,更利于在lowcode和设计图转代码的工具中使用。
  5. 代码的可读性感觉更高些。

缺点:

  1. 改变了原有写代码的认知。
  2. 需要预先记忆住一些原子CSS,增加了记忆成本。
  3. 改变原有的写代码习惯,会有些不适应。

总结: 这是我的前端代码的思路,并且在工作中使用,在养成这种习惯后,会发现写代码效率得到了提高,而求由于没有css的打断,写代码的感觉更好。

我预定好的 css 原子

.w_100{
  width: 100%;
}

.h_100 {
	height: 100%;
}
.border-box {
	box-sizing: border-box
}
.auto{
  margin:0 auto;
}
.ellipsis{
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.bold {
	font-weight: bold;
	font-weight: bolder
}
.center {
	text-align: center
}

.right-align {
	text-align: right
}

.justify {
	text-align: justify
}

.overflow-hidden {
	overflow: hidden
}

.overflow-scroll {
	overflow: scroll
}
.inline {
	display: inline
}

.block {
	display: block
}

.inline-block {
	display: inline-block
}
.flex {
	display: flex
}
.flex-wrap {
	flex-wrap: wrap
}

.items-start {
	align-items: flex-start
}

.items-end {
	align-items: flex-end
}

.items-center {
	align-items: center
}

.items-baseline {
	align-items: baseline
}

.items-stretch {
	align-items: stretch
}

.justify-start {
	justify-content: flex-start
}

.justify-end {
	justify-content: flex-end
}

.justify-center {
	justify-content: center
}

.justify-between {
	justify-content: space-between
}

.justify-around {
	justify-content: space-around
}
.relative {
	position: relative
}

.absolute {
	position: absolute
}

.fixed {
	position: fixed
}
.z1 {
	z-index: 1
}

.z2 {
	z-index: 2
}

.z3 {
	z-index: 3
}

.z4 {
	z-index: 4
}
.circle {
	border-radius: 50%
}

.border1 {
	border-style: solid;
	border-width: 1px;
}

.border2 {
	border-style: solid;
	border-width: 2px;
}
.border3 {
	border-style: solid;
	border-width: 3px;
}
.border4 {
	border-style: solid;
	border-width: 4px;
}