CSS 幕后解析

概述

层叠与优先级

数值处理

继承

盒模型

架构、组件与 BEM 命名法

项目的可维护性与可扩展性应满足这些要求:

  • 干净
  • 模块化
  • 可重用
  • 可扩展

具体来说,工作流应呈现以下形态:

  1. THINK
  2. BUILD
  3. ARCHITECT

THINK | 布局与组件设计

BUILD | 使用 BEM 命名法

ARCHITECT | 使用 7-1 设计模式

7-1 设计模式为基于 CSS 预处理器(后面的章节将介绍 SASS 预处理器)的前端设计提供了一种文件布局思路,目的在于提升代码的可重用性、可维护性可扩展性。

具体来说,所有 Sass 文件均放在 sass/ 目录内,其中包含:

  • 7 个子文件夹,用于定义各类组件。
  • 1main.scss 文件用于导入与组织 7 个文件夹内的组件,并编译成最终的 css/style.css 文件。

7 个文件夹的名称和功能分别为:

  • base/
    定义页面的基本元素属性,如:
    • _base.scss:定义 htmlbody等元素的基本属性,响应式设计的设置等。
    • _typography.scss:定义排版、标题的样式。
    • _utilities.scss:各种工具类,如 margin-bottom-smgrid-vertical-center 等。
  • components/
    定义各类原子组件的样式等,如:
    • _btn.scss:页面按钮样式。
  • layout/
    定义页面的布局设置:
    • _grid.scss:网格系统。
  • pages/
    针对每个页面各自布局的特化设置:
    • _home.scss:主页。
  • themes/
  • abstracts/
    包含各类常量与可重用样式:
    • variables:颜色,字体,间隔设置等。
    • mixins:各种 mixins 的定义。
    • functions:各种 functions 的定义。
  • vendors/
    包含可能用到的外部库。

SASS 与 NPM 简介

SASS 预处理器

SASS 是一种 CSS 预处理器,即对原生 CSS 语法进行扩展,使之具备比 CSS 更强的表达能力,然后编译成标准 CSS ,便于写出简洁明了、可维护性与可扩展性更强的代码。

变量与嵌套

重复出现的值可以通过变量来定义:

  • SCSS:
    1
    2
    3
    4
    5
    6
    $color-primary: #f9ed69;
    .navigation {
    background-color: $color-primary;
    display: flex;
    list-style: none;
    }
  • CSS:
    1
    2
    3
    4
    5
    .navigation {
    background-color: #f9ed69;
    display: flex;
    list-style: none;
    }

选择器可以嵌套:

  • SCSS:
    1
    2
    3
    4
    5
    6
    7
    .navigation {
    display: flex;
    list-style: none;
    li {
    text-decoration: none;
    }
    }
  • CSS:
    1
    2
    3
    4
    5
    6
    7
    .navigation {
    display: flex;
    list-style: none;
    }
    .navigation li {
    text-decoration: none;
    }

Mixin、Extend 与 Function

Mixin 将可重用的若干属性封装在特定代码块内,可用 @include 调用:

  • SCSS:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @mixin absCenter {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    }

    .heading-primary {
    font-size: 5.2rem;
    letter-spacing: -0.2rem;
    @include absCenter;
    }
  • CSS:
    1
    2
    3
    4
    5
    6
    7
    8
    .heading-primary {
    font-size: 5.2rem;
    letter-spacing: -0.2rem;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    }

Extend 同样用于封装代码,与 Mixin 不同之处在于,其声明名称被替换为 使用 @extend 引用处的选择器,便于设置多个类的共有默认属性,同时避免覆盖各自的客制化属性设置:

  • SCSS:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    $color-primary: #f9ed69;
    $color-secondary: #f08a5d;

    %btn--placeholder {
    padding: 1.2rem 2.4rem;
    border-radius: 100rem;
    }

    .btn--main {
    background-color: $color-primary;
    @extend %btn--placeholder;
    }

    .btn--sub {
    background-color: $color-secondary;
    @extend %btn--placeholder;
    }
  • CSS:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    .btn--sub, .btn--main {
    padding: 1.2rem 2.4rem;
    border-radius: 100rem;
    }

    .btn--main {
    background-color: #f9ed69;
    }

    .btn--sub {
    background-color: #f08a5d;
    }

SASS 可以定义和使用函数:

  • SCSS:
    1
    2
    3
    4
    5
    6
    7
    @function divide($a, $b) {
    @return $a / $b;
    }

    nav {
    margin: divide(60, 2) * 1px;
    }
  • CSS:
    1
    2
    3
    nav {
    margin: 30px;
    }

