CSS教程

CSS Sass/SCSS基础

CSS Sass/SCSS基础教程:变量、嵌套和混合

Sass/SCSS简介

Sass(Syntactically Awesome Stylesheets)是一种CSS预处理器,它为CSS增加了变量嵌套混合继承等高级功能,让CSS的编写和维护更加高效和规范。SCSS(Sassy CSS)是Sass 3引入的新语法,它完全兼容CSS3的语法,同时继承了Sass的强大功能。任何有效的CSS文件都是有效的SCSS文件,这使得开发者可以轻松地将现有CSS代码迁移到SCSS。

Sass有两种语法格式:最早的是Sass语法(缩进格式),使用严格的缩进而不依赖大括号和分号,文件扩展名为.sass;另一种是SCSS语法,使用大括号和分号,与CSS书写方式相似,文件扩展名为.scss。由于SCSS与传统CSS语法相似,更易为前端开发者接受,因此本教程将基于SCSS语法进行讲解。

作为找找网提供的教程,我们将从基础开始,逐步介绍Sass/SCSS的主要功能和使用方法。

环境搭建与编译

安装Sass

Sass是基于Ruby开发的,因此需要先安装Ruby环境。安装完成后,可以通过命令行安装Sass:

gem install sass

编译Sass/SCSS

Sass/SCSS文件需要编译为CSS文件才能在浏览器中使用。编译方法有多种:

命令行编译

# 单文件编译
sass input.scss output.css

# 监听文件变化自动编译
sass --watch input.scss:output.css

# 多文件编译(监听整个目录)
sass --watch app/sass:public/stylesheets

使用编辑器插件
主流代码编辑器如VS Code都有Sass编译插件(如Live Sass Compiler),可以在保存SCSS文件时自动编译为CSS。

自动化工具集成
还可以使用Grunt、Gulp等自动化工具集成Sass编译功能。

Sass变量

变量定义与使用

Sass使用$符号来声明变量。变量可以存储颜色、字体、尺寸等任何CSS属性值。

// 定义变量
$primary-color: #333;
$font-stack: Helvetica, sans-serif;
$base-margin: 10px;

// 使用变量
body {
  font: 100% $font-stack;
  color: $primary-color;
  margin: $base-margin;
}

编译后的CSS:

body {
  font: 100% Helvetica, sans-serif;
  color: #333;
  margin: 10px;
}

变量作用域

Sass变量有作用域的概念,在规则块内定义的变量只能在该块内使用。

$global-color: red; // 全局变量

.header {
  $local-color: blue; // 局部变量
  color: $local-color;
  background-color: $global-color;
}

.footer {
  color: $global-color; 
  // background-color: $local-color; // 这行会报错,因为$local-color在.footer中未定义
}

变量默认值

使用!default标志可以为变量设置默认值,如果变量已经被赋值,则使用已有的值,否则使用默认值。

$primary-color: #f00 !default; // 只在$primary-color未定义时生效

.header {
  color: $primary-color; // 如果之前未定义$primary-color,则使用#f00
}

Sass嵌套

选择器嵌套

Sass允许将CSS规则嵌套在其他规则中,使层次结构更加清晰。

// SCSS嵌套写法
nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li {
    display: inline-block;
  }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;

    &:hover {
      text-decoration: underline;
    }
  }
}

编译后的CSS:

nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

nav li {
  display: inline-block;
}

nav a {
  display: block;
  padding: 6px 12px;
  text-decoration: none;
}

nav a:hover {
  text-decoration: underline;
}

属性嵌套

Sass还支持属性嵌套,将同一命名空间的属性嵌套在一起。

// SCSS属性嵌套
.box {
  font: {
    family: Arial, sans-serif;
    size: 16px;
    weight: bold;
  }

  border: {
    width: 1px;
    style: solid;
    color: #ccc;
    radius: 5px;
  }
}

编译后的CSS:

.box {
  font-family: Arial, sans-serif;
  font-size: 16px;
  font-weight: bold;
  border-width: 1px;
  border-style: solid;
  border-color: #ccc;
  border-radius: 5px;
}

父选择器引用

在嵌套中使用&符号引用父选择器,常用于伪类和复合选择器。

// 使用&引用父选择器
.button {
  background-color: blue;
  color: white;

  &:hover {
    background-color: darkblue;
  }

  &.disabled {
    background-color: #ccc;
    cursor: not-allowed;
  }

  &::before {
    content: ">";
    margin-right: 5px;
  }
}

编译后的CSS:

