>  기사  >  웹 프론트엔드  >  CSS 전처리 언어의 모듈식 실습

CSS 전처리 언어의 모듈식 실습

巴扎黑
巴扎黑원래의
2017-03-29 14:43:261320검색

CSS를 작성하는 것은 프런트 엔드 작업에서 일반적이고 빈번한 작업입니다. CSS는 언어가 아니기 때문에 프로그래밍이 약간 조잡해 보입니다. 소규모 프로젝트의 경우 CSS의 양이 크지 않아 문제가 부각되지 않습니다. 그러나 대규모 프로젝트를 개발하고 유지하려면 CSS를 관리하고 표준화해야 합니다. 그렇지 않으면 돌이킬 수 없는 결과가 발생하게 됩니다. 겁?).

배경

이전 섹션 [CSS의 모듈성에 대해 이야기]에서는 지속 가능한 개발 경로를 형성하기 위해 표준화된 제약 조건을 통해 CSS가 작성되는 방식을 최적화하고 개선했습니다. 하지만 아직 남아 있는 것이 있습니다. 바로 중복성입니다. 퍼블릭 모듈과 프라이빗 모듈을 정의하여 커먼의 볼륨을 완곡하게 공유하지만, 커먼의 볼륨은 여전히 ​​너무 크며, 디자인 관점에서는 재사용을 더 잘 달성하기 위해 가능한 한 많은 퍼블릭 모듈을 개선해야 합니다. 가장 이상적인 상황은 모든 모듈이 공통 라이브러리에 저장되고 필요할 때마다 라이브러리에서 직접 전송할 수 있다는 것입니다. 이 아름다운 소망은 전처리 언어의 도움으로 쉽게 달성할 수 있습니다.

전처리 언어는 CSS와 유사한 언어라는 것을 우리는 알고 있으며, 전처리 언어는 언어 기능 중 이 부분을 채우기 위해 탄생했습니다. 변수 정의, 함수 정의, 믹스 정의는 물론 파일 참조, 병합, 압축 등의 기능을 구현하여 CSS를 객체지향적으로 만들어 복잡하고 규모가 큰 비즈니스에 대응할 수 있습니다.

현재 널리 사용되는 전처리 언어에는 less와 sass라는 두 가지 언어가 있습니다. 공부할 때는 둘 다 시작할 수 있고, 일할 때는 둘 중 하나에 익숙해지도록 노력하세요. 저는 sass를 더 자주 사용하기 때문에 sass를 기본 언어로 사용하여 다음 내용을 소개합니다. 둘은 기능면에서 많은 유사점이 있으므로 구현에 있어서 큰 차이는 없다고 걱정하지 않으셔도 됩니다.

으악

공식 홈페이지(영어)나 w3cplus sass 가이드(중국어)에서 기본 문법을 배울 수 있습니다. 여기서는 간략하게만 살펴보고 사용해야 할 내용 중 일부만 다루겠습니다.

Sass에는 두 개의 접미사 파일 이름이 있습니다. 하나는 접미사 이름이 sass이고 중괄호와 세미콜론을 사용하지 않습니다. 다른 하나는 여기서 사용하는 scss 파일로, 중괄호와 세미콜론을 사용하여 일반적으로 작성하는 CSS 파일 형식과 유사합니다. 이 튜토리얼에서 언급된 모든 sass 파일은 접미사가 scss인 파일을 참조합니다. 또한 sass 접미사의 엄격한 형식 요구 사항으로 인한 오류를 방지하려면 접미사 scss가 있는 파일을 사용하는 것이 좋습니다. ——w3cplus sass 가이드에서 발췌

1. 네스팅(매우 중요한 기능)

Sass에는 두 가지 유형의 중첩이 있습니다. 하나는 선택자의 중첩이고, 다른 하나는 속성의 중첩입니다. 우리가 일반적으로 이야기하거나 사용하는 것은 선택자의 중첩입니다. ——w3cplus sass 가이드에서 발췌

선택기 중첩 소위 선택기 중첩은 하나의 선택기를 다른 선택기 내에 중첩하여 상속을 달성함으로써 Sass 파일의 구조와 가독성을 향상시키는 것을 의미합니다. 선택기 중첩에서는 &를 사용하여 상위 요소 선택기를 나타낼 수 있습니다. ——w3cplus sass 가이드에서 발췌

