前端工程化之CSS

在构建一个工程化的项目时,我们会针对样式选择使用CSS预处理器,下面来详细聊聊关于css预处理器。

什么是CSS预处理器

css预处理器究竟是什么呢。css预处理器定义了一种新的语言,他的基本思想是用一种专门的编程语言,为css增加了一些编程的特性,简单来说就是他可以改善我们书写css的习惯,像写js那样充满逻辑性,举个最简单的例子,正常我们写css样式是这样。

.div {
   color: #ccc;
   ........
}

当我们使用css预处理器之后玩法就很多了,比如我们定义一个全局的字体样式,然后在想要使用的地方直接赋值就可以了。单从这个例子还不足以看出css预处理器的优势。但是项目变大大了复杂之后。你会庆幸使用了css预处理器。

$color-report-text: #ccc;
​
.div {
    color: $color-report-text;
    .......
}

carbon.png

css预处理器的作用就是使用编程似的书写方式写出web开发的样式,最后通过编译器转换为正常的css文件,这其中虽然最后多了一步编译的过程,但是在开发阶段却可以提高开发人员书写样式的效率。

为什么要使用CSS预处理器

在前端开发中,大家都知道JavaScript可以定义变量,但是css仅仅是一门标记语言,他不能定义变量,也不能在别的地方引用,因此使用原生的css将局限他在项目中扩展性,复用性。

css的缺点

  • 语法不够强大,无法嵌套书写,导致开发过程中要重复写很多的选择器;
  • 没有变量和合理的复用机制,使得他在逻辑上相关的属性值,必须以字面量的形式重复输出,导致难以维护。

这样就会导致我们在开发过程中增加了很多无谓的工作量,而使用css预处理器可以提供css的样式复用机制,减少冗余的代码,提高代码的可维护性,最终的目标——提高了我们的开发效率。

当然使用css预处理器也有缺点,比如我们在调试的时候,因为我们使用了预处理器,而我们在web调试时,他的样式都是最原生的css,所以在调试过程中也变得麻烦了。

Sass && Less

本人在开发过程中最长接触的预处理器有sass和less。
sass和less都被统称为css预处理器,那么我们都会有一些共同的疑惑,下面一起来看看。

了解下什么是sass和less

  • sass:Syntactically Awesome Stylesheets——动态样式语言。作为”世界上最成熟、最稳定、最强大的专业级CSS扩展语言”。兼容所有版本的css,且有无数框架使用sass构建,如Compass,Bourbon,和Susy。他提供了很多类似编程的思想比如变量嵌套运算混入(Mixin)继承颜色处理函数等。sass在3.0之后的版本其后缀名改为.scss

sass和scss的关系

sass在3.0之前的后缀名为.sass。其之前的语法对传统书写css样式的开发者很不友好,并且css样式代码不能直接copy到sass里,所以sass的开发人员在3.0版本时对sass的语法进行了改良处理,所以在3.0版本之后其命名的后缀改为了.scss,不仅对3.0之前的版本做了兼容,并且还友好的支持了css代码。

  • less:Leaner Style Sheets——他也是一种动态的样式语言。并且他是一种向后兼容的扩展语言。这里的向后兼容就是他支持IE 6+, Webkit, Firefox。并且他借助node.js还可以在服务端运行。
从两者提供的功能来看,less是比sass稍微简单一点的。

sass和less的区别

sass和less本身就是有区别的

编译环境不同

因为他们并不是直接输出的css,所以他们需要一个编译环境,而两者的设计模式都不同,所以两者的编译环境也不同。

  • Sass的安装需要Ruby环境,是在服务端 处理的。
  • Less基于JavaScript,是需要引入Less.js来处理代码输出css到浏览器,也可以在开发环节使用Less,然后编译成css文件,直接放在项目中.

less比sass简单

当你使用less的时候,只要你有css语法的使用基础,使用less并没有太大的难度.
当你使用sass的时候,sass提供的复杂功能,丰富的语法让其对使用者的要求也更高了一点.

sass比less功能更强大

sass相较于less有如下一些功能

  • sass有变量和作用域。
  • sass有函数的概念;
  • 进程控制;
  • 数据结构;