.button {
  background-color: blue;
  color: white;
}

.button:hover {
  background-color: darkblue;
}

.button.disabled {
  background-color: #ccc;
  cursor: not-allowed;
}

.button::before {
  content: ">";
  margin-right: 5px;
}

Sass混合(Mixins)

基本混合

混合(Mixin)是可以重用的CSS代码块,使用@mixin定义,@include引用。

// 定义Mixin
@mixin border-radius($radius) {
  border-radius: $radius;
  -webkit-border-radius: $radius;
  -moz-border-radius: $radius;
}

// 使用Mixin
.button {
  @include border-radius(5px);
  background-color: blue;
  color: white;
}

.card {
  @include border-radius(10px);
  background-color: white;
  padding: 20px;
}

编译后的CSS:

.button {
  border-radius: 5px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  background-color: blue;
  color: white;
}

.card {
  border-radius: 10px;
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  background-color: white;
  padding: 20px;
}

带参数和默认值的混合

Mixins可以接受参数,也可以为参数设置默认值。

// 带参数和默认值的Mixin
@mixin alert-box($type: 'info', $padding: 10px) {
  padding: $padding;
  border: 1px solid #ccc;

  @if $type == 'success' {
    border-color: green;
    background-color: #e6ffe6;
  } @else if $type == 'error' {
    border-color: red;
    background-color: #ffe6e6;
  } @else if $type == 'warning' {
    border-color: orange;
    background-color: #fff9e6;
  } @else {
    border-color: blue;
    background-color: #e6f3ff;
  }
}

// 使用Mixin
.info-alert {
  @include alert-box();
}

.success-alert {
  @include alert-box('success', 15px);
}

.error-alert {
  @include alert-box('error');
}

编译后的CSS:

.info-alert {
  padding: 10px;
  border: 1px solid #ccc;
  border-color: blue;
  background-color: #e6f3ff;
}

.success-alert {
  padding: 15px;
  border: 1px solid #ccc;
  border-color: green;
  background-color: #e6ffe6;
}

.error-alert {
  padding: 10px;
  border: 1px solid #ccc;
  border-color: red;
  background-color: #ffe6e6;
}

内容块传递

使用@content指令可以在Mixin中传递内容块。

// 使用@content的Mixin
@mixin media-query($breakpoint) {
  @if $breakpoint == 'mobile' {
    @media (max-width: 768px) {
      @content;
    }
  } @else if $breakpoint == 'tablet' {
    @media (min-width: 769px) and (max-width: 1024px) {
      @content;
    }
  }
}

// 使用带内容块的Mixin
.sidebar {
  width: 25%;

  @include media-query('mobile') {
    width: 100%;
    margin-bottom: 20px;
  }
}

.main-content {
  width: 75%;

  @include media-query('mobile') {
    width: 100%;
  }
}

编译后的CSS:

.sidebar {
  width: 25%;
}

@media (max-width: 768px) {
  .sidebar {
    width: 100%;
    margin-bottom: 20px;
  }
}

.main-content {
  width: 75%;
}

@media (max-width: 768px) {
  .main-content {
    width: 100%;
  }
}

模块化与导入

局部文件与导入

Sass允许将样式拆分为多个文件,并使用@import指令导入。以下划线_开头的Sass文件被称为局部文件,Sass不会单独编译这些文件。

// _variables.scss
$primary-color: #333;
$secondary-color: #666;
$font-size-base: 16px;

// _mixins.scss
@mixin flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

@mixin box-shadow($x, $y, $blur, $color) {
  box-shadow: $x $y $blur $color;
  -webkit-box-shadow: $x $y $blur $color;
  -moz-box-shadow: $x $y $blur $color;
}

// main.scss
@import 'variables';
@import 'mixins';

.header {
  background-color: $primary-color;
  @include flex-center;
  padding: 20px;
}

.card {
  @include box-shadow(0, 2px, 4px, rgba(0,0,0,0.1));
  margin-bottom: 20px;
  font-size: $font-size-base;
}

编译后的CSS:

.header {
  background-color: #333;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;
}

.card {
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  -moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  margin-bottom: 20px;
  font-size: 16px;
}

继承与占位符

选择器继承

使用@extend可以让一个选择器继承另一个选择器的样式。

// 基础样式
.message {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
  border-radius: 3px;
}

// 继承样式
.success {
  @extend .message;
  border-color: green;
  background-color: #e6ffe6;
}

.error {
  @extend .message;
  border-color: red;
  background-color: #ffe6e6;
}

