1.嵌套
1.1选择器嵌套
css中重复写选择器是非常恼人的。尤其是html结构嵌套非常深的时候,scss的选择器嵌套可以避免重复输入父选择器,可以有效的提高开发效率,减少样式覆盖可能造成的异常问题。这也是我们最常用的功能。
Scss写法:
.container {
width: 1200px;
margin: 0 auto;
.header {
.img {
width: 100px;
height: 60px;
}
}
}
css写法
.container {
width: 1200px;
margin: 0 auto;
}
.container .header .img {
width: 100px;
height: 60px;
}
1.2属性嵌套
有些css属性遵循相同的命名空间 (相同的开头),比如font-family,font-size,font-weight都以font作为属性的命名空间。为了便于管理这样的属性,也为了避免重复输入。
.container {
font: {
family: fantasy;
size: 30em;
weight: bold;
}
}
编译为css:
.container {
font-family: fantasy;
font-size: 30em;
font-weight: bold;
}
1.3父选择器&
在嵌套 css规则时,有时会需要使用嵌套外层的父选择器,例如,当给某个元素设定 hover 样式时,可以用& 代表嵌套规则外层的父选择器,scss在编译时会把&替换成父选择器名。
案例里面的&表示的就是父级a选择器
.container {
a {
color: #333;
&:hover {
text-decoration: underline;
color: #f00;
}
}
}
编译为css:
.container a {
color:#333;
}
.container a:hover {
text-decoration:underline;
color:#F00;
}
或者进行选择器名称拼接。
.main {
color: black;
&-sidebar { border: 1px solid; }
}
编译为css:
.main {
color: black;
}
.main-sidebar {
border: 1px solid;
}
2.变量
2.1 使用
原生css中的变量,使用--变量名:变量值定义,var(--变量名)进行使用。
:root {
--color: #F00;
}
p {
color: var(--color);
}
scss中的变量,以美元符号$开头,赋值方法与 css属性的写法一样。
$color:#F00;
p {
color: $color;
}
编译为css:
p {
color: #F00;
}
2.2 作用域
变量作用域分为全局变量域和局部变量域:
全局变量:声明在最外层的变量,可在任何地方使用;
局部变量:嵌套规则内定义的变量只能在嵌套规则内使用。
将局部变量转换为全局变量可以添加!global 声明。
$color: red;
.container {
$height: 500px;
$font-size: 16px !global;
font-size: $font-size;
color: $color;
height: $height;
}
.footer {
font-size: $font-size;
height:$height;
}
以上例子中$font-size使用!global 声明成全局变量了, 而$height是.container下的局部变量,无法在.footer下面编译
编译为css:
.container {
font-size: 16px;
color: red;
height: 500px;
}
.footer {
font-size: 16px;
}
3.插值语句#{}
通过 #{} 插值语句可以在选择器或属性名中使用变量:
$name: foo;
$attr: border;
p.#{$name} {
#{$attr}-color: blue;
}
编译为css:
p.foo {
border-color: blue; }
4.混合@mixin @include
混合指令(Mixin)用于定义可重复使用的样式,避免了使用无语意的 class,比如 .float-left。混合指令可以包含所有的 CSS 规则,绝大部分 Sass 规则,甚至通过参数功能引入变量,输出多样化的样式。
简而言之,当你的代码中需要用到大段大段重用样式代码的时候,可以通过 SCSS 的混合器实现大段样式的重用。混合器使用@mixin定义。
4.1定义
混合指令的用法是在 @mixin 后添加名称与样式,比如名为 large-text 的混合通过下面的代码定义:
@mixin large-text {
font: {
family: Arial;
size: 20px;
weight: bold;
}
color: #ff0000;
}
4.2 引用
混合指令的用法是在 @mixin 后添加名称与样式,比如名为 large-text 的混合通过下面的代码定义:
.page-title {
@include large-text;
padding: 4px;
margin-top: 10px;
}
编译为css:
.page-title {
font-family: Arial;
font-size: 20px;
font-weight: bold;
color: #ff0000;
padding: 4px;
margin-top: 10px; }
值得一提:混合可以用 & 引用父选择器,混合样式中也可以包含其他混合样式。
4.3 参数
参数用于给混合指令中的样式设定变量,并且赋值使用。在定义混合指令的时候,按照变量的格式,通过逗号分隔,将参数写进圆括号里。引用指令时,按照参数的顺序,再将所赋的值对应写进括号:
@mixin sexy-border($color, $width) {
border: {
color: $color;
width: $width;
style: dashed;
}
}
p { @include sexy-border(blue, 1in); }
也可以使用给变量赋值的方式设定默认值如:$width=lin
编译为css:
p {
border-color: blue;
border-width: 1in;
border-style: dashed; }
5.其他常用指令
5.1 @import
原生css 的 @import 规则是可以在一个 css 文件导入其他 css 文件,但是需要执行到它时才能触发浏览器去下载它所 import 来的 css 文件,导致页面加载起来特别慢,还不如直接在里面写一大坨标签的引入效率高。
与原生css对比,scss@import 的功能,允许其导入 SCSS 或 Sass 文件。被导入的文件将合并编译到同一个 CSS 文件中,另外,被导入的文件中所包含的变量或者混合指令 (mixin) 都可以在导入的文件中使用。
@import "foo.scss";
5.2 @use 私有成员 !default
5.2.1@use
从其他样式表加载mixin,function和变量,并将来自多个样式表的CSS组合在一起,@use可以看作是对@import的增强,相比@import,@use在项目中无论使用多少次,都只会被导入一次
// src/_corners.scss
$radius: 3px;
@mixin rounded {
border-radius: $radius;
}
// style.scss
@use "src/corners" as corners;
.button {
@include corners.rounded;
padding: 5px + corners.$radius;
}
5.2.2 定义私有成员
如果引入的模块内部有变量只想在模块内使用,可使用 - 或 _ 定义在变量头即可,类似函数定义中的private
base-style.scss:
//base-style.scss
$-font-size:14px;
* {
margin: 0;
padding: 0;
font-size: $-font-size;
color: #333;
}
index.scss:
//index.scss
@use "base-style" as baseStyle;
div {
font-size: baseStyle.$-font-size; /*报错*/
}
另外在index.scss中引入此scss文件,可省略后缀
5.2.3 定义默认值
通过 !default 能给变量定义默认值
base-style.scss:
//base-style.scss
$font-size:14px !default;
* {
margin: 0;
padding: 0;
font-size: $font-size;
color: #333;
}
index.scss:
//index.scss
@use "base-style" as baseStyle with($font-size: 20px);
div {
font-size: baseStyle.$font-size;
}
@use引入时可通过with(…)修改默认值
5.3 @while @if...
@if、@for...from...through...@each..in 、@while 用法很好理解 ,一些基础的控制指令,比如在满足一定条件时引用样式,或者设定范围重复输出格式。控制指令是一种高级功能,日常编写过程中并不常用到,主要与混合指令 (mixin) 配合使用,尤其是用在 Compass 等样式库中。
6.常用声明
6.1 !default
如果变量已经被赋值,不会再被重新赋值,但是如果变量还没有被赋值,则会被赋予新的值。如5.2所示。
6.2 !global
变量作用域分为 全局变量域和 局部变量域:
全局变量:声明在最外层的变量,可在任何地方使用;
局部变量:嵌套规则内定义的变量只能在嵌套规则内使用。
将局部变量转换为全局变量可以添加!global 声明。如2.2所示
6.3 !important(css)
!important,作用是提高指定样式规则的应用优先权(优先级)
.app {
color: red !important;
}
#app {
color: green;
}
以上代码最终结果为红色。
在 CSS 选择器中,ID 选择器 > 类选择器,比 ID 选择器还优先的是 !important。
.search-box {
width: 100%;
padding: 0 12px !important;
}
附:深度选择器:deep && scoped
scoped:
对于类似Vue3项目,只有一个页面,页面内容被拆分成了一个个组件,组件加载完成后,组件的样式也都加载在同一个页面内,所以这些组件的样式都可以看成全局样式,对其他组件都有效,要避免当前组件的样式对其他组件产生污染,就要把每个组件的样式独立开。
<style lang="scss" scoped>
:deep
deep是常用来样式穿透,覆盖子组件加了scoped的样式或者第三方组件的样式。
我们在开发vue项目时,通常需要引用了第三方库,例如elementui;如果我们在某个页面中使用了elementui的组件,然后我们需要修改组件中对应元素的样式,这时就可以使用深度选择器
:deep(.actions .el-form-item__content){
justify-content: flex-end;
}
修改上面的代码,使用深度选择器:deep()进行选择可以达到想要的效果