// index.scss

.g-index {
  ...

  .g-hd {
    ...

    .m-nav { ... }
  }

  .g-bd {
    ...

    .m-news { ... }
  }

  .g-ft {
    ...

    .m-copy_right { ... }
  }

  .m-dialog {
    display: none;

    &.z-active {  // 留意此处&的用法
      display: block;
    }
  }
}

편집 후:

/* index.css */

.g-index { ... }
.g-index .g-hd { ... }
.g-index .g-hd .m-nav { ... }

.g-index .g-bd { ... }
.g-index .g-bd .m-news { ... }

.g-index .g-ft { ... }
.g-index .g-ft .m-copy_right { ... }

.g-index .m-dialog {
  display: none;
}

.g-index .m-dialog.z-active {  // 留意此处&的编译结果
  display: block;
}

멋지지 않나요? 수많은 선택자를 반복해서 복사하고 수정할 필요도 없고, 이들 사이의 관계를 정리할 필요도 없으며, 중첩만 하면 모든 관계가 DOM을 보는 것처럼 간단하고 명확합니다. 곧장! 손을 자유롭게 하고 눈을 자유롭게 하며 동시에 효율성을 높이십시오. Sass를 작성할 때 Sass의 중첩 순서를 DOM과 일관되게 유지해야 한다는 점은 주목할 가치가 있습니다. DOM의 모든 요소에 스타일을 지정할 필요가 없기 때문에 중첩 순서는 레벨이 아니라 일관됩니다.

sass의 중첩된 작성 방법이 유지 관리하기 쉽다는 것을 설명하기 위해 또 다른 시나리오를 언급하겠습니다. 원래 g-bd 아래에 m-article_box 모듈이 있다고 가정합니다. 이제 m-article_box를 g-bd에서 g-hd로 마이그레이션하려고 합니다. 물론 이 요구 사항은 다소 불합리합니다~), 원본 코드를 살펴보겠습니다:

<!-- index.html -->

<!DOCTYPE html>
<html>
<head>
  <title>index</title>
</head>
<body>
  <p class="g-index">
    <p class="g-bd">
      <p class="m-article_box">
        <p class="hd">
          最新文章
        </p>
        <p class="bd">
          <p class="list">
            <p class="item">
              <img class="cover" />
              <p class="info">
                <p class="title">
                  <a href="#">文章标题</a>
                </p>
                <p class="desc">文章简介</p>
              </p>
            </p>
          </p>
        </p>
        <p class="ft">
          <p class="page">
            <a href="#" class="pg">1</a>
            <a href="#" class="pg">2</a>
            <a href="#" class="pg">3</a>
            <a href="#" class="pg">4</a>
          </p>
        </p>
      </p>
    </p>
  </p>
</body>
</html>
rrree

CSS 방식에 따르면 m-article_box와 관련된 모든 부분을 g-bd에서 g-hd로 복사해야 합니다. 이것은 아직 모듈의 작성이 사양을 준수한다는 조건 하에서입니다. 모듈의 작성이 사양을 준수하지 않고 m-article_box 클래스 아래의 모든 구조를 걸지 않으면 정말 재앙이 될 것입니다~ 하지만 이제 sass를 사용하면 m-article_box의 전체 블록을 g-bd에서 g-hd로 자르기만 하면 됩니다(수정 작업의 부담을 강조하기 위해 전체 모듈 구조를 특별히 작성했습니다. 단어 수... ):

아아아아

매우 편리하고 오류가 덜 발생합니다.

2. 변수

코드로 바로 이동해 보겠습니다.

.g-bd { ... }
.g-bd .m-article_box { ... }
.g-bd .m-article_box .hd { ... }

.g-bd .m-article_box .bd { ... }
.g-bd .m-article_box .bd .list { ... }
.g-bd .m-article_box .bd .list .item { ... }
.g-bd .m-article_box .bd .list .item .cover { ... }
.g-bd .m-article_box .bd .list .item .info { ... }
.g-bd .m-article_box .bd .list .item .info .title { ... }
.g-bd .m-article_box .bd .list .item .info .desc { ... }

.g-bd .m-article_box .ft { ... }
.g-bd .m-article_box .ft .page { ... }
.g-bd .m-article_box .ft .page .pg { ... }

