Maison  >  Article  >  interface Web  >  Pratique modulaire du langage de prétraitement CSS

Pratique modulaire du langage de prétraitement CSS

巴扎黑
巴扎黑original
2017-03-29 14:43:261320parcourir

L'écriture de CSS est une tâche courante et fréquente dans le travail front-end. Puisque CSS n'est pas un langage, la programmation semble un peu grossière. Pour les petits projets, la quantité de CSS n'est pas énorme et le problème n'est pas mis en évidence. Cependant, si vous souhaitez développer et maintenir un projet plus important, vous devez gérer et standardiser le CSS, sinon des conséquences irréversibles se produiront (à qui essayez-vous). faire peur ?).

Contexte

Dans la section précédente [Parler de la modularité de CSS], nous avons optimisé et amélioré la façon dont CSS est écrit via des contraintes normatives pour former une voie de développement durable. Mais quelque chose demeure : la redondance. Bien que nous partagions par euphémisme le volume du commun en définissant les modules publics et les modules privés, le volume du commun est encore trop important et du point de vue de la conception, nous devrions affiner autant de modules publics que possible pour mieux parvenir à la réutilisation. La situation la plus idéale est que tous les modules soient stockés dans une bibliothèque commune et qu'ils puissent être directement transférés depuis la bibliothèque là où ils sont nécessaires. Ce beau souhait n’est pas inaccessible. Avec l’aide du langage de prétraitement, nous pouvons facilement le réaliser.

Le langage de prétraitement est un langage de type CSS. Nous savons que CSS en lui-même n'est pas un langage, et le langage de prétraitement est né pour remplir cette partie de la fonction du langage. Il implémente la définition de variables, de fonctions et de mixages, ainsi que les fonctions de référence, de fusion et de compression de fichiers, rendant CSS orienté objet et capable de faire face à des activités complexes et énormes.

Il existe actuellement deux langages de prétraitement populaires : less et sass. Pour étudier, vous pouvez commencer avec les deux, et pour le travail, essayez de vous familiariser avec l'un d'entre eux. J'utilise sass plus souvent, donc le contenu suivant est introduit en utilisant sass comme langage de base. Les deux présentent de nombreuses similitudes en termes de fonctionnalités, vous n'avez donc pas à vous soucier d'énormes différences de mise en œuvre.

culot

Vous pouvez apprendre la grammaire de base sur le site officiel (anglais) ou sur le guide sass w3cplus (chinois). Nous ne l'aborderons que brièvement ici et parlerons d'une partie du contenu que nous devons utiliser. Nous ne couvrirons pas tout.

Sass a deux noms de fichiers de suffixe : l'un porte le nom de suffixe sass et n'utilise pas d'accolades ni de points-virgules ; l'autre est le fichier scss que nous utilisons ici, qui est similaire au format de fichier CSS que nous écrivons habituellement, en utilisant des accolades et des points-virgules. Tous les fichiers sass mentionnés dans ce didacticiel font référence à des fichiers portant le suffixe scss. Il est également recommandé d'utiliser des fichiers avec le suffixe scss pour éviter les erreurs dues aux exigences strictes de format du suffixe sass. ——Extrait du guide sass w3cplus

1. Nesting (caractéristique très importante)

Il existe deux types d'imbrication dans Sass : l'un est l'imbrication des sélecteurs ; l'autre est l'imbrication des attributs. Ce dont nous parlons ou utilisons habituellement, c'est l'imbrication des sélecteurs. ——Extrait du guide sass w3cplus

Imbrication de sélecteurs L'imbrication de sélecteurs fait référence à l'imbrication d'un sélecteur dans un autre sélecteur pour obtenir l'héritage, améliorant ainsi la structure et la lisibilité du fichier Sass. Dans l'imbrication du sélecteur, vous pouvez utiliser & pour représenter le sélecteur d'élément parent. ——Extrait du guide sass w3cplus

// 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;
    }
  }
}

Après compilation :