.warning {
  @extend .message;
  border-color: orange;
  background-color: #fff9e6;
}

编译后的CSS:

.message, .success, .error, .warning {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
  border-radius: 3px;
}

.success {
  border-color: green;
  background-color: #e6ffe6;
}

.error {
  border-color: red;
  background-color: #ffe6e6;
}

.warning {
  border-color: orange;
  background-color: #fff9e6;
}

占位符选择器

占位符选择器以%开头,它定义的样式只有在被继承时才会编译到CSS中,不会单独输出。

// 占位符选择器
%button-base {
  display: inline-block;
  padding: 10px 20px;
  border: none;
  border-radius: 3px;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  font-size: 16px;
}

// 继承占位符
.primary-button {
  @extend %button-base;
  background-color: blue;
  color: white;

  &:hover {
    background-color: darkblue;
  }
}

.secondary-button {
  @extend %button-base;
  background-color: #eee;
  color: #333;

  &:hover {
    background-color: #ddd;
  }
}

编译后的CSS:

.primary-button, .secondary-button {
  display: inline-block;
  padding: 10px 20px;
  border: none;
  border-radius: 3px;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  font-size: 16px;
}

.primary-button {
  background-color: blue;
  color: white;
}

.primary-button:hover {
  background-color: darkblue;
}

.secondary-button {
  background-color: #eee;
  color: #333;
}

.secondary-button:hover {
  background-color: #ddd;
}

运算符与计算

Sass支持基本的数学运算符,可以在样式表中进行数学计算。

// 运算符使用
.container {
  width: 100%;
}

.main {
  float: left;
  width: 600px / 960px * 100%;
  margin-right: 20px;
}

.sidebar {
  float: right;
  width: 300px / 960px * 100%;
}

// 使用计算
$base-font-size: 16px;
$line-height: 1.5;

.article {
  font-size: $base-font-size;
  line-height: $line-height;
  margin-bottom: $base-font-size * $line-height;

  h1 {
    font-size: $base-font-size * 2;
    margin-bottom: $base-font-size * 1.5;
  }

  p {
    margin-bottom: $base-font-size;
  }
}

编译后的CSS:

.container {
  width: 100%;
}

.main {
  float: left;
  width: 62.5%;
  margin-right: 20px;
}

.sidebar {
  float: right;
  width: 31.25%;
}

.article {
  font-size: 16px;
  line-height: 1.5;
  margin-bottom: 24px;
}

.article h1 {
  font-size: 32px;
  margin-bottom: 24px;
}

.article p {
  margin-bottom: 16px;
}

完整示例:个人资料卡片

下面是一个使用Sass/SCSS编写的完整个人资料卡片示例:

// _variables.scss
$primary-color: #3498db;
$secondary-color: #2ecc71;
$text-color: #333;
$light-gray: #f5f5f5;
$border-radius: 8px;
$box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);

// _mixins.scss
@mixin flex-column {
  display: flex;
  flex-direction: column;
}

@mixin flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

@mixin card-style {
  background-color: white;
  border-radius: $border-radius;
  box-shadow: $box-shadow;
  overflow: hidden;
}

// main.scss
@import 'variables', 'mixins';

.profile-card {
  @include card-style;
  max-width: 300px;
  margin: 20px auto;
  font-family: Arial, sans-serif;

  &-header {
    background-color: $primary-color;
    padding: 20px;
    @include flex-center;

    .avatar {
      width: 100px;
      height: 100px;
      border-radius: 50%;
      border: 3px solid white;
      object-fit: cover;
    }
  }

  &-body {
    padding: 20px;
    @include flex-column;

    .name {
      font-size: 24px;
      font-weight: bold;
      margin-bottom: 5px;
      color: $text-color;
    }

    .title {
      color: $primary-color;
      font-size: 16px;
      margin-bottom: 15px;
    }

    .bio {
      line-height: 1.5;
      margin-bottom: 20px;
    }

    .stats {
      display: flex;
      justify-content: space-around;
      border-top: 1px solid $light-gray;
      padding-top: 15px;

      .stat {
        @include flex-column;
        align-items: center;

        .value {
          font-size: 20px;
          font-weight: bold;
          color: $primary-color;
        }

        .label {
          font-size: 12px;
          color: lighten($text-color, 30%);
        }
      }
    }
  }

  &-footer {
    background-color: $light-gray;
    padding: 15px;
    @include flex-center;

    .btn {
      padding: 8px 16px;
      border: none;
      border-radius: $border-radius;
      cursor: pointer;
      font-weight: bold;
      transition: background-color 0.3s;

      &.primary {
        background-color: $primary-color;
        color: white;

        &:hover {
          background-color: darken($primary-color, 10%);
        }
      }

      &.secondary {
        background-color: $secondary-color;
        color: white;
        margin-left: 10px;

        &:hover {
          background-color: darken($secondary-color, 10%);
        }
      }
    }
  }
}