편집 결과:

// 修改前
.g-hd { ... }

.g-bd {
  .m-article_box {
    .hd { ... }
    .bd {
      .list {
        .item {
          .cover {
            ...
          }

          .info {
            .title {
              ...
            }

            .desc {
              ...
            }
          }
        }
      }
    }

    .ft {
      .page {
        .pg { ... }
      }
    }
  }
}

// 修改后
.g-hd {
  .m-article_box {
    .hd { ... }
    .bd {
      .list {
        .item {
          .cover {
            ...
          }

          .info {
            .title {
              ...
            }

            .desc {
              ...
            }
          }
        }
      }
    }

    .ft {
      .page {
        .pg { ... }
      }
    }
  }
}

.g-bd { ... }

코드를 작성해본 사람이라면 매개변수의 사용법은 익히 알고 있을 것입니다. 너무 간단하고 간단해서 직접 알아보세요.

3. 기능

rree

너무 간단하고 간단합니다. 너무 많이 말하고 싶지 않습니다.

4、混合(mixin)

混合,顾名思义,就是混合的意思。。。也就是我们可以事先定义一段代码块,在需要使用到的地方,直接引用(include),而在引用之前,这段代码都不会出现在编译文件中,也就是不会生成任何内容。

这也是非常重要的一个特性!我们知道common的体积非常大,而体积大的根本原因是它存放了许许多多的模块。我们设想一下,如果将每一个模块都打包成mixin,那common不就减肥成功了?!多年的顽疾终于看到希望,没有比这更让人惊喜的了!我们这就上车:

/* common.css */

.m-nav { ... }
.m-news { ... }
.m-copy_right { ... }

改造后

// common.scss

@mixin m-nav {
  .m-nav { ... }
}

@mixin m-news {
  .m-news { ... }
}

@mixin m-copy_right {
  .m-copy_right { ... }
}


// index.scss

.g-index {
  @include m-nav;
  @include m-news;
  @include m-copy_right;
}

5、import

这个属性很眼熟?没错,事实上,css本身就有这个属性实现,我们可以在css文件中直接使用import来引入其他文件。那么css的import和sass的import有什么区别?从含义和用法上来说,没有区别,区别在于工作原理。css的import是阻塞的,而sass的import在编译后,其实是合并文件,最后只产出一个css文件,而css则没有合并,该多少个文件就还是多少个文件。

注意:

  1. 只有import一个.sass/.scss文件的时候,才可以省去后缀名,如果是直接import一个.css文件,要补全文件名;


  2. import之后的分号;不要漏写,会报错;


  3. sass如果import的是一个.css文件的话,那它的作用就跟css原生的import作用一样,只有import一个sass文件的时候,才是合并文件。

如下:

// index.scss
@import &#39;common&#39;;
@import &#39;a.css&#39;;

编译结果:

/* index.scss */

.m-nav { ... }
.m-news { ... }
.m-copy_right { ... }