/* 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;
}

N'est-ce pas cool ? Il n'est pas nécessaire de copier et de modifier un grand nombre de sélecteurs encore et encore, et il n'est pas nécessaire de trier les relations entre eux. Il vous suffit de les imbriquer, et toutes les relations sont aussi simples et claires que de regarder le DOM. directement! Libérez vos mains, libérez vos yeux et augmentez en même temps l'efficacité. Il convient de noter que lorsque nous écrivons Sass, nous devons essayer de garder l'ordre d'imbrication de Sass cohérent avec le DOM. Notez que l'ordre d'imbrication est cohérent, pas le niveau, car tous les éléments du DOM n'ont pas besoin d'être stylisés.

Mentionnons un autre scénario pour illustrer que la méthode d'écriture imbriquée de sass est facile à maintenir. Supposons qu'il existe à l'origine un module m-article_box sous g-bd. Nous voulons maintenant migrer m-article_box de g-bd vers g-hd (. bien sûr, cette exigence est quelque peu déraisonnable ~), regardons le code original :

<!-- 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>
.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 { ... }

Selon la méthode CSS, nous devons copier toutes les parties liées à m-article_box de g-bd vers g-hd. Ceci est toujours à condition que l'écriture du module soit conforme aux spécifications et ne bloque pas toutes les structures sous la classe m-article_box, ce sera vraiment un désastre~ Mais maintenant, en utilisant sass, il suffit de couper tout le bloc de m-article_box de g-bd à g-hd (afin de mettre en évidence la lourde charge de travail de modification, j'ai spécialement écrit toute la structure du module - pour ne pas rattraper le nombre de mots... ):

// 修改前
.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 { ... }

Très pratique et moins sujet aux erreurs.

2. Variable

Passons directement au code :

// index.scss

$fontSize: 16px;
$grey: #ccc;

.m-nav {
  font-size: $fontSize;
  color: $grey;
}

Résultat de la compilation :

/* index.css */

.m-nav {
  font-size: 16px;
  color: #ccc;
}

Quiconque a écrit du code connaît l'utilisation du paramètre C'est trop simple et direct. Je ne veux pas en dire trop.

3. Fonction

// pixels to rems

@function rem($px) {
    @return $px / 640 * 16rem;
}

C'est trop simple et direct. Je ne veux pas en dire trop. Comprenez-le vous-même.

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的书写规范。