Minix 中亦可以使用变量:

  • SCSS:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $color-primary: #f9ed69;
    @mixin style-link-text($color) {
    padding: 1.2rem 2.4rem;
    background-color: $color;
    border-radius: 100rem;
    display: inline-block;
    }

    a {
    text-decoration: none;
    @include style-link-text($color-primary);
    }
  • CSS:
    1
    2
    3
    4
    5
    6
    7
    a {
    text-decoration: none;
    padding: 1.2rem 2.4rem;
    background-color: #f9ed69;
    border-radius: 100rem;
    display: inline-block;
    }

NPM 包管理器

安装 Node.js

  • 直接去官网下载安装包安装,或者使用 NVM 创建虚拟 Node.js 环境即可。

  • 安装完成后注意环境变量设置,并检查一下环境:

    1
    node -v

使用 NPM 配置 SASS 环境

  • 初始化 Node.js 环境:

    1
    npm init

    根据提示配置参数即可。

  • 安装 node-sass 预处理器:

    1
    npm install node-sass --save-dev

    由于这是在开发环境下使用 node-sass ,当工作环境迁移时,我们不可能将生成的 node_modules 一并拷贝或加入 commit,因此我们需要添加 --save-dev 参数,将 node-sass 添加为依赖项,之后在其他设备上进行开发时,只需要输入:

    1
    npm install node-sass --save-dev

    即可从 npm 镜像源安装所有依赖项。

  • 添加 SCSS 编译脚本

    package.json 里找到 "scripts" 字段,修改成如下形式:

    1
    2
    3
    4
    "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "compile:sass": "node-sass sass/main.scss css/style.css -w"
    },

    此处定义了一个 complie:sass 脚本,你可以通过:

    1
    npm run compile:sass

    来运行此脚本。sass/main.scsscss/style.css 分别是编译的源文件和目标文件。 -w 参数用于监听 SASS 组件的更新情况,每次更新 .scss 文件都会重新编译。

float-clearfix hack 布局

flex 布局

grid 布局

响应式设计

先决条件

SASS 中的 @media 也可以嵌套:

  • SCSS:
    1
    2
    3
    4
    5
    html {
    @media (max-width: 1200px) {
    font-size: 62.5%;
    }
    }
  • CSS:
    1
    2
    3
    4
    5
    @media (max-width: 1200px) {
    html {
    font-size: 62.5%;
    }
    }

使用 @include 调用 Mixin 代码块时, @content 将被替换成调用处的代码块:

  • SCSS:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    @mixin respond-phone {
    @media (max-width: 600px) { @content }
    }

    html {
    @include respond-phone {
    font-size: 50%;
    }
    }
  • CSS:
    1
    2
    3
    4
    5
    @media (max-width: 600px) {
    html {
    font-size: 50%;
    }
    }

if 语句用于选择性替换内容:

  • SCSS:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @mixin respond($breakpoint) {
    if $breakpoint == phone {
    font-size: 50%;
    }

    }

    html {
    @include respond(phone);
    }
  • CSS:
    1
    2
    3
    html {
    font-size: 50%;
    }

使用 SASS 快速实现响应式设计

abstracts/mixins 内声明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
phone: 0 ~ 600px
tab-port: 600px ~ 900px
tab-land: 900px ~ 1200px
desktop(default): 1200px ~ 1800px
big-desktop: 1800px ~ infinity
*/

@mixin respond($breakpoint) {
@if $breakpoint == phone {
@media (max-width: 37.5em) { @content } //37.5em = 600px
}
@if $breakpoint == tab-port {
@media (max-width: 56.25em) { @content }//56.25em = 900px
}
@if $breakpoint == tab-land {
@media (max-width: 75em) { @content } //75em = 1200px
}
@if $breakpoint == big-desktop {
@media (min-width: 112.5em) { @content }//112.5em = 1800px
}
}

以选中 html 元素并响应式地设置 font-size 为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
html {
// define what 1rem is
font-size: 62.5%; //1rem = 16px * 62.5% = 10px

@include respond(phone) {
font-size: 37.5% //1rem = 16px * 37.5% = 6px
}

@include respond(tab-port) {
font-size: 50%; //1rem = 16px * 50% = 8px
}

@include respond(tab-land) {
font-size: 56.25% //1rem = 16px * 56.25% = 9px
}

@include respond(big-desktop) {
font-size: 75% //1rem = 16px * 75% = 12px
}
}

其他常用技巧