两者的处理机制不同

less通过客户端处理,sass通过服务端处理.从解析速度来说less解析会比sass慢一点.

变量命名规范不同

less中定义变量前缀使用@符号,而sass中定义变量的前缀使用$符号.

相同之处

Less和Sass在语法上有些共性,比如下面这些:

1、混入(Mixins)——class中的class;
2、参数混入——可以传递参数的class,就像函数一样;
3、嵌套规则——Class中嵌套class,从而减少重复的代码;
4、运算——CSS中用上数学;
5、颜色功能——可以编辑颜色;
6、名字空间(namespace)——分组样式,从而可以被调用;
7、作用域——局部修改样式;
8、JavaScript 赋值——在CSS中使用JavaScript表达式赋值。

两者的实际应用

变量(Variables)

@width: 10px;
@height: @width + 10px;

#header {
width: @width;
height: @height;
}

输出结果

carbon.png

$width: 10px;
$height: $width + 10px;

#header {
    width: $width;
    height: $height;
}

输出结果是一样的

变量的作用域

@color: #00c; /* 蓝色 */

#header {
    @color: #c00; /* red */
    border: 1px solid @color; /* 红色边框 */
}
#footer {
    border: 1px solid @color; /* 蓝色边框 */
}

Less-作用域编译后

#header{border:1px solid #cc0000;}
#footer{border:1px solid #0000cc;}

$color: #00c; /* 蓝色 */

#header {
    $color: #c00; /* red */
    border: 1px solid $color; /* 红色边框 */
}
#footer {
    border: 1px solid $color; /* 蓝色边框 */
}

Sass-作用域编译后

#header{border:1px solid #c00}
#footer{border:1px solid #c00}

  • 我们可以看出来,less和scss中的变量会随着作用域的变化而不一样。

混合(Mixins)

混合(Mixin)是一种将一组属性从一个规则集包含(或混入)到另一个规则集的方法。假设我们定义了一个类(class)如下:

.bordered {
    border-top: dotted 1px black;
    border-bottom: solid 2px black;
}

如果希望在其它规则集中使用这些属性,只需像下面这样输入所需属性的类(class)名称即可

#menu a {
    color: #111;
    .bordered();
}

.post a {
    color: red;
    .bordered();
}

混合器使用@mixin标识符定义,这个标识符给一大段样式赋予一个名字,可以轻易地通过引用这个名字重用这段样式。

下边的这段sass代码,定义了一个非常简单的混合器,目的是添加跨浏览器的圆角边框。

@mixin rounded-corners {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}

然后就可以在样式表中通过@include来使用这个混合器。@include调用会把混合器中的所有样式提取出来放在@include被调用的地方。如果像下边这样写:

notice {
background-color: green;
border: 2px solid #00aa00;
@include rounded-corners;
}

//sass最终生成:

.notice {
background-color: green;
border: 2px solid #00aa00;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}

嵌套(Nesting)

Less 提供了使用嵌套(nesting)代替层叠或与层叠结合使用的能力。假设我们有以下 CSS 代码:

#header {
color: black;
}
#header .navigation {
font-size: 12px;
}
#header .logo {
width: 300px;
}

用 Less 语言我们可以这样书写代码:

#header {
color: black;
.navigation {
font-size: 12px;
}
.logo {
width: 300px;
}
}

你还可以使用此方法将伪选择器(pseudo-selectors)与混合(mixins)一同使用。下面是一个经典的 clearfix 技巧,重写为一个混合(mixin) (& 表示当前选择器的父级):

.clearfix {
display: block;
zoom: 1;

&:after {
content: " ";
display: block;
font-size: 0;
height: 0;
clear: both;
visibility: hidden;
}
}

基本用法与less相同

  • 子组合选择器和同层组合选择器:>、+和~

这三个组合选择器必须和其他选择器配合使用,以指定浏览器仅选择某种特定上下文中的元素。

这些组合选择器可以毫不费力地应用到sass的规则嵌套中。可以把它们放在外层选择器后边,或里层选择器前边:

