Version: Next

SASS 是个啥

  • 简单地说,就是有变量、函数、分支等功能的 CSS
  • 最后需要编译成基本 CSS

安装

  • 百度

编译 SASS

  • SASS 文件 .scss 类型
sass {文件名}:{目标路径}
sass ./style.scss:../css/style.css

自动编译

sass --watch sass:css
  • 监视名为 sass 的文件夹,一旦发生改变,就把里面的东西编译好,放到 css 文件夹

SASS 编译输出 CSS 格式

共 4 种

  • nested 嵌套
  • compact 紧凑
  • expanded 扩展
  • compressed 压缩

了解

  • webpack 等构建工具会自动做这个事

nested 嵌套

默认嵌套

举例:

  • sass 代码
ul {
font-size: 15px;
li {
list-style: none;
}
}
  • 编译后
ul {
font-size: 15px; }
ul li {
list-style: none; }
/*# sourceMappingURL=style.css.map */

compact 紧缩

暂停自动编译,执行下列命令,修改 style

sass --watch sass:css --style compact
  • 编译后
ul { font-size: 15px; }
ul li { list-style: none; }
/*# sourceMappingURL=style.css.map */

expanded 扩展 (最常用)

修改方法类比 compact

ul {
font-size: 15px;
}
ul li {
list-style: none;
}
/*# sourceMappingURL=style.css.map */

compressed 压缩

修改方法类比 compact

  • 编译后
ul{font-size:15px}ul li{list-style:none}
/*# sourceMappingURL=style.css.map */

.sass 与 .scss 的区别

  • sass : 就 sass
    • 缩进式,代码规则不严格
  • scss : Sassy CSS
    • 更像传统编程语言

变量

定义变量

  • $,赋值号为 :,结尾要有 ;
$primary-color: #1269b5;
$primary-color: #1269b5;
$primary-border: 1px solid $primary-color;
div.box {
background-color: $primary-color;
}
h1.page-header {
border: $primary-border;
}
div.box {
background-color: #1269b5;
}
h1.page-header {
border: 1px solid #1269b5;
}
/*# sourceMappingURL=style.css.map */

nested 嵌套

  • 用于重复出现某些标签的场景
  • 例如:导航栏 -- 导航栏里的无序列表 -- 导航栏里无序列表里的列表项
    • 那么 可以按照 导航栏 -- 无序列表 -- 列表项 的形式嵌套书写
.nav {
height: 100px;
ul {
margin: 0;
li {
float: left;
list-style: none;
padding: 5px;
}
}
}
.nav {
height: 100px;
}
.nav ul {
margin: 0;
}
.nav ul li {
float: left;
list-style: none;
padding: 5px;
}
/*# sourceMappingURL=style.css.map */

嵌套时调用父选择器

默认情况下嵌套之间用的是 空格

  • 场景 如果我想用 a:hover,那编译之后会变成 a :hover 多了个空格
  • 这种情况可以在嵌套时,加一个 & 符号,就可以直接拼接父选择器,没有 空格
.nav {
height: 100px;
ul {
margin: 0;
li {
float: left;
list-style: none;
padding: 5px;
}
a {
display: block;
color: #000;
padding: 5px;
&:hover {
background-color: #0d2f7e;
color: #fff;
}
}
}
& &-text {
font-size: 15px;
}
}
.nav {
height: 100px;
}
.nav ul {
margin: 0;
}
.nav ul li {
float: left;
list-style: none;
padding: 5px;
}
.nav ul a {
display: block;
color: #000;
padding: 5px;
}
.nav ul a:hover {
background-color: #0d2f7e;
color: #fff;
}
.nav .nav-text {
font-size: 15px;
}
/*# sourceMappingURL=style.css.map */

嵌套属性

body {
font-family: Arial, Helvetica, sans-serif;
font-size: 15px;
font-weight: normal;
}
.nav {
border: 1px solid #000;
border-left: 0;
border-right: 0;
}
  • 其中,fontborder 这两个词在重复出现
  • 可以用 xxx : {} 的格式来写
body {
font: {
family: Arial, Helvetica, sans-serif;
size: 15px;
weight: normal;
}
}
.nav {
border: 1px solid #000;
border: {
left: 0;
right: 0;
}
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 15px;
font-weight: normal;
}
.nav {
border: 1px solid #000;
border-left: 0;
border-right: 0;
}
/*# sourceMappingURL=style.css.map */

函数——mixin 混合

可以把 mixin 想象成一块 定义好的有名字的 样式

  • 函数
@minxin 函数名 (参数1, 参数2) {
}
  • 调用语法:@include 函数名()@include 函数名
@mixin alert {
color: #fff;
background-color: #001;
a {
color: mediumaquamarine;
}
}
.alert-warning {
@include alert();
}
.alert-warning {
color: #fff;
background-color: #001;
}
.alert-warning a {
color: mediumaquamarine;
}
/*# sourceMappingURL=style.css.map */