@import url(&#39;a.css&#39;);

css的import之所以没有被普遍使用是有原因的。我们可以大概猜到它的工作原理:a.css import b.css以后,当浏览器加载到页面中的a.css的时候,已经准备按照a.css的内容来渲染页面了,刚解析到第一行,发现a.css居然还import了一个b.css,于是它不得不先放下a.css(既阻塞a.css),去加载b.css,直到b.css加载完,并且优先解析它,然后才开始回来解析a.css——鬼知道b.css会不会又import了c.css……这直接导致了渲染工作滞后,引发性能问题。

说实话我还不如直接用两个link标签去同步加载a.css和b.css,效率会高一些。

所以css的import基本是被抛弃了的属性。

sass的import主要的好处就是把文件合并了,减少了请求。原本需要link好几个css文件的页面,现在只需要一个。

模块化

终于要开始干点正事了,首先我们来回顾一下,上一节我们以规范为基础构建的模块化项目,遗留了一些什么问题。

  1. 冗余 体积庞大的common;


  2. 使用cm-模块区别m-模块,使得后期开发过程中,m-模块向cm-模块转变过程比较繁琐;

……

好像,问题也不是特别多,我们一个一个解决。

为了方便,在这里我们把每个页面所对应的scss文件叫做 页面scss;把变量、函数、混合等(没有被引用或者执行的情况下)编译后不产生实际内容的代码叫做 定义类代码 ,那么相对应的其他内容就是 实际内容代码。

1、mixin.scss

我们知道,一方面,在common中过多地添加模块最终会导致common的体积过大,使得资源冗余,另一方面,为了方便维护,我们又希望尽量多地把模块公有化。

这是一对矛盾,仅靠css本身是无法解决的,但sass可以!如果我们使用mixin来代替直接书写模块,由于mixin并不直接生成代码,而是通过主动引用,才能生成对应内容,那么理论上,common就可以无限多地存放模块而不必占用一点空间!

(注意,这里说的是理论上,实际应用中,文件太过庞大的话,免不了还是要受到命名冲突的限制的,不过这问题不大。)

说干就干,我们把common中的模块全部打包成mixin:

/* common.css */

.m-nav { ... }
.m-news { ... }
.m-copy_right { ... }

改造后

// common.scss

@mixin m-nav {
  .m-nav { ... }
}

@mixin m-news {
  .m-news { ... }
}

@mixin m-copy_right {
  .m-copy_right { ... }
}

调用方式如下:

// index.scss

@import &#39;common&#39;; // 记得先引入common

.g-index {
  @include m-nav;
  @include m-news;
  @include m-copy_right;
}

原本我们会在每个需要用到公共模块的页面中,先引用common,然后再引用页面css,而现在,我们只需要在页面scss中直接@import common;就可以了。

使用common:

<!-- index.html -->

<!DOCTYPE html>
<html>
<head>
  <title>index</title>
  <link rel="stylesheet" type="text/css" href="./style/common.css">
  <link rel="stylesheet" type="text/css" href="./style/index.css">
</head>
<body>
  ...
</body>
</html>

改造后:

// index.scss
@import &#39;common&#39;;
<!-- index.html -->

<!DOCTYPE html>
<html>
<head>
  <title>index</title>
  <link rel="stylesheet" type="text/css" href="./style/index.css">
</head>
<body>
  ...
</body>
</html>

很完美,——至少目前为止是这样。

我们思考一个问题,common除了存放模块之外,还有没有其他内容?答案是肯定的,大家一定知道有个东西叫做css reset(或者normalize.css),这肯定是全局的;另外,如果是做后台管理系统的话,可能还会有bootstrap。当然,还有一些自定义的全局的样式,比如常见的.clearfix,等等。

这些东西目前我们也堆积在common当中,而且合情合理,因为它们都是全局的样式。但是对比起mixin来说,这些实际内容代码显得很少量,有种被淹没的感觉,使得整个common看上去就像只有mixin。但是这些实际内容代码的作用却又非常重要。为了使common的构成更加直观,我们把mixin全部都抽离出来,单独存放一个叫做mixin.scss的文件中,然后在common引用它,这样,mixin的管理更加的规范,而且common的结构也更加清晰了。

抽离mixin还有另外一个重要原因,后面会讲到的,我们希望mixin作为一个纯粹定义类代码文件,随处可以引用而不会生成多余的代码。

原本我们会在每个需要用到公共模块的页面中,先引用common,然后再引用页面css,而现在,我们只需要在页面scss中直接@import mixin;就可以了。

使用mixin:

// index.scss
@import &#39;common&#39;;  // 引入common,如果有需要,common里一样可以引入mixin
@import 'mixin';  // 引入mixin

.g-index {
  ...
}
<!-- index.html -->

<!DOCTYPE html>
<html>
<head>
  <title>index</title>
  <link rel="stylesheet" type="text/css" href="./style/index.css">
</head>
<body>
  ...
</body>
</html>

2、common.scss

好,抽离了mixin之后,我们现在来重新看回common,common里应该是些什么样的内容。上面的内容我们稍稍提到了一点,我们来展开一下。

2.1、css reset(normalize)

我们知道浏览器千差万别,各浏览器的默认样式也是不尽相同,最常见的比如body的默认内边距,p标签的默认内边距,以及ul/ol等等。这些不统一的默认样式经常让我们感到头疼,所以就有人提出一开始写样式就先把它们消除的想法,于是就催生了后来非常流行的reset.css。

起初的reset.css很简单,大概是这样的:

html, body, h1, h2, h3, h4, h5, h6, p, dl, dt, dd, ul, ol, li, p {
  margin: 0;
  padding: 0;
}

没错,就是把几乎所有会用到的标签都给去了内边距和外边距,简单粗暴,这样所有的标签就都统一了,而且在不同的浏览器下也是统一的。

其他的部分每个人有各自的补充,比如有人会把h1~h6的所有字号给定义一遍,以保证在不同浏览器下他们有统一的大小;有人会给a标签设置统一的字体颜色和hover效果,诸如此类等等。

很好,没毛病。我们把这些统称为css reset,然后再统一封装到一个叫做reset.css的文件中,然后每个页面都引用。

这种方式一直以来都挺实用,而且大家也都这么用,没出过什么问题。只是后来有人提出,这种方式太过粗暴(居然还心疼浏览器了)。。。而且会降低页面渲染的性能,最重要的是,这使得我们原本设计出来的表达各种含义的标签儿们,变得毫无特点了。。。

说的好有道理,如果你家里所有人名字不一样但是都长一个样,还有啥意思。

于是,就出现了normalize.css,normalize的目的同样是为了统一各个浏览器下各不相同的默认样式,不过它并不是简单粗暴地全部抹平,而是根据规范,来人为地把那些不符合规范的默认样式“扶正”,从而达到统一各个浏览器默认样式,同时保留各个标签原有特点的目的。

我们不能说reset与normalize这两种思想孰好孰坏,只能说各有各的特点和作用,它们的存在都是为了解决同样的问题。

2.2、插件

一般来说,一个ui插件都会至少包括一个css文件,像bootstrap、datepicker等等。假设我们项目中需要以bootstrap为基础框架,实现快速开发,那么这时候我们就需要在项目中全局引入bootstrap.min.css,当然,还有bootstrap.min.js。说到全局暴露,我们第一时间想到的是common,没错,我们可以在common中引入。

有人问,插件的.css文件怎么import?额,改一下扩展名为.scss就可以了,scss是兼容原生css语法的~

所以最终,我们的common大概是这样子的:

// common.scss

@import &#39;./reset&#39;;
@import &#39;./bootstrap.min&#39;;
@import &#39;./mixin&#39;;

事实上,如果我们不需要使用到 mixin.scss 中的变量和mixin的话,我们可以不引用它。

那么我们的页面scss应该是这样的:

// index.scss

@import &#39;./common&#39;;
@import &#39;./mixin&#39;;

.g-index {
  ...
}

干净,整洁。

3、mixin编写规范

每添加一个新角色,我们就要及时给它设置规范,好让它按照我们的期望工作别添乱。我们接下来来归纳一下mixin的书写规范。

시나리오 1: 프로젝트에는 mixin.scss, a.scss(특정 함수 파일이라고 가정), index.scss라는 세 가지 파일이 있습니다. $fontSize: 16px 변수가 mixin에 정의되어 있습니다. a.: #ccc;에 정의되어 있으며 인덱스에서 이 두 파일을 동시에 참조한 다음 인덱스에서 두 변수 $fontSize 및 $color를 직접 사용할 수 있습니다. 이 두 변수의 선언 및 정의에 대한 인덱스이지만 그냥 존재합니다.

이것은 좋은 일인가요, 아니면 나쁜 일인가요? 내 직감은 뭔가 문제가 있을 수 있다고 말합니다. 네, 이것은 앞서 논의했던 오염과 비슷합니까? 단지 이전에 common을 참조한 후 뭔가가 작성되기 전에 인덱스에서 많은 모듈 이름을 차지했을 뿐입니다. 이제는 다른 파일을 참조했기 때문에 인덱스에서 많은 변수 이름을 차지했습니다. 게다가 유지관리 측면에서도 이것도 문제가 되네요. 제가 미리 말씀드리지 않거나, 믹스인과 a를 미리 읽어보지 않으시면 인덱스의 $color가 어디서 나오는지 아시나요? ? 글꼴 크기가 필요하다고 가정해 보겠습니다. 어떤 파일을 수정해야 하는지 아시나요? 또한 mixin과 a를 동시에 참조할 때 둘 사이에 동일한 이름을 가진 변수가 있을 수 있는지 어떻게 확인합니까? 그럼 누가 누구를 덮나요? 이러한 문제는 사소해 보일 수 있지만 프로젝트 규모가 커지면 돌이킬 수 없는 재앙이 될 수도 있습니다(누구를 겁주시나요???).

시나리오 2: 프로젝트에 테마 색상이 있다고 가정합니다. 테두리, 탭 배경, 탐색 표시줄 배경, 글꼴 색상 등은 사용 편의성을 위해 항상 색상 선택기를 사용하고 싶지 않습니다. 값을 얻으므로 믹스인에 전역 변수 $color: #ff9900을 정의하면 어디서나 즐겁게 사용할 수 있습니다!

전체 홈페이지가 완성된 지 한 달쯤 지나서 디자이너가 갑자기 찾아와서 "사장님이 테마 색상을 바꿔야 한다고 하더군요. 좀 흙빛이 나네요. 밝은 빨간색으로 바꾸자고 하더군요."라고 했습니다. 마지못해 기쁜 마음으로 몰래 열어보고 $color 값을 밝은 빨간색으로 변경한 뒤 디자이너에게 "다행히 준비했으니 됐어요. 한번 보세요."라고 자랑스럽게 말했습니다. , 페이지를 열어보세요 디자이너와 내 얼굴이 모두 녹색인데 페이지가 왜 이렇게 못생겼나요? 일부 단어는 원래 테마 색상이었는데 배경이 빨간색이었는데 지금은 변경하고 나서 블록 전체가 이렇게 되었습니다. 원래 테두리가 빨간색이었는데, 글꼴이 원래 테마 색상인데 지금은 변경되어 테두리와 글꼴이 빨간색으로 바뀌었습니다.

디자이너: "아뇨, 아뇨, 그냥 배경색을 바꾸고 싶은데요.
당신: "테마 색 바꾸라고 하지 않았어? 그게 다야.
디자이너: "아니요, 그냥 배경만 바꾸세요.
당신: "말도 안돼..."
디자이너: "왜 안 되나요? 그냥 배경색만 바꾸면 되지 않나요? 설정한 대로 다시 바꾸면 됩니다.
당신: "생각보다 간단하지 않네요..."

……

좋아요, 저는 단지 당신에게 겁을 주려고 왔습니다. 당신이 정말 잘한다면 별 문제가 되지 않을 것입니다.

따라서 믹스인을 관리했던 것처럼 (전역) 변수를 관리해야 합니다. 원하는 곳 어디에서나 변수를 정의할 수 없으며, 매번 전역 변수를 수정할 수도 없습니다.

  1. 전역 변수는 믹스인에서만 정의됩니다. 다른 scss 파일(전역 또는 로컬에 노출되는지 여부)에 정의된 변수는 지역 변수로만 간주되며 현재 파일 외부에서는 사용되지 않습니다(참조할 수 있더라도 사용하지 마십시오).


  2. 전역 변수를 사용해야 하는 경우에는 mixin을 직접 import하세요.


  3. 일반적으로 전역 변수는 주의해서 정의해야 하며, 전역 변수의 수는 가능한 한 적어야 합니다. > 요구 사항이 변경되는 경우 목적이 매우 확실하지 않은 한 전역 변수를 추가하여 수정해야 하는 부분을 점진적으로 교체하세요.

  4. color와 같은 너무 일반적인 명사를 전역 변수로 사용하지 마십시오. $orange: #ff9900과 같이 색상 값에 대한 설명을 직접 사용하는 것이 좋습니다. 수정해야 하지만 모든 위치를 수정해야 하는 것은 아닙니다. 그런 다음 $red:red와 같이 확장하기 위해 새 변수를 정의할 수 있습니다.


  5. 사실, 우리가 이것을 해야 하는 이유를 설명하는 것은 정말 어렵습니다. 결국 그것은 모두 경험의 요약이므로, 생각하기 전에 일정 기간 동안 Sass를 사용하는 데 익숙해지는 것이 좋습니다. 이러한 문제를 자세히 설명합니다.
  6. 위의 사항은 엄격한 규칙이 아니며 나중에 설명할 SPA와 같은 실제 프로젝트를 기반으로 이 사양을 조정해야 하는 경우도 있습니다. 완벽한 프로젝트도 없고, 모든 프로젝트에 적용할 수 있는 개발 모델도 없습니다. 현지 상황에 맞게 조치를 취해야만 문제를 더 잘 해결할 수 있습니다. 게다가 지금까지 언급한 문제 중 치명적인 문제는 이전 섹션에서 사양을 공식화했을 때 피할 수 없었습니다.

  7. 모듈 호출
  8. 질문, 모듈을 어디에서 호출해야 합니까?

    답변, 페이지 scss.
  9. 在页面scss中调用模块是一个好习惯,它使得我们在每个页面所用到的模块既是一致的又是互相隔离的,不像在common中直接引用模块那样,使得一个页面scss还没有内容的时候就已经被很多模块名污染了。

    再提个问题,在页面scss的哪里调用模块?

    例一,根类外:

    // index.scss
    
    @import &#39;./common&#39;;
    @import &#39;./mixin&#39;;
    
    @include m-nav;
    @include m-news;
    @include m-copy_right;
    
    .g-index {
      ...
    }

    例二,根类内:

    // index.scss
    
    @import &#39;./common&#39;;
    @import &#39;./mixin&#39;;
    
    .g-index {
      @include m-nav;
      @include m-news;
      @include m-copy_right;
    
      ...
    }

    目前为止,这两种方式都是可以的,至于我为什么用“目前为止”这个词,那是因为我们后面将要讲到的SPA,如果用例一的方式是有问题的。所以我比较鼓励使用例二的方式。当然,我说了,目前为止例一也是没问题的。

    性能优化

    目前为止,我们的模块化工作已经算是完成了,其实已经可以收工了。不过我们还是可以稍微做一下优化。

    1、缓存

    我们需要考虑一个问题:缓存。

    缓存是我们web开发中最常见的情况之一,很多时候我们都需要跟缓存打交道,特别是在做性能优化的时候。

    一般来说,静态资源在被加载到浏览器之后,浏览器会把它本地缓存下来,以便下次请求同个资源的时候可以快速响应,不需要再去远程服务器加载。

    我们就css来说,假设我们按照原来的方式,使用多个link去加载reset、bootstrap、common、index这几个文件的话,这几个文件都会被缓存下来,以使得下次再访问这个页面,这个页面的加载速度会快很多。

    如果是从index页面跳转到about页面呢?你会发现也很快,因为about页面的全局css(reset、bootstrap、common)和index页面是一样的,而它们在你访问index的时候,已经加载过了,得益于缓存的作用,之后的页面打开都快。

    我们现在的方式是,一个页面所用到的所有css文件都被合并成一个,也就不存在相同的文件可以利用缓存这样的优势了。

    那我们有办法改进吗?有的!我们只需要把common独立出来,那么common就可以做为被缓存的公共文件了。最终我们从一个页面只引用一个文件变成了一个页面引用两个文件,即common和页面css:

    // common.scss
    
    @import &#39;./reset&#39;;
    @import &#39;./bootstrap.min&#39;;
    @import &#39;./mixin&#39;;
    // index.scss
    
    @import &#39;./mixin&#39;;
    
    .g-index {
      ...
    }

    注意,不同于之前,我们这里的index.scss不再引入common.scss,所以我们最终是得到了两个css文件,而common.css是在所有页面中通过link标签引入的。

    如此一来,我们就实现了既能够合并文件,减少请求数,又可以利用缓存,提高加载速度。

    2、压缩

    代码压缩是优化工作中最基本的一步,css的压缩空间是很大的,尤其是我们这种 垂直的书写方式 ,压缩起来是相当高效的。

    在sass中这很简单,sass在编译的时候提供了几种模式,其中的compressed模式是最高效的压缩模式,记得在编译打包的时候选择compressed模式就行了。

    总结

    总的来说,预处理语言在使我们编程更加美好的同时,也使得规范更加的完善。在css本身无法实现的情况下,我们通过工具来完成了模块化开发。

    我不会讲如何去安装和配置sass环境,因为这些w3cplus sass guide有详细的介绍了,建议使用nodejs的方式,不会捣鼓nodejs/npm的前端不是好前端。

    最后,我们回到一开始提到的问题——为什么要模块化?现在我们可以先从css的工作来回答,从某种意义上讲,模块化提高了我们编程能力和解决问题的能力,使得构建一个庞大而可扩展可维护的项目成为可能,使得我们能够以架构的思维和眼光去搭建整个项目。

위 내용은 CSS 전처리 언어의 모듈식 실습의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.