article {
~ article { border-top: 1px dashed #ccc }

> section { background: #eee }
> dl > {
> dt { color: #333 }
> dd { color: #555 }
> }
> nav + & { margin-top: 0 }
> }
  • 嵌套属性;

嵌套属性的规则是这样的:把属性名从中划线-的地方断开,在根属性后边添加一个冒号:,紧跟一个{ }块,把子属性部分写在这个{ }块中。就像css选择器嵌套一样,sass会把你的子属性一一解开,把根属性和子属性部分通过中划线-连接起来,最后生成的效果与你手动一遍遍写的css样式一样:

nav {
border: {
style: solid;
width: 1px;
color: #ccc;
}
}
navbar {
border-style: solid;
border-width: 1px;
border-color: #ccc;
}

对于属性的缩写形式,你甚至可以像下边这样来嵌套,指明例外规则:

nav {
border: 1px solid #ccc {
left: 0px;
right: 0px;
}
}

导入(Importing)

你可以导入一个 .less 文件,此文件中的所有变量就可以全部使用了。如果导入的文件是 .less 扩展名,则可以将扩展名省略掉:

@import "library"; // library.less

sass也有一个@import规则,但不同的是,sass的@import规则在生成css文件时就把相关文件导入进来。这意味着所有相关的样式被归纳到了同一个css文件中,而无需发起额外的下载请求。

  • 使用sass的@import规则并不需要指明被导入文件的全名。你可以省略.sass或.scss文件后缀
  • 默认变量值;
    !default用于变量,含义是:如果这个变量被声明赋值了,那就用它声明的值,否则就用这个默认值。
$fancybox-width: 400px !default;
.fancybox {
width: $fancybox-width;
}

在上例中,如果用户在导入你的sass局部文件之前声明了一个$fancybox-width变量,那么你的局部文件中对$fancybox-width赋值400px的操作就无效。如果用户没有做这样的声明,则$fancybox-width将默认为400px。

函数(Function)

函数的用法非常简单。下面这个例子将介绍如何利用 percentage 函数将 0.5 转换为 50%,将颜色饱和度增加 5%,以及颜色亮度降低 25% 并且色相值增加 8 等用法:

@base: #f04615;
@width: 0.5;

.class {
  width: percentage(@width); // returns `50%`
  color: saturate(@base, 5%);
  background-color: spin(lighten(@base, 25%), 8);
}


Sass也可以使用函数
如果$isHorizontal等于true,scroll-bar函数将执行width:8px,否则高度则等于8px

$isHorizontal: true

scroll-bar($isHorizontal: true) {
    @if $isHorizontal {

      width: 8px;

    } @else {

      height: 8px;

    }
}

实际开发问题

在实际的开发过程中,我们经常会引用一些UI库的组件,但是我们面对各种的业务场景和UI设计时,会来更改组件的样式达到目的

样式穿透

在实际开发过程中样式穿透较常用

<style lang="less" scoped>
.conBox /deep/ .el-input__inner{
    padding:0 10px;
}
</style>

<style lang="scss" scoped>
.conBox ::v-deep .el-input__inner{
    padding:0 10px;
}
</style>

<style>
.num-input {
    width: 90px;
    margin-top: 15px;
    >>> .ivu-input {
      text-align: center!important;
    }
}
</style>

Sass的流程控制

sass中可以使用类似编程语言的流程控制语句,例如下面:

&::-webkit-scrollbar {
    @if $isHorizontal {
      width: 8px;
    } @else {
      height: 8px;
    }

  }

项目中的使用

通常我们实际开发会借助UI库来帮助我们开发,在实际的项目开发中我们也会对项目做一些全局的封装和混入.

封装可复用的过渡动画

封装一个可复用且支持混入的过渡动画

transition-slide-fade($translation: -100px, $isHorizontal: true) {

  &.slide-fade-enter-active {

    transition: all 0.3s ease;

  }

  &.slide-fade-leave-active {

    transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1);

  }

  &.slide-fade-enter,

  &.slide-fade-leave-to {

    @if $isHorizontal {

      transform: translateX($translation);

    } @else {

      transform: translateY($translation);

    }

    opacity: 0;

  }

}
最后修改:2021 年 12 月 09 日
如果觉得我的文章对你有用,可以对我进行您主观即不限定金额大小的打赏。