参数

@mixin alert($text-color, $background) {
color: $text-color;
background-color: $background;
a {
color: darken($text-color, 10%);
}
}
.alert-warning {
@include alert(rgb(63, 131, 131), #fff);
}
  • darken() 函数用来计算指定颜色,加深 10% 后的颜色
.alert-warning {
color: #3f8383;
background-color: #fff;
}
.alert-warning a {
color: #2e6161;
}
/*# sourceMappingURL=style.css.map */

也可以在调用时,指定形参,和 python 一样的

@mixin alert($text-color, $background) {
color: $text-color;
background-color: $background;
a {
color: darken($text-color, 10%);
}
}
.alert-warning {
@include alert($background: rgb(63, 131, 131), $text-color: #fff);
}
.alert-warning {
color: #fff;
background-color: #3f8383;
}
.alert-warning a {
color: #e6e6e6;
}
/*# sourceMappingURL=style.css.map */

继承 —— inheritance

  • @extend
    • 用来让一个 选择器,继承 另一个选择器 所有的 样式
.alert {
padding: 15px;
}
.alert-info {
@extend .alert;
background-color: aqua;
}
.alert, .alert-info {
padding: 15px;
}
.alert-info {
background-color: aqua;
}
/*# sourceMappingURL=style.css.map */

注意:父选择器相关的子选择器也会被继承过来

  • 注意看 .alert a,它编译之后多出了 .alert-info a
.alert {
padding: 15px;
}
.alert a {
font-weight: bold;
}
.alert-info {
@extend .alert;
background-color: aqua;
}
.alert, .alert-info {
padding: 15px;
}
.alert a, .alert-info a {
font-weight: bold;
}
.alert-info {
background-color: aqua;
}
/*# sourceMappingURL=style.css.map */

partials 与 @import

用来在 css 中导入其他 css

  • 原生 import 都会发送一个 http 请求
  • @import 会把小 scss 编译成一个大的 css,这样请求数量就少了,每一个这样的小 scss 称为一个 partials
    • 作为 partials 的 scss 文件,名字以 _ 开头 ,这样 sass 默认就不会单独去编译它们

案例

  • 新建一个文件 _base.scss
body {
margin: 0;
padding: 0;
}
  • style.scss 中用 @import 导入
  • 直接写 "base" 就好,省略 下划线.scss
  • 对于不同路径的文件,需要指定一下相对路径
@import "base";
.alert {
padding: 15px;
}
body {
margin: 0;
padding: 0;
}
.alert {
padding: 15px;
}
/*# sourceMappingURL=style.css.map */

注释

  • // 单行,编译后就没了
  • /**/ 多行,在 expanded 模式下会保留,在压缩模式下就没了
  • /*! */ 强制多行:编译后也不会被干掉

数据类型

  • 5 数字
  • hello 字符串
  • "hello" 字符串
  • 1px solid #000 list,用 空格 或者 , 分开的就是 list
  • #ff0000 color
  • red color
  • rgb(255, 0, 0) color

数字

  • 可以携带 单位 进行计算
    • 5px + 5px
    • 5px - 3

大坑:乘法 5px 5px = 25pxpx,单位也会乘了,而且这个单位不能用

  • 应该写 5px * 5

大坑:除法 5px / 5px = 1,单位也会除了,除完单位没了

  • 应该写 (5px / 5)

  • 除法

    • 8 / 4 不会被计算,而是被当作一个 分式
    • 要计算的话需要写 (8 / 4)

内置数字函数

  • abs() 绝对值
  • round 四舍五入
  • ceil 向上取整
  • floor 向下取整
  • percentage(650px / 1000px) 输出 65%
  • min
  • max

字符串

  • + 号 拼接
  • -/ 作用于字符串也会拼接,并且 - / 自己也会被拼进去
  • * 会报错

内置字符串函数

  • to-upper-case
  • to-lower-case
  • str-length
  • str-index(source, target) 返回 target字符串 在 source 字符串中的起始下标,下标从 1 开始
  • str-insert(目标字符串, 插入新内容字符串, 插入位置下标)

颜色

  • rgb(红, 绿, 蓝) 0~255
  • rgba,a 是不透明度 0~1.0
  • hsl()——色相 饱和度 明度
  • hsla()——色相 饱和度 明度 不透明读
  • adjust-hue 调整 色相
  • lighten 让指定颜色变明亮
  • darken 让之地那个颜色变暗
  • saturate 增加饱和度
  • desaturate 降低饱和度
  • transparentize 让颜色更透明
  • opacify 增加颜色不透明度

列表

空格 或者 , 分开

  • 1px solid #fff
  • a, b, c
  • 可以多个列表组成一个列表
    • 5px 10px, 5px 0
    • 其中 5px 10px 是一个列表, 5px 0 是另一个列表
    • 也可以写成 (5px 10px)(5px 0)

内置列表函数

  • length(列表)
  • nth(列表, 下标) 获取指定下标的元素
  • index(1px solid red, solid) 获取指定元素对应的下标
  • append(原列表,新项目) 在列表后面追加元素
  • join(列表1, 列表2, 分隔符) 拼接两个列表

map

带名字的 list

$map: (k1: v1, k2: v2...)
$colors:(light:#ffffff, dark:#000000);
  • list 的一些函数它也能用,例如获得长度

内置 map 函数

  • map-get(map名字,Key) 返回 Value
  • map-keys(map名字),返回指定 map 的 key 组成的列表,类似 keySet
  • map-values 返回 valueSet
  • map-has-key(map名,key) containsKey,返回 boolean
  • map-merge(map1, map2) 合并 map
  • map-remove(map,keys....) 用key删除元素,keys 是可变长参数

布尔

  • 看起来跟 python 是对应的
  • true 和 false
  • < >
  • and or not

Interpolation

  • 占位符
  • 一个变量,在 位置可以直接被调用
  • 属性名 位置不能直接被调用,必须用 #{$xxx} 来调用

场景:在注释中插入一个变量

$version: "0.0.1";
/* 版本号 #{$version} */
@charset "UTF-8";
/* 版本号 0.0.1 */
/*# sourceMappingURL=style.css.map */

场景:在选择器,属性中使用

$version: "0.0.1";
/* 版本号 #{$version} */
$name: "info";
$attr: "border";
.alert-#{$name} {
#{$attr}-color: #ccc;
}
@charset "UTF-8";
/* 版本号 0.0.1 */
.alert-info {
border-color: #ccc;
}
/*# sourceMappingURL=style.css.map */

控制指令

@if

@if 条件 {
}
@if 条件 {
} @else if 条件 {
} @else {
}
$use-prefixes: false;
.rounded {
@if $use-prefixes {
color: red;
}
border-radius: 5px;
}
.rounded {
border-radius: 5px;
}
/*# sourceMappingURL=style.css.map */
  • 改为 true
$use-prefixes: true;
.rounded {
@if $use-prefixes {
color: red;
}
border-radius: 5px;
}
.rounded {
color: red;
border-radius: 5px;
}
/*# sourceMappingURL=style.css.map */

@for

@for $var from <初始值> through <结束值> {
}
@for $var from <初始值> to <结束值> {
}
  • through 闭区间
  • to 开区间
$colums: 4;
@for $i from 1 through $colums {
.col-#{$i} {
width: 100% / $colums * $i;
}
}
.col-1 {
width: 25%;
}
.col-2 {
width: 50%;
}
.col-3 {
width: 75%;
}
.col-4 {
width: 100%;
}
/*# sourceMappingURL=style.css.map */

@each

增强 for 循环

@each $var in $list {
}
$icons: success error warning;
@each $icon in $icons {
.icon-#{$icon} {
background-image: url(../images/icons/#{$icon}.png);
}
}
.icon-success {
background-image: url(../images/icons/success.png);
}
.icon-error {
background-image: url(../images/icons/error.png);
}
.icon-warning {
background-image: url(../images/icons/warning.png);
}
/*# sourceMappingURL=style.css.map */

@while

@while 条件 {
}
$i: 6;
@while $i > 0 {
.item-#{$i} {
width: 5px * $i;
}
$i: $i - 2;
}
.item-6 {
width: 30px;
}
.item-4 {
width: 20px;
}
.item-2 {
width: 10px;
}
/*# sourceMappingURL=style.css.map */

用户自定义函数 function

@function 名称 (参数1, 参数2) {
}
$colors: (light: #ffffff, dark: #000000); // 这是个 map
@function color($key) {
@return map-get($colors, $key);
}
body {
background-color: color(light); // 此处的 light 是个字符串,进入 color 函数后会被当成 key
}
body {
background-color: #ffffff;
}
/*# sourceMappingURL=style.css.map */

警告与错误

  • @warn —— 不会报错,警告信息会出现在 cmd 中
  • @error —— 会直接报错推出,编译失败
$colors: (light: #ffffff, dark: #000000); // 这是个 map
@function color($key) {
@if not map-has-key($colors, $key) {
@warn "$colors 中没这个 #{$key} key"; // 会显示在Cmd中
}
@return map-get($colors, $key);
}
body {
background-color: color(light1); // 此处的 light 是个字符串,进入 color 函数后会被当成 key
}
$colors: (light: #ffffff, dark: #000000); // 这是个 map
@function color($key) {
@if not map-has-key($colors, $key) {
@error "$colors 中没这个 #{$key} key"; // 会显示在Cmd中
}
@return map-get($colors, $key);
}
body {
background-color: color(light1); // 此处的 light 是个字符串,进入 color 函数后会被当成 key
}