编译后的CSS:

.profile-card {
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  overflow: hidden;
  max-width: 300px;
  margin: 20px auto;
  font-family: Arial, sans-serif;
}

.profile-card-header {
  background-color: #3498db;
  padding: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.profile-card-header .avatar {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  border: 3px solid white;
  object-fit: cover;
}

.profile-card-body {
  padding: 20px;
  display: flex;
  flex-direction: column;
}

.profile-card-body .name {
  font-size: 24px;
  font-weight: bold;
  margin-bottom: 5px;
  color: #333;
}

.profile-card-body .title {
  color: #3498db;
  font-size: 16px;
  margin-bottom: 15px;
}

.profile-card-body .bio {
  line-height: 1.5;
  margin-bottom: 20px;
}

.profile-card-body .stats {
  display: flex;
  justify-content: space-around;
  border-top: 1px solid #f5f5f5;
  padding-top: 15px;
}

.profile-card-body .stats .stat {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.profile-card-body .stats .stat .value {
  font-size: 20px;
  font-weight: bold;
  color: #3498db;
}

.profile-card-body .stats .stat .label {
  font-size: 12px;
  color: #8c8c8c;
}

.profile-card-footer {
  background-color: #f5f5f5;
  padding: 15px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.profile-card-footer .btn {
  padding: 8px 16px;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font-weight: bold;
  transition: background-color 0.3s;
}

.profile-card-footer .btn.primary {
  background-color: #3498db;
  color: white;
}

.profile-card-footer .btn.primary:hover {
  background-color: #2980b9;
}

.profile-card-footer .btn.secondary {
  background-color: #2ecc71;
  color: white;
  margin-left: 10px;
}

.profile-card-footer .btn.secondary:hover {
  background-color: #27ae60;
}

Sass与SCSS语法对比

虽然Sass和SCSS本质上是同一种工具,但语法上有明显区别:

特性Sass(缩进语法)SCSS(CSS超集)
文件扩展名.sass.scss
大括号不使用使用
分号不使用使用
缩进严格缩进不强制缩进
变量符号使用$使用$
示例body<br> color: #333<br> font: 100% Arialbody {<br> color: #333;<br> font: 100% Arial;<br>}

编译与输出样式

Sass提供了多种输出样式选项,可以通过命令行参数控制:

# 嵌套输出格式
sass --watch input.scss:output.css --style nested

# 展开格式(更易读)
sass --watch input.scss:output.css --style expanded

# 紧凑格式
sass --watch input.scss:output.css --style compact

# 压缩格式(生产环境)
sass --watch input.scss:output.css --style compressed

总结

本教程涵盖了Sass/SCSS的基础知识,包括变量、嵌套、混合、继承、模块化等核心功能。通过使用Sass/SCSS,开发者可以编写更加模块化、可维护性更强的CSS代码,提高开发效率。

找找网提供的这篇教程旨在帮助初学者快速上手Sass/SCSS,建议在实际项目中多加练习,以更好地掌握这些概念和技巧。

Sass/SCSS基础知识点总结

知识点知识内容
Sass/SCSS简介Sass是CSS预处理器,为CSS添加变量、嵌套、混合等高级功能。SCSS是Sass的语法变体,完全兼容CSS语法。
环境搭建需要安装Ruby和Sass gem,可以使用命令行、编辑器插件或构建工具进行编译。
变量使用$符号定义变量,存储可重用的值,包含作用域概念和默认值设置。
嵌套允许选择器和属性嵌套,使用&引用父选择器,简化层级结构编写。
混合(Mixins)使用@mixin定义可重用代码块,@include引用,支持参数和内容块。
模块化与导入使用@import导入局部文件(以_开头),实现代码组织和分离。
继承使用@extend共享选择器样式,占位符选择器%只在被继承时输出。
运算符支持数学运算(加、减、乘、除),可在属性值中进行计算。
语法差异Sass使用缩进语法,SCSS使用类似CSS的括号语法,SCSS更易上手。
编译输出可控制输出格式(嵌套、展开、紧凑、压缩),适应开发和生产环境。