CSS 幕后解析
概述
层叠与优先级
数值处理
继承
盒模型
架构、组件与 BEM 命名法
项目的可维护性与可扩展性应满足这些要求:
- 干净
- 模块化
- 可重用
- 可扩展
具体来说,工作流应呈现以下形态:
- THINK
- BUILD
- ARCHITECT
THINK | 布局与组件设计
BUILD | 使用 BEM 命名法
ARCHITECT | 使用 7-1 设计模式
7-1 设计模式为基于 CSS 预处理器(后面的章节将介绍 SASS 预处理器)的前端设计提供了一种文件布局思路,目的在于提升代码的可重用性、可维护性可扩展性。
具体来说,所有 Sass 文件均放在 sass/
目录内,其中包含:
- 7 个子文件夹,用于定义各类组件。
- 1 个
main.scss
文件用于导入与组织 7 个文件夹内的组件,并编译成最终的css/style.css
文件。
这 7 个文件夹的名称和功能分别为:
base/
定义页面的基本元素属性,如:_base.scss
:定义html
、body
等元素的基本属性,响应式设计的设置等。_typography.scss
:定义排版、标题的样式。_utilities.scss
:各种工具类,如margin-bottom-sm
、grid-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:
$color-primary: #f9ed69; .navigation { background-color: $color-primary; display: flex; list-style: none; }
- CSS:
.navigation { background-color: #f9ed69; display: flex; list-style: none; }
选择器可以嵌套:
- SCSS:
.navigation { display: flex; list-style: none; li { text-decoration: none; } }
- CSS:
.navigation { display: flex; list-style: none; } .navigation li { text-decoration: none; }
Mixin、Extend 与 Function
Mixin 将可重用的若干属性封装在特定代码块内,可用 @include
调用:
- SCSS:
@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:
.heading-primary { font-size: 5.2rem; letter-spacing: -0.2rem; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
Extend 同样用于封装代码,与 Mixin 不同之处在于,其声明名称被替换为 使用 @extend
引用处的选择器,便于设置多个类的共有默认属性,同时避免覆盖各自的客制化属性设置:
- SCSS:
$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:
.btn--sub, .btn--main { padding: 1.2rem 2.4rem; border-radius: 100rem; } .btn--main { background-color: #f9ed69; } .btn--sub { background-color: #f08a5d; }
SASS 可以定义和使用函数:
- SCSS:
@function divide($a, $b) { @return $a / $b; } nav { margin: divide(60, 2) * 1px; }
- CSS:
nav { margin: 30px; }
Minix 中亦可以使用变量:
- SCSS:
$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:
a { text-decoration: none; padding: 1.2rem 2.4rem; background-color: #f9ed69; border-radius: 100rem; display: inline-block; }
NPM 包管理器
安装 Node.js
使用 NPM 配置 SASS 环境
初始化 Node.js 环境:
npm init
根据提示配置参数即可。
安装
node-sass
预处理器:npm install node-sass --save-dev
由于这是在开发环境下使用
node-sass
,当工作环境迁移时,我们不可能将生成的node_modules
一并拷贝或加入commit
,因此我们需要添加--save-dev
参数,将node-sass
添加为依赖项,之后在其他设备上进行开发时,只需要输入:npm install node-sass --save-dev
即可从
npm
镜像源安装所有依赖项。添加 SCSS 编译脚本
在
package.json
里找到"scripts"
字段,修改成如下形式:"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "compile:sass": "node-sass sass/main.scss css/style.css -w" },
此处定义了一个
complie:sass
脚本,你可以通过:npm run compile:sass
来运行此脚本。
sass/main.scss
与css/style.css
分别是编译的源文件和目标文件。-w
参数用于监听 SASS 组件的更新情况,每次更新.scss
文件都会重新编译。
float-clearfix hack
布局
flex
布局
grid
布局
响应式设计
先决条件
SASS 中的 @media
也可以嵌套:
- SCSS:
html { @media (max-width: 1200px) { font-size: 62.5%; } }
- CSS:
@media (max-width: 1200px) { html { font-size: 62.5%; } }
使用 @include
调用 Mixin 代码块时, @content
将被替换成调用处的代码块:
- SCSS:
@mixin respond-phone { @media (max-width: 600px) { @content } } html { @include respond-phone { font-size: 50%; } }
- CSS:
@media (max-width: 600px) { html { font-size: 50%; } }
if
语句用于选择性替换内容:
- SCSS:
@mixin respond($breakpoint) { if $breakpoint == phone { font-size: 50%; } } html { @include respond(phone); }
- CSS:
html { font-size: 50%; }
使用 SASS 快速实现响应式设计
在 abstracts/mixins
内声明:
/*
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
为例:
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
}
}