Scénario 1 : il y a trois fichiers dans le projet : mixin.scss, a.scss (en supposant qu'il s'agit d'un certain fichier de fonction) et index.scss. Une variable $fontSize : 16px est définie dans mixin et une variable $color. est défini dans a. : #ccc;, on référence ces deux fichiers dans l'index en même temps, alors on peut utiliser directement les deux variables $fontSize et $color dans l'index - je veux dire, même si on ne le voit pas dans l'index de la déclaration et de la définition de ces deux variables, mais elles existent simplement.

Est-ce une bonne ou une mauvaise chose ? Mon instinct me dit qu’il y a peut-être quelque chose qui ne va pas. Oui, est-ce similaire à la pollution dont nous avons parlé précédemment ? C'est juste qu'après avoir référencé common auparavant, de nombreux noms de modules étaient occupés dans l'index avant que quoi que ce soit ne soit écrit. Maintenant, parce que nous avons référencé d'autres fichiers, de nombreux noms de variables dans l'index étaient occupés. De plus, d'un point de vue maintenance, cela pose également problème. Si je ne vous le dis pas à l'avance, ou si vous ne lisez pas le mixin et a à l'avance, savez-vous d'où vient le $color dans l'index. ? Supposons que nous ayons besoin de la taille de la police, savez-vous quel fichier modifier ? De plus, comment vous assurer que lorsque vous référencez mixin et a en même temps, est-il possible qu'il y ait une variable du même nom entre eux ? Alors qui couvre qui ? Ces problèmes peuvent sembler minimes, mais lorsque l’ampleur de votre projet est importante, cela peut être un désastre irréversible (à qui faites-vous peur ???).

Scénario 2 : Supposons que notre projet ait une couleur de thème. La bordure, l'arrière-plan des onglets, l'arrière-plan de la barre de navigation, la couleur de la police, etc. sont tous cette couleur de thème. Pour plus de commodité, nous ne souhaitons pas toujours utiliser le sélecteur de couleurs. récupérons la valeur, nous définissons donc une variable globale $color: #ff9900 dans le mixin, et vous pourrez ensuite l'utiliser partout !

Après le développement de l'ensemble du site Web, un mois plus tard, le concepteur est soudainement venu vous dire : « Le patron a dit que la couleur de ce thème devait être changée. C'est un peu terreux. Changeons-la en rouge vif. Alors vous avez regardé. réticent mais secrètement ouvert avec joie dans votre cœur, changez la valeur de $color en rouge vif, puis dites fièrement au concepteur : "Heureusement, je l'ai préparé, et c'est fait. Jetez un oeil." , ouvrez la page et voyez, le concepteur et votre Mon visage est tout vert, pourquoi la page est-elle si moche Certains mots étaient à l'origine dans la couleur du thème, mais l'arrière-plan était rouge, mais maintenant après l'avoir modifié, tout le bloc est devenu ? rouge, et le contenu n'est pas visible clairement. Certaines bordures étaient à l'origine rouges, mais la police est la couleur du thème d'origine, mais maintenant elle a été modifiée et la bordure et la police sont devenues rouges.

Designer : "Non, non, non, je veux juste changer la couleur du fond."
Vous : "Tu n'as pas dit de changer la couleur du thème ? C'est tous les endroits
." Concepteur : "Non, changez simplement l'arrière-plan."
Vous : "Pas question..."
Concepteur : "Pourquoi pas ? Pourquoi ne pas simplement changer la couleur d'arrière-plan ? Changez-la simplement en fonction de la façon dont vous l'avez définie
." Vous : "Ce n'est pas aussi simple que tu le penses..."

……

D'accord, je suis juste là pour t'effrayer. Si tu es vraiment bon dans ce domaine, ce ne sera pas grave.

Nous devons donc gérer les variables (globales), tout comme nous avons géré les mixins. Nous ne pouvons pas les définir où nous voulons, ni modifier une variable globale à chaque tour :

  1. . Les variables globales ne sont définies que dans le mixin. Les variables définies dans d'autres fichiers scss (qu'elles soient exposées au global ou au local) sont uniquement considérées comme des variables locales et ne sont pas utilisées en dehors du fichier actuel (même si elles peuvent être référencées, évitez de les utiliser) ;


  2. Là où des variables globales doivent être utilisées, importez directement le mixin


  3. D'une manière générale, les variables globales doivent être définies avec prudence, et le nombre de variables globales doit être aussi petit que possible


  4. Gardez-le aussi inchangé que possible. Si les exigences changent, à moins que le but ne soit très certain, veuillez ajouter une variable globale pour remplacer progressivement les parties qui doivent être modifiées

  5. ;

  6. N'utilisez pas de noms trop généraux comme variables globales, tels que couleur. Il est recommandé d'utiliser directement la description de la valeur de couleur, telle que $orange : #ff9900. Cela nous permet de maintenir et de développer plus facilement la valeur de couleur. doit être modifié, mais ce n'est pas le cas. Tous les endroits doivent être modifiés, nous pouvons alors définir une nouvelle variable pour la développer, comme $red: red.

Ces points semblent un peu erratiques. En fait, il est vraiment difficile d'expliquer pourquoi nous devrions faire cela. Après tout, ce sont tous des résumés d'expériences, donc autant vous familiariser avec l'utilisation de Sass pendant un certain temps avant d'y penser. ces questions en détail.

Notez que les règles ci-dessus ne sont pas rigides. À un moment donné, cette spécification doit être ajustée en fonction de projets réels, comme le SPA dont nous parlerons plus tard. Il n'existe pas de projet parfait, ni de modèle de développement applicable à tous les projets. Ce n'est qu'en adaptant les mesures aux conditions locales que nous pourrons mieux résoudre les problèmes. De plus, aucun des problèmes que nous avons évoqués jusqu’à présent n’est fatal. Les problèmes fatals ont été évités lorsque nous avons formulé les spécifications de la section précédente.

Module d'appel

Question, où appeler le module ?

Réponse, page scss.

在页面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的工作来回答,从某种意义上讲,模块化提高了我们编程能力和解决问题的能力,使得构建一个庞大而可扩展可维护的项目成为可能,使得我们能够以架构的思维和眼光去搭建整个项目。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn