前言
因为刚刚自己前段学完SCSS,故写篇博客,来再次复习一哈。 看完这篇文章你将会学到:
- 如何快速配置SCSS环境
- SCSS的基础语法
- SCSS响应式
- 你会发现Less、Stylus、Sass/SCSS 基本差不多学会一个,学其他的就很快
SASS/SCSS文档
以下只说部分语法,更多语法请查看 👉🏻 中文文档
配置环境
默认是已经装了 node npm/yarn
mkdir sass-v1
cd sass-v1
npm init -y
npm i -D parcel
npx parcel index.html
本文用parcel代替Webpack,它不需要任何配置就能使用Webpack功能的一个工具 如果觉得复杂可以用 codepen 在线写代码
CSS和SCSS的区别
header {
color: red;
font-size: 18px;
}
header {
color: red;
p {
font-size: 18px;
}
}
SCSS的基础语法
<nav>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</nav>
$grey: #ccc;
$gray: $grey;
$border-width: 2px;
// $border-color: red 默认red
@mixin debug($border-color: red) {
border: 1px solid $border-color;
// background: $gray;
}
// 把一些好用的、常用的代码放到这里 placeholder
%box {
box-shadow: 0 0 2px #ccc;
}
nav {
@include debug; // 机械的把代码考过来
> ul {
background: white;
background: $gray;
@include debug(red); // 把代码拷过来
> li {
@include debug(green); // 拷贝样式
@extend %box; // 这个的意思是把 li 放到%box 那里(考到%box里),不拷贝样式而是把选择器提到样式的前面
}
}
}
选择器扩展
BEM命名法
Block Element Modifier
block: 主要名词 user-card
element: div里的哥哥元素 user-card__name
modifier: 某一个元素的不同状态 user-card--active
优化
啰嗦的BEM命名法: .user-card__picture--active
优化后的: .userCard-picture .active
class = "userCard-picture active"
嵌套的选择器
nav {
font-size: 24px;
> ul {
background: red;
> li {
background: pink;
}
}
}
& 符号
<div class="userCard">
<div class="userCard-name">你好</div>
<div class="userCard-picture"> 嗯嗯安啊
<div class="userCard-picture-hhh">
hellow
<ul class="userCard-picture-hhh-j">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
</div>
<div class="userCard-content"></div>
</div>
.userCard {
width: 100px;
// 写成 .active 表示你是.userCard里面的后代元素, &.active 表示ta自己被激活
&.active { // 转成CSS是 .userCard.active 如果 .userCard 拥有 .active 这么个类,它的背景就是黄色
background: yellow;
}
// & 指的是当前所属的选择器
&-picture {
background-color: $grey;
}
&-name {
$red: #f60;
background: {
color: #bd1000;
}
font: {
size: 20px;
weight: bold;
}
color: blue;
&:hover {
color: $red;
}
}
&-picture {
$red: #bd1000;
&:hover{
color: $red;
}
&-hhh {
background: aqua;
&-j {
margin: 0;
padding: 0;
list-style: none;
li {
color: $red;
}
}
}
}
&-content {
$pink: pink;
$width: 250px;
// 符合预期的 1:1 div
width: $width;
margin-top: $width / 2;
height: $width;
border-radius: $width / 2;
border: 1px solid $gray;
background-color: change-color($color: $pink, $green: 255);
&:hover {
background: {
color: $pink;
}
}
}
}
嵌套属性
// 加了冒号
font: {
size: 24px;
weight: bold;
family: monospace;
}
background: {
color: $pink;
image: url(../img/btn.jpg);
}
注释
单行 // 多行 /* */
变量
$grey: #ccc; // 把#ccc赋值给 变量 $grey
$gray: $grey; // $grey === $gray 为了防止自己拼错
$width: 1px;
> ul {
$grey: red; // 变量可以有作用域,在这个作用域中是 red ,后面加 !global 就是全局声明
border: 1px solid $grey;
> li {
$width: 120px; // 可以做一个符合自己预期 1:1 的 div
width: $width;
height: $width;
}
}
一个属性放在多个地方,可以全局的改,可以让不同的变量是同一个,如果有多个$red,就采用就近原则。
SCSS里面的 - 和 _ 不会报错。
mixin
案例一
// $border-color: red 参数默认red
@mixin debug($border-color: red) {
border: 1px solid $border-color;
// 把一堆代码放到mixin里
}
nav {
@include debug; // include的特点是机械的把代码考过来,$border-color默认的值是 red
> ul {
$grey: #red // 变量可以有作用域,在这个作用域中是 red
background: white;
background: $gray;
@include debug(pink); // 将pink这个参数传给$border-color,把代码拷过来
> li {
@include debug(green); // 拷贝样式,传参数 green
}
}
}
案例二
@mixin box($width: 100px, height: 100px) {
box-shadow: 0 0 5px black;
margin: 10px;
width: $width;
height: $height;
}
.smallBox {
@include box(); // 使用默认的
}
.bigBox {
@include box(300px, 300px);
}
article {
> section {
.textAside {
@include box(20px, 20px)
}
}
}
placeholder
// 把一些好用的、常用的代码放到这里 placeholder,占位符选择器,把使用@extend %box的选择器提到这里
%box {
box-shadow: 0 0 2px #ccc;
}
nav {
> ul {
background: white;
background: $gray;
> li {
@extend %box; // extend的意思是把你的选择器复制到前面去(article,li) 这个的意思是把 li 放到%box 那里(考到%box里),不拷贝样式而是把选择器提到样式的前面
}
}
}
placeholder它可以是的我们的代码更加简洁
运算
$width: 300px;
=>width: $width/3;
width: (300px/3)
width: 300px/3 - 0
用来做奇偶性,width: 100%3px
=> 1pxcolor: $red + #888
color: change-color($color: $red, $green: 255)
color: fade-out($color: $red, $amount: 0.5)
=>fade-out($red, 0.5)
字符串差值
$red: #f60;
&::before {
content: '「 #{$red}'; // #{}的意思就是把 $red的值赋值过来
}
&::after {
content: '」';
}
@keyframes
案例一
@keyframes x {
10% {
color: red;
}
20% {
color: red;
}
30% {
color: red;
}
40% {
color: red;
}
50% {
color: red;
}
}
变成SCSS👇
$z: 10%;
@keyframes x {
@for $i from 1 to 6 {
#{$i * $z} {
color:red;
}
}
}
案例二
@keyframes x2 {
0% {
transform: translateX(-$n);
}
25% {
transform: translateX($n);
}
50% {
transform: translateX(-$n);
}
75% {
transform: translateX($n);
}
100% {
transform: translateX(0);
}
}
变成SCSS👇
$step: 25%;
@keyframes x2 {
@for $i from 0 to 4 {
#{$i * $step} {
@if $i % 2 == 0 {
transform: translateX(-$n);
} @else {
transform: translateX($n);
}
}
}
100% {
transform: translateX(0);
}
}
思考
如何放弃px、%,使用 vw(页面宽度)计算,它所有的宽度都以页面宽度的基准来算 设计师给的设计图以不同手机的宽为基准的话,你得去一个个算,好麻烦=-=,那该如何解决呢🤔?使用函数👇
function
@function px($npx) {
@return $npx/375 * 100vw; // 以375宽的屏幕为基准算
// @return $value/2 + px; 把单位缩小50%
}
.icon {
width: px(70); // 70为设计图宽
height: px(70);
}
对某个东西统一计算 function ,复用属性值的计算逻辑的
vw的兼容性有些许差,如图👇
SCSS响应式
- 使用 vw 来进行动态缩放
- 使用函数将 px => vw 的计算过程简化
@function px($npx) {
@return $npx/375 * vw;
}
- 使用flex布局(加一个flex-shrink: 0: 不会变形)
media 媒体查询
@media(max-width: 500px) {
> ul {
display:none
}
.menu {
display: blockl;
}
}
通过mixin简化
// 定义
@mixin phone {
@media (max-width: 500px) {
@concent;
}
}
@mixin ipad {
@media(min-width:501px) and (max-width: 1024px) {
@concent;
}
}
@mixin pc {
@media(min-width:1025px){
@content;
}
}
// 使用
@include phone {
//这里面是@content
> ul {
display: none;
.menu {
display: block;
}
}
}
@include ipad { }
@include pc {}
🌰
定义
@mixin df($fd:null,$jc:null,$ai:null,$as:null) {
display:flex;
flex-direction:$fd;
justify-content:$jc;
align-items:$ai;
align-self:$as;
}
调用
// 用谁调谁
@include df($jc:center,$ai:center)
h1 { font-size: 2em; } h2 { font-size: 1.5em; } h3 { font-size: 1.2em; }
// 使用以下写法就可以
@each $header, $size in (h1: 2em, h2: 1.5em, h3: 1.2em) {
#{$header} {
font-size: $size;
}
}
导入SCSS
@import "xxx";
@import "xxxx.scss";
以上两种方式都可以导入