不错的 SCSS 使用技巧总结(1w字)

发表于 2年以前  | 总阅读数:489 次

前言

今时不同往日,能叫我们切图仔的只能是我们自己!

JavasScrip框架满天飞的年代,前端三板斧之一的CSS也前前后后涌出SassLessStylus等多款CSS预处理框架。

今天我们要讲的就是其中的的老大哥Sass的升级版ScssScss给我们提供了变量 、循环 、继承 、混入、函数等一系列强大的功能以方便我们开发。

以前觉得Scss简单,后来发现,简单是真的简单,我菜也是真的菜

Scss和Sass

Sass从第三代开始,放弃了缩进式风格,并且完全向下兼容普通的CSS代码,这一代的Sass也被称为Scss

文档

单文件编译可以在下面的网站进行操作,多文件编译见下下节,中文文档缺失的东西挺多的,有条件的可以翻看英文文档。

  • 中文文档:www.sass.hk[2]
  • 英文文档:sass-lang.com/documentati…[3]
  • CSSScss:www.sass.hk/css2sass[4]
  • ScssCSS:www.sassmeister.com[5]

Sass版本

Sass有三个版本Dart SasslibsassRuby Sass

  1. Dart Sass,用Dart语言写的sass实现,于2016年11月1日发布alpha版本,版本1.23.0之后完全支持模块化机制。
  2. libSass也就是俗称的node-sass,用c/c++实现的sass版本,使用非常广泛。node-sass是绑定了 libsassnodejs库,可以极快的将.scss 文件编译为.css文件,这个安装过程……,懂的都懂,官方也不推荐再使用了。
  3. Ruby Sass,是最初的Sass实现,但是2019年3月26日被停止了,以后也不会再支持,使用者需要迁移到别的实现上。

环境配置

中文文档的安装教程是Ruby Sass,个人推荐使用npm安装Dart Sass,这也是官方推荐的方式。

全局安装

npm默认安装的是Dart Sass了。

npm install -g sass

项目结构

code
    --css
        --index.scss
    --dist

监听运行

使用命令行操作,监听文件夹下的scss文件并输出为css文件,如果是webpack项目,则需要使用sass-loader

sass --style=expanded  -w css:dist --no-source-map

Live Sass Compiler

如果你使用的VSCodeLive Sass Compiler插件,可以参考我的配置,这个插件用的 Sass版本是LibSass3.5.4,对有些指令存在兼容性和不支持的情况。

"liveSassCompile.settings":{
        "generateMap":false,
        "formats":[
            {
                "format": "expanded",
                "savePath": "~/css/",
            }
        ]
}

输出格式

嘿嘿,下面正文术语都同统一改为小写哈。 scss提供了四种输出格式,在命令行中使用 --style 选项进行设置,在Live Sass Compiler中配置format参数。

「注:」dart sass只支持expandedcompressed

sass --watch style.scss:style.css --style compressed

:nested

nestedscss默认的输出格式,选择器与属性等单独占用一行,缩进量与 scss文件中一致,「每行的缩进量反映了其在嵌套规则内的层数」

#main {
  color: #fff;
  background-color: #000; }
  #main p {
    width: 10em; }

.p {
  font-size: 10em;
  font-weight: bold;
  text-decoration: underline; }

:expanded

expanded输出像是我们平常手写的样式,选择器、属性等各占用一行,属性根据选择器缩进,而选择器不做任何缩进。

#main {
  color: #fff;
  background-color: #000;
}
#main p {
  width: 10em;
}

.p {
  font-size: 10em;
  font-weight: bold;
  text-decoration: underline;
}

:compact

compact会将每条 css 规则归纳为一行。嵌套过的选择器在输出时没有空行,不嵌套的选择器会输出空白行作为分隔符。

#main { color: #fff; background-color: #000; }
#main p { width: 10em; }

.p { font-size: 10em; font-weight: bold; text-decoration: underline; }

:compressed

compressed会删除所有无意义的空格、空白行、以及注释,力求将文件体积压缩到最小,同时也会做出其他调整,比如会自动替换占用空间最小的颜色表达方式。

#main{color:#fff;background-color:#000}#main p{width:10em}.p{font-size:10em;font-weight:bold;text-decoration:underline}

语法嵌套规则

选择器嵌套

css中重复写选择器是非常恼人的。尤其是html结构嵌套非常深的时候,scss的选择器嵌套可以避免重复输入父选择器,可以有效的提高开发效率,减少样式覆盖可能造成的异常问题。这也是我们最常用的功能。很多人用scss就只用了这个功能,然后觉得自己会了。

这个是正常的css结构

.container {
    width: 1200px;
    margin: 0 auto;
}
.container .header .img {
    width: 100px;
    height: 60px;
}

编译成scss的样子,子元素向父元素内部嵌套了。

.container {
    width: 1200px;
    margin: 0 auto;
    .header {
        .img {
            width: 100px;
            height: 60px;
        }
    }
}

属性嵌套

有些css属性遵循相同的命名空间 (相同的开头),比如font-familyfont-sizefont-weight都以font作为属性的命名空间。为了便于管理这样的属性,也为了避免重复输入。(这个编辑器提示有点不太理想……,不是很好用)。

.container {
  font: {
    family: fantasy;
    size: 30em;
    weight: bold;
  }
}

编译成css

.container {
  font-family: fantasy;
  font-size: 30em;
  font-weight: bold;
}

命名空间也可以包含自己的属性值

.container {
  color: red {
    adjust: fantasy;
  }
}

编译成css

.container {
  color: red;
  color-adjust: fantasy;
}

父选择器&

在嵌套 css规则时,有时会需要使用嵌套外层的父选择器,例如,当给某个元素设定 hover 样式时,可以用& 代表嵌套规则外层的父选择器,scss在编译时会把&替换成父选择器名。

案例里面的&表示的就是父级a选择器

.container {
    a {
        color: #333;
        &:hover {
             text-decoration: underline;
             color: #f00;
        }
    }
}

转化成scss

.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;
}

Scss的两种注释

多行注释/* ... */

多行注释会编译到.css文件中,compressed(压缩)模式下除外, 将 !作为多行注释的第一个字符表示在压缩输出模式下也保留这条注释,通常用于添加版权信息。

/*!
* 我是
* 多行
* 注释
*/
body { color: black; }

编译成css

/*!
* 我是
* 多行
* 注释 
*/body{color:#000}

单行注释//

单行注释不会编译到.css文件

// 我是单行注释
body { color: black; }

编译成css

body {
  color: black;
}

变量

使用

原生css中的变量,使用--变量名:变量值定义,var(--变量名)进行使用。

:root {
    --color: #F00;
}
p {
    color: var(--color);
}

scss中的变量,以美元符号$开头,赋值方法与 css属性的写法一样。

$color:#F00;
p {
    color: $color;
}

转行成css

p {
    color: #F00;
}

5条变量规则

下文的mixinfunction命名也遵循1234条规则:

  1. 变量以美元符号$开头,后面跟变量名;
  2. 变量名是不以数字开头的可包含字母、数字、下划线、横线(连接符);
  3. 通过连接符-与下划线_定义的同名变量为同一变量;
  4. 变量一定要先定义,后使用;
  5. 写法同css,即变量名和值之间用冒号:分隔;

2种变量作用域

  1. 变量作用域分为「全局变量域」「局部变量域」
  • 全局变量:声明在最外层的变量,可在任何地方使用;
  • 局部变量:嵌套规则内定义的变量只能在嵌套规则内使用。

2 . 将局部变量转换为全局变量可以添加!global 声明。

$color: red;
.container {
    $height: 500px;
    $font-size: 16px !global;
    font-size: $font-size;
    color: $color;
    height: $height;
}
.footer {
    /**$font-size使用!global 申明成全局变量了*/
    font-size: $font-size; 
    /**
    * Error: Undefined variable. 
    * $height是.container下的局部变量,无法在.footer下面编译
    */
    height:$height;
}

编译成css

.container {
    font-size: 16px;
    color: red;
    height: 500px;
}

.footer {
     /**$font-size使用!global 申明成全局变量了*/
    font-size: 16px;
}

7种主要的数据类型

scss支持7种主要的数据类型:

  1. 数字,1rem、2vh、13、 10px
  2. 字符串,分有引号字符串与无引号字符串,"foo"、 'bar'、baz
  3. 颜色,blue, #04a3f9, rgba(255,0,0,0.5)
  4. 布尔型,truefalse
  5. 空值,null是其类型的唯一值。表示缺少值,通常由函数返回以表示缺少结果;
  6. 数组 (list),用空格或逗号作分隔符,1.5em 1em 0 2em,Helvetica,Arial,sans-serif
  7. maps, 相当于 JavaScriptobject(key1: value1, key2: value2)

官网中把Function也当作一种类型,点击原文了解[6]。

$layer-index: 10;
$border-width: 3px;

$font-weight: bold;

$font-base-family: "Open Sans", Helvetica, Sans-Serif;
$block-base-padding: 6px 10px 6px 10px;

$top-bg-color: rgba(255, 147, 29, 0.6);

$blank-mode: true;

$var: null;

$fonts: (
  serif: "Helvetica Neue",
  monospace: "Consolas",
);

.container {
  font-family: $font-base-family;
  font-size: $font-size;
  padding: $block-base-padding;

  @if $blank-mode {
    background-color: #000;
  } @else {
    background-color: #fff;
  }

  content: type-of($var);
  content: length($var);
  color: $top-bg-color;
}

// 如果列表中包含空值,则生成的CSS中将忽略该空值。
.wrap {
  font: 18px $font-weight map-get($fonts, "sans");
}

编译成css

.container {
  font-family: "Open Sans", Helvetica, Sans-Serif;
  font-size: 16px;
  padding: 6px 10px 6px 10px;
  background-color: #000;
  content: null;
  content: 1;
  color: rgba(255, 147, 29, 0.6);
}

.wrap {
  font: 18px bold; // 如果列表中包含空值,则生成的CSS中将忽略该空值。
}

scss属性也支持其他值,比如Unicode字符集,或!important 声明。但是scss 不会特殊对待这些属性值,一律视为无引号字符串。

$color:red;
.container {
    color:$color !important;
}

编译成css

.container {
  color: red !important;
}

!default

可以在变量的结尾添加!default来给变量设置默认值,有点类似Javascript的逻辑运算符let content=content || "Second content"。注意,变量是 null时将视为未被!default赋值。

$content: "First content";
// 如果$content之前没定义就使用如下的默认值
$content: "Second content" !default;
#main {
    content: $content;
}

编译成css

#main {
  content: "First content";
}

圆括号

圆括号()可以用来影响运算的顺序,和数学中的效果是一致的。

运算符

相等运算==和不相等运算!=。所有数据类型均支持 ==!=,另外,每种数据类型也有其各自支持的运算方式。

$theme:"blue";

.container {
    @if $theme=="blue" {
        background-color: red;
    }
    @else {
        background-color: blue;
    }
}

.container {
    @if $theme !="blue" {
        background-color: red;
    }
    @else {
        background-color: blue;
    }
}

编译为css

.container {
  background-color: red;
}

.container {
  background-color: blue;
}

关系运算符

四个关系运算符< > >= <=

$theme:3;
.container {
    @if $theme >= 5 {
        background-color: red;
    }
    @else {
        background-color: blue;
    }
}

编译为css

.container {
    background-color: blue;
}

布尔运行符

三个布尔运算符and or not

$width: 100;
$height: 200;
$last: false;
div {
  @if $width>50 and $height<300 {
    font-size: 16px;
  } @else {
    font-size: 14px;
  }
  @if not $last {
    border-color: red;
  } @else {
    border-color: blue;
  }

  @if $width>500 or $height<300{
    line-height: 20px;
  } @else {
    line-height: 50px;
  }
}

编译为css

div {
    font-size: 16px;
    border-color: red;
    line-height: 20px;
}div {
    font-size: 16px;
    border-color: red;
}

数字操作符

+ - * / %

/* 纯数字与百分号或单位运算时会自动转化成相应的百分比与单位值 */
.container {
    /* ================== + 运算===================== */
    width: 50 + 20;
    width: 50 + 20%;
    width: 50% + 20%;
    width: 10pt + 20px;
    width: 10pt + 20;

    /* ================== - 运算===================== */
    height: 50 - 20;
    height: 10 - 20%;
    height: 50pt - 20px;

    /* ================== * 运算===================== */
    height: 50 * 30;
    height: 10 * 30%;
    height: 50 * 2px;
    height: 50pt * 4;

    /* ==================/ 运算 (除完后最多只能保留一种单位)===================== */
    $width: 100px;
    width: 10/5;
    width: 10px / 5px;
    width: 10px / 20;
    width: ($width/2); // 使用变量与括号
    height: (500px/2); // 使用了括号

    /* ==================% 求余运算===================== */
    width: 10 % 3;
    width: 50px % 7;
    width: 50% % 7;
}

编译成css

/* 纯数字与百分号或单位运算时会自动转化成相应的百分比与单位值 */
.container {
    /* ================== + 运算===================== */
    width: 70;
    width: 70%;
    width: 70%;
    width: 25pt;
    width: 30pt;
    /* ================== - 运算===================== */
    height: 30;
    height: -10%;
    height: 35pt;
    /* ================== * 运算===================== */
    height: 1500;
    height: 300%;
    height: 100px;
    height: 200pt;
    /* ==================/ 运算 (除完后最多只能保留一种单位)===================== */
    width: 10/5;
    width: 10px/5px;
    width: 10px/20;
    width: 50px;
    height: 250px;
    /* ==================% 运算===================== */
    width: 1;
    width: 1px;
    width: 1%;
}

/css中有分隔数字的用途,在scss中,以下三种情况会进行除法运算:

  1. 如果值或值的一部分,是变量或者函数的返回值;
  2. 如果值被圆括号包裹;
  3. 如果值是算数表达式的一部分。
$width: 1000px;
div {
    font: 16px/30px Arial, Helvetica, sans-serif; // 不运算
    width: ($width/2); // 使用变量与括号
    width: (#{$width}/2); // 使用 #{} 插值语句将变量包裹,避免运算。
    z-index: round(10)/2; // 使用了函数
    height: (500px/2); // 使用了括号
    margin-left: 5px + 8px/2px; // 使用了+表达式
}

编译成css

div {
    font: 16px/30px Arial, Helvetica, sans-serif;
    width: 500px;
    width: 1000px/2;
    z-index: 5;
    height: 250px;
    margin-left: 9px;
}

如果需要使用变量,同时又要确保 / 不做除法运算而是完整地编译到 css文件中,只需要用 #{} 插值语句将变量包裹。

字符串运算

  1. +可用于连接字符串;
  2. 如果有引号字符串(位于 + 左侧)连接无引号字符串,运算结果是有引号的;
  3. 无引号字符串(位于 + 左侧)连接有引号字符串,运算结果则没有引号。
.container {
    content: "Foo " + Bar;
    font-family: sans- + "serif";
}

编译为css

.container {
    content: "Foo Bar";
    font-family: sans-serif;
}

插值语句

文章上面有讲到插值语句,这里来解释一下。 通过 #{} 插值语句可以在选择器、属性名、注释中使用变量,使用#{}插值语句将变量包裹起来即可,和js中的模板字符串很像。

$font-size: 12px;
$line-height: 30px;
$class-name: danger;
$attr: color;
$author: "福大命大";

p {
    font: #{$font-size}/#{$line-height} Arial Helvetica, sans-serif;
}

/* 
* 这是文件的说明部分
* @author: #{$author}
*/

a.#{$class-name} {
    border-#{$attr}: #f00;
}

编译成css

p {
    font: 12px/30px Arial Helvetica, sans-serif;
}

/* 
* 这是文件的说明部分
* @author: 福大命大
*/
a.danger {
    border-color: #f00;
}

流程控制

sass中流程控制包含四类,也是我们在js中常见的@if、@for、@each、@while

@if

@if语法和js类似,基本格式是@if...@else if...@else

使用

$theme:3;
.container {
    @if $theme >= 5 {
        background-color: red;
    }
    @else {
        background-color: blue;
    }
}

编译为css

.container {
    background-color: blue;
}

案例

这里已一个利用mixinif封装一个三角形生成,mixin知识后面又讲到。

@mixin triangle($direction:top, $size:30px, $border-color:black) {
  width: 0px;
  height: 0px;
  display: inline-block;
  border-width: $size;
  border-#{$direction}-width: 0;
  @if ($direction==top) {
     border-color: transparent transparent $border-color transparent;
     border-style: dashed dashed solid dashed;
  }
  @else if($direction==right) {
     border-color: transparent transparent transparent $border-color;
     border-style: dashed dashed dashed solid;
  }
  @else if($direction==bottom) {
     border-color: $border-color transparent transparent transparent;
     border-style: solid dashed dashed dashed;
  }
  @else if($direction==left) {
     border-color: transparent $border-color transparent transparent;
     border-style: dashed solid dashed dashed;
  }
}
.p0 {
     @include triangle($size:50px);
}

.p1 {
     @include triangle(right, 50px, red);
}

.p2 {
    @include triangle(bottom, 50px, blue);
}

.p3 {
     @include triangle(left, 50px, green);
}

编译为

.p0 {
    width: 0px;
    height: 0px;
    display: inline-block;
    border-width: 50px;
    border-top-width: 0;
    border-color: transparent transparent black transparent;
    border-style: dashed dashed solid dashed;
}

.p1 {
    width: 0px;
    height: 0px;
    display: inline-block;
    border-width: 50px;
    border-right-width: 0;
    border-color: transparent transparent transparent red;
    border-style: dashed dashed dashed solid;
}

.p2 {
    width: 0px;
    height: 0px;
    display: inline-block;
    border-width: 50px;
    border-bottom-width: 0;
    border-color: blue transparent transparent transparent;
    border-style: solid dashed dashed dashed;
}

.p3 {
    width: 0px;
    height: 0px;
    display: inline-block;
    border-width: 50px;
    border-left-width: 0;
    border-color: transparent green transparent transparent;
    border-style: dashed solid dashed dashed;
}

@for

for在条件范围内重复操作,这个指令包含两种格式:

  1. @for $var from <start> through <end>
  2. @for $var from <start> to <end>

两者区别在于 throughto 的含义:

  1. 使用 through时,条件范围包含 <start><end>的值;
  2. 使用 to时条件范围只包含<start>的值不包含<end>的值;
  3. $var 可以是任何变量,比如$i<start><end> 必须是整数值。
@for $i from 1 to 3 {
  #loading span:nth-child(#{$i}) {
      width: 20 * ($i - 1) + px;
  }
}

编译为

#loading span:nth-child(1) {
    width: 0px;
}

#loading span:nth-child(2) {
    width: 20px;
}

如果把to换成through

#loading span:nth-child(1) {
    width: 0px;
}

#loading span:nth-child(2) {
    width: 20px;
}

#loading span:nth-child(3) {
    width: 40px;
}

@each

@each指令的格式是@each $var in $list , $var可以是任何变量名,比如$length 或者$name,而$list是一连串的值,也就是值列表。

$color-list:red green blue turquoise darkmagenta;
@each $color in $color-list {
    $index: index($color-list, $color);
    .p#{$index - 1} {
        background-color: $color;
    }
}

编译为

.p0 {
    background-color: red;
}

.p1 {
    background-color: green;
}

.p2 {
    background-color: blue;
}

.p3 {
    background-color: turquoise;
}

.p4 {
    background-color: darkmagenta;
}

@while

@while 指令循环输出直到表达式返回结果为 false。这样可以实现比@for 更复杂的循环。

比如,可以借此生成栅格化布局。

$column:12;
@while $column>0 {
   .col-sm-#{$column} {
      width: $column / 12 * 100%;
   }
    $column:$column - 1;
}

编译为

.col-sm-12 {
    width: 100%;
}

.col-sm-11 {
    width: 91.6666666667%;
}

.col-sm-10 {
    width: 83.3333333333%;
}

.col-sm-9 {
    width: 75%;
}

.col-sm-8 {
    width: 66.6666666667%;
}

.col-sm-7 {
    width: 58.3333333333%;
}

.col-sm-6 {
    width: 50%;
}

.col-sm-5 {
    width: 41.6666666667%;
}

.col-sm-4 {
    width: 33.3333333333%;
}

.col-sm-3 {
    width: 25%;
}

.col-sm-2 {
    width: 16.6666666667%;
}

.col-sm-1 {
    width: 8.3333333333%;
}

@import

@import算是一个比较简易的模块系统。scss拓展了@import 的功能,允许其导入 scsssass文件。被导入的文件将合并编译到同一个 css文件中,被导入的文件中所包含的变量或者混合指令 (mixin) 都可以在导入的文件中使用。

使用

common.scss

$color:red;

index.scss

@import "common.scss";
.container {
    border-color: $color;
}

编译成

.container {
  border-color: red;
}

以下情况下,@import 仅作为普通的css语句,不会导入scss文件:

  1. 文件拓展名是 .css
  2. 文件名以 http:// 开头;
  3. 文件名是 url()
  4. @import包含媒体查询。
@import "common.css";
@import url(common);
@import "http://xxx.com/xxx";
@import 'landscape' screen and (orientation:landscape);

scss允许同时导入多个文件,例如同时导入 rounded-cornerstext-shadow 两个文件,不用再单独写个import引入。

@import "rounded-corners", "text-shadow";

导入文件也可以使用 #{} 插值语句(下面有讲,这里把它理解成js中模板字符串就行)动态导入,但不是通过变量动态导入 scss文件,只能作用于 cssurl() 导入方式

$family: unquote("Droid+Sans");
@import url("http://fonts.googleapis.com/css?family=#{$family}");

编译为

@import url("http://fonts.googleapis.com/css?family=Droid+Sans");

@Partials

如果需要导入 scss或者 sass文件,但又不希望将其编译为 css,只需要在文件名前添加下划线,这样会告诉 scss不要编译这些文件。注意:

  1. 导入语句中却不需要添加下划线;
  2. 不可以同时存在添加下划线与未添加下划线的同名文件,添加下划线的文件将会被忽略。

「_common.scss」

$color:red;

「index.scss」

@import "common.scss";
.container {
    border-color: $color;
}

编译为

.container {
  border-color: red;
}

_common.scss文件不会编译成_common.css 文件。

Partials主要是用来定义公共样式的,专门用于被其他的 scss文件 import进行使用的。

嵌套@import

大多数情况下,一般在文件的最外层(不在嵌套规则内)使用@import,其实,也可以将@import 嵌套进内层选择器或者 @media 中,与平时的用法效果相同,只是这样导入的样式只能出现在嵌套的层中,存在作用域。

common.scss

.example {
    color: red;
}

index.scss

#main {
    @import "example";
}

被编译成

#main .example {
    color: red;
}

注意:@import不能嵌套使用在控制指令或混入中(带有@符号的叫指令)。

@media 媒体查询增强

scss中,@media 指令与 css中用法一样,只是增加了一点额外的功能,允许在css规则中嵌套。如果@media 嵌套在 css规则内,编译时,@media 将被编译到文件的最外层,包含嵌套的父选择器。这个让 @media 方便不少,不需要重复写选择器,也不会打乱 css的书写流程。

使用

.sidebar {
  width: 300px;
  @media screen and (orientation: landscape) {
    width: 500px;
    .item {
      height: auto;
    }
  }
}

编译为

.sidebar {
    width: 300px;
}
@media screen and (orientation: landscape) {
  .sidebar {
    width: 500px;
  }
  .sidebar .item {
    height: auto;
  }
}

嵌套

@media允许互相嵌套使用,编译时,scss自动添加 and

@media screen {
  .sidebar {
    @media (orientation: landscape) {
      width: 500px;
    }
  }
}

编译为

@media screen and (orientation: landscape) {
  .sidebar {
    width: 500px;
  }
}

使用插值

可以使用变量,函数,以及运算符代替条件的名称或者值。

$media: screen;
$feature: -webkit-min-device-pixel-ratio;
$value: 1.5;

@media #{$media} and ($feature: $value) {
  .sidebar {
    width: 500px;
  }
}

编译为

@media screen and (-webkit-min-device-pixel-ratio: 1.5) {
  .sidebar {
    width: 500px;
  }
}

@mixin

混合指令(Mixin)用于定义可重复使用的样式。混合指令可以包含所有的css规则,绝大部分 scss规则,甚至可以通过参数功能引入变量,输出多样化的样式。

「注意:函数命名和变量命名规则一致。」

使用

@mixin mixin-name() {
    /* css 声明 */
}
// 使用
@include mixin-name;

标准形式

// 定义一个区块基本的样式
@mixin block {
    width: 96%;
    margin-left: 2%;
    border-radius: 8px;
    border: 1px #f6f6f6 solid;
}
// 使用混入 
.container {
    .block {
        @include block;
    }
}

编译为

.container .block {
    width: 96%;
    margin-left: 2%;
    border-radius: 8px;
    border: 1px #f6f6f6 solid;
}

嵌入选择器

@mixin里面再嵌套一层

@mixin warning-text {
    font-size: 12px;
    .warn-text {
        color: rgb(255, 253, 123);
        line-height: 180%;
    }
}

.container {
    @include warning-text;
}

编译为

.container {
    font-size: 12px;
}

.container .warn-text {
    color: #fffd7b;
    line-height: 180%;
}

单参数

// 定义flex布局元素纵轴的排列方式
@mixin flex-align($aitem) {
    align-items: $aitem;
}

// 只有一个参数,直接传递参数
.container {
    @include flex-align(center);
}

编译为

.container {
    align-items: center;
}

多参数

// 定义块元素内边距
@mixin block-padding($top, $right, $bottom, $left) {
    padding-top: $top;
    padding-right: $right;
    padding-bottom: $bottom;
    padding-left: $left;
}

// 按照参数顺序赋值
.container1 {
   @include block-padding(10px, 20px, 30px, 40px);
}

// 可指定参数赋值
.container2 {
   @include block-padding($left: 20px, $top: 10px, $bottom: 10px, $right: 30px);
}

// 可指定参数赋值,但是必须指定4个值,不能缺失
.container3 {
   @include block-padding($left: 10px, $top: 10px, $bottom: 0, $right: 0);
}

编译为


.container1 {
    padding-top: 10px;
    padding-right: 20px;
    padding-bottom: 30px;
    padding-left: 40px;
}

.container2 {
    padding-top: 10px;
    padding-right: 30px;
    padding-bottom: 10px;
    padding-left: 20px;
}

.container3 {
    padding-top: 10px;
    padding-right: 0;
    padding-bottom: 0;
    padding-left: 10px;
}

指定默认值

// 定义块元素内边距,参数指定默认值
@mixin block-padding($top:0, $right:0, $bottom:0, $left:0) {
    padding-top: $top;
    padding-right: $right;
    padding-bottom: $bottom;
    padding-left: $left;
}

// 可指定参数赋值
.container {
    /** 不带参数 */
    @include block-padding;
    /** 按顺序指定参数值 */
    @include block-padding(10px,20px);
    /** 给指定参数指定值 */
    @include block-padding($left: 10px, $top: 20px)
}

编译为

.container {
    /** 不带参数 */
    padding-top: 0;
    padding-right: 0;
    padding-bottom: 0;
    padding-left: 0;
    /** 按顺序指定参数值 */
    padding-top: 10px;
    padding-right: 20px;
    padding-bottom: 0;
    padding-left: 0;
    /** 给指定参数指定值 */
    padding-top: 20px;
    padding-right: 0;
    padding-bottom: 0;
    padding-left: 10px;
}

可变参数

使用...处理参数不固定的情况,类似于js中的函数的剩余参数

@mixin linear-gradient($direction, $gradients...) {
    background-color: nth($gradients, 1);
    background-image: linear-gradient($direction, $gradients);
}

.table-data {
    @include linear-gradient(to right, #F00, orange, yellow);
}

编译为

.table-data {
    background-color: #F00;
    background-image: linear-gradient(to right, #F00, orange, yellow);
}

总结

  1. mixin是可以重复使用的一组css声明,有助于减少重复代码,只需声明一次,就可在文件中引用;
  2. 混合指令可以包含所有的 css规则,绝大部分scss规则,可以传递参数,输出多样化的样式;
  3. 使用参数时建议加上默认值;
  4. @import导入局部模块化样式(类似功能、同一组件);
  5. @minix定义的是可重复使用的样式

@function

@function用于封装复杂的操作,可以很容易地以一种可读的方式抽象出通用公式和行为,函数提供返回值,常用来做计算方面的工作。

使用

注意:函数命名和变量命名规则一致。

@function square($base) {
    @return $base * $base * 1px;
}

.sidebar {
    float: left;
    margin-left: square(4);
}

编译为

.sidebar {
    float: left;
    margin-left: 16px;
}

可选参数

默认值可以是任何表达式,它们甚至可以引用前面的参数!

//change-color和hue是内置方法
//hue 返回$color的颜色为0到360度之间的一个数字。
//change-color 用于设置颜色的属性
@function invert($color, $amount: 100%) {
    //@error hue($color); 调试 210deg
    $inverse: change-color($color, $hue: hue($color) + 180);
    @return mix($inverse, $color, $amount);
}

$primary-color: #036;
.header {
    background-color: invert($primary-color, 80%);
}

编译为

.header {
    background-color: #523314;
}

指定参数

$primary-color: #036;
.banner {
    //scale-color Fluidly scales one or more properties of .$color
    background-color: $primary-color;
    color: scale-color($primary-color, $lightness: +40%);
}

编译为

.banner {
    background-color: #036;
    color: #0a85ff;
}

可变参数

参数列表还可用于采用任意关键字参数,meta.keywords()函数采用参数列表

@function sum($numbers...) {
    $sum: 0;
    @each $number in $numbers {
        $sum: $sum + $number;
    }
    @return $sum;
}

$widths: 50px, 30px, 100px;
.micro {
    width: sum($widths...);
}

编译为

.micro {
    width: 180px;
}

@return

@return只允许在@function内使用,和js一样,遇到return就会返回。

@function red() {
    $is: true;
    @if $is {
        @return 'is';
    }
    @return red;
}
.con{
    color: red();
}

编译为

.con {
    color: "is";
}

总结: @function@mixin参数的使用方式没啥区别; @function用来计算,@mixin用来封装样式,@import用来抽离他们为一个模块。

@extend继承

使用

我们以elementUIel-button组件为例,可以使用@extend继承已经存在的样式,原理是使用逗号选择器。

// # id选择器一样的
.button {
    display: inline-block;
    margin-bottom: 0;
    font-weight: normal;
    text-align: center;
    white-space: nowrap;
    vertical-align: middle;
    cursor: pointer;
    background-image: none;
    border: 1px solid transparent;
    padding: 6px 12px;
    font-size: 14px;
    line-height: 1.42857143;
    border-radius: 4px;
    user-select: none;
}

.btn-default {
    @extend .button;
    color: #333;
    background-color: #fff;
    border-color: #ccc;
}

.btn-danger {
    @extend .button;
    color: #fff;
    background-color: #d9534f;
    border-color: #d43f3a;
}

编译成

.button, .btn-danger, .btn-default {
    display: inline-block;
    margin-bottom: 0;
    font-weight: normal;
    text-align: center;
    white-space: nowrap;
    vertical-align: middle;
    cursor: pointer;
    background-image: none;
    border: 1px solid transparent;
    padding: 6px 12px;
    font-size: 14px;
    line-height: 1.42857143;
    border-radius: 4px;
    user-select: none;
}

.btn-default {
    color: #333;
    background-color: #fff;
    border-color: #ccc;
}

.btn-danger {
    color: #fff;
    background-color: #d9534f;
    border-color: #d43f3a;
}

可以使用多个@extend

.alert {
    padding: 15px;
    margin-bottom: 20px;
    border: 1px solid transparent;
    border-radius: 4px;
    font-size: 12px;
}

.important {
    font-weight: bold;
    font-size: 14px;
}
.alert-danger {
    @extend .alert;
    @extend .important;
    color: #a94442;
    background-color: #f2dede;
    border-color: #ebccd1;
}

编译为

.alert, .alert-danger {
    padding: 15px;
    margin-bottom: 20px;
    border: 1px solid transparent;
    border-radius: 4px;
    font-size: 12px;
}

.important, .alert-danger {
    font-weight: bold;
    font-size: 14px;
}

.alert-danger {
    color: #a94442;
    background-color: #f2dede;
    border-color: #ebccd1;
}

多层继承

@extend可以多层继承,列如:.alert-danger继承自.important.important又继承自.alert

.alert {
    padding: 15px;
    margin-bottom: 20px;
    border: 1px solid transparent;
    border-radius: 4px;
    font-size: 12px;
}

.important {
    @extend .alert;
    font-weight: bold;
    font-size: 14px;
}
.alert-danger {
    @extend .important;
    color: #a94442;
    background-color: #f2dede;
    border-color: #ebccd1;
}

编译为

.alert, .important, .alert-danger {
    padding: 15px;
    margin-bottom: 20px;
    border: 1px solid transparent;
    border-radius: 4px;
    font-size: 12px;
}

.important, .alert-danger {
    font-weight: bold;
    font-size: 14px;
}

.alert-danger {
    color: #a94442;
    background-color: #f2dede;
    border-color: #ebccd1;
}

占位符选择器

占位符选择器%,与常用的idclass选择器写法相似,只是 #. 替换成了%,占位符选择器必须通过 @extend 指令调用。 还是上面的例子,这里使用占位符选择器操作

.button %base {
    display: inline-block;
    margin-bottom: 0;
    font-weight: normal;
    text-align: center;
    white-space: nowrap;
    vertical-align: middle;
    cursor: pointer;
    background-image: none;
    border: 1px solid transparent;
    padding: 6px 12px;
    font-size: 14px;
    line-height: 1.42857143;
    border-radius: 4px;
    user-select: none;
}

.btn-default {
    @extend %base;
    color: #333;
    background-color: #fff;
    border-color: #ccc;
}

.btn-danger {
    @extend %base;
    color: #fff;
    background-color: #d9534f;
    border-color: #d43f3a;
}

效果和上面的类选择器一样,但是,他有个有优点,占位符选择器%所属的样式未使用时,不会被编译到css文件中,算是一个小优化吧。

.button .btn-danger, .button .btn-default {
    display: inline-block;
    margin-bottom: 0;
    font-weight: normal;
    text-align: center;
    white-space: nowrap;
    vertical-align: middle;
    cursor: pointer;
    background-image: none;
    border: 1px solid transparent;
    padding: 6px 12px;
    font-size: 14px;
    line-height: 1.42857143;
    border-radius: 4px;
    user-select: none;
}

.btn-default {
    color: #333;
    background-color: #fff;
    border-color: #ccc;
}

.btn-danger {
    color: #fff;
    background-color: #d9534f;
    border-color: #d43f3a;
}

@use

存在兼容性问题,仅在Dart Sass 1.23.0以上有效,官方文档有兼容性介绍[7]。

scss真正意义上的模块化,可以从其它 scss样式表中加载mixinfunction变量,并将来自多个样式表的 css组合在一起。scss还提供了很多内置模块,我们可以通过@use使用。

@import缺点

  1. 多处导入,存在样式重复加载。
  2. 因为没有命名空间,为了避免撞名,不敢使用简写的 classname,因此起名总是需要注意。
  3. 没有私有函数的概念,样式完全暴露在使用import的地方,这对ui库不够友好。

使用

src/_corners.scss

$radius: 3px;
@mixin rounded {
    border-radius: $radius;
}

index.scss

@use "src/corners";
.button {
    @include corners.rounded;
    padding: 5px + corners.$radius;
}

命名空间

src/_corners.scss

$radius: 3px;
@mixin rounded {
    border-radius: $radius;
}

index.scss

@use "src/corners" as c;
.button {
    @include c.rounded;
    padding: 5px + c.$radius;
}

编译为

.button {
    border-radius: 3px;
    padding: 8px;
}

as*

使用as*,那么这一模块就处于全局命名空间。

src/_corners.scss

$radius: 3px;
@mixin rounded {
    border-radius: $radius;
}

index.scss

@use "src/corners" as *;

.button {
    @include rounded;
    padding: 5px + $radius;
}

编译为

.button {
    border-radius: 3px;
    padding: 8px;
}

私有模块

使用scss可以轻松地定义私有成员,私有成员命名以-或开头。

src/_corners.scss

$-radius: 3px;

@mixin rounded {
    border-radius: $-radius;
}

index.scss

@use "src/corners";

.button {
    @include corners.rounded;
    // Error: Private members can't be accessed from outside their modules
    padding: 5px + corners.$-radius;
}

@forward

@forward语句可以引入另一个模块的所有变量、mixins和函数,将它们直接作为当前模块的API暴露出去,不会真的在当前模块增加代码。不同于 @use@forward不能给变量添加命名空间。

用法

注意,此时生成的bootstrap.css文件中,是不包含functionsvariablesmixins代码的,也不能直接在bootstrap.scss文件中使用这些模块。而是需要在另一个文件中 @import 'bootstrap'或者 @use bootstrap模块,再去使用这些方法。bootstrap.scss文件类似于一个传输中转站,把上下游的成员变量无缝连接起来。

/* bootstrap.scss */
@forward"functions";
@forward"variables";
@forward"mixins";

注意,直接写在上游模块的正常的样式仍然会被 @forward进来。见下例:

a.scss

@mixin rounded {
    border-radius: 100px;
}
footer {
    height: 1px;
}

b.scss

$radius: 3px;

c.scss

@forward "a";
@forward "b";

index.scss

@import "c.scss";

.button {
    @include rounded;
    padding: $radius;
}

编译为

footer {
    height: 1px;
}

.button {
    border-radius: 100px;
    padding: 3px;
}

show/ hide

通过控制 showhide,可以决定模块中的哪些成员对引入后的模板可见。对隐藏的变量,在下游文件中不可以使用,相当于模块私有成员。

c.scss

@forward "a" show rounded;
@forward "b" hide $radius;

index.css

@import "c.scss";

.button {
    @include rounded;
    padding: $radius;
}
// Error: Undefined variable. padding: $radius;

使用as *号为子模块添加前缀

大多数情况下,一个样式库会存在一个入口文件index.scss,然后在index.scss中引入其他的子文件。这种结构类似于一个多合一模块。那么,如果要在某一文件中 @forward多个子模块,就可以使用as <prefix>-*语句,为子模块下的成员自动带上前缀以区分。

c.scss


@forward "a" as mixin-*;
@forward "b" as var-*;

index.css

@import "c.scss";

.button {
    @include mixin-rounded;
    padding: $var-radius;
}

很多内置的方法就是这样使用的,嘿嘿!

@at-root

@at-root用来跳出嵌套,在多级嵌套时比较常用,包含withoutwith

用法

//没有跳出
.parent-1 {
    color:#f00;
    .child {
        width:100px;
    }
}

//单个选择器跳出
.parent-2 {
    color:#f00;
    @at-root .child {
        width:200px;
    }
}

//多个选择器跳出
.parent-3 {
    background:#f00;
    @at-root {
        .child1 {
            width:300px;
        }
        .child2 {
            width:400px;
        }
    }
}

编译为

.parent-1 {
    color: #f00;
}
.parent-1 .child {
    width: 100px;
}

.parent-2 {
    color: #f00;
}
.child {
    width: 200px;
}

.parent-3 {
    background: #f00;
}
.child1 {
    width: 300px;
}

.child2 {
    width: 400px;
}

@without和with

默认@at-root只会跳出选择器嵌套,而不能跳出@media@support,如果要跳出这两种,则需使用@at-root (without: media)@at-root (without: support)@at-root的关键词有四个:

  1. all 表示所有;
  2. rule 表示常规css选择器;
  3. media 表示media
  4. support表示support@support主要是用于检测浏览器是否支持css的某个属性)。

我们默认的@at-root@at-root (without:rule)

/*跳出父级元素嵌套*/
@media print {
    .parent1{
        color:#f00;
        @at-root .child1 {
            width:200px;
        }
    }
}

/*跳出media嵌套,父级有效*/
@media print {
    .parent2{
        color:#f00;
        @at-root (without: media) {
            .child2 {
                width:200px;
            }
        }
    }
}

/*跳出media和父级*/
@media print {
    .parent3{
        color:#f00;
        @at-root (without: all) {
            .child3 {
                width:200px;
            }
        }
    }
}

编译成

/*跳出父级元素嵌套*/
@media print {
    .parent1 {
        color: #f00;
    }
    .child1 {
        width: 200px;
    }
}
/*跳出media嵌套,父级有效*/
@media print {
    .parent2 {
        color: #f00;
    }
}
.parent2 .child2 {
    width: 200px;
}
/*跳出media和父级*/
@media print {
    .parent3 {
        color: #f00;
    }
}
.child3 {
    width: 200px;
}

@at-root与 & 配合使用

.child{
    @at-root .parent &{
        color:#f00;
    }
}

编译成

.parent .child {
    color: #f00;
}

应用于@keyframe

.demo {
    animation: motion 3s infinite;
    @at-root {
        @keyframes motion {
        }
    }
}

编译成

.demo {
    animation: motion 3s infinite;
}
@keyframes motion {}

Scss内置扩展

scss内置扩展分为color list map math meta selector string等,扩展也就是scss内置的一些function,每个模块下内容比较多,这里用一些常用的进行举例。

内置函数可以使用@use模块化引入,也可以直接使用他提供的全局函数名调用,以下两种方式是一样的。

@use 'sass:list';
p {
    color: nth($list: red blue green, $n: 2); // blue
    color: list.nth($list: red blue green, $n: 2); // blue
}

color

scss包含很多操作颜色的函数。例如lighten()darken()可用于调亮或调暗颜色,opacify()使颜色透明度减少,transparent()使颜色透明度增加,mix()用来混合两种颜色。

.p1 {
    // 让颜色变亮
    color:scale-color(#5c7a29, $lightness: +30%);
}

.p2 {
    // 让颜色变暗
    color:scale-color(#5c7a29, $lightness: -15%);
}

.p3 {
    // 降低颜色透明度
    color:scale-color(#5c7a29, $alpha: -40%);
}

编译为

.p1 {
    color: #95c249;
}

.p2 {
    color: #4e6823;
}

.p3 {
    color: rgba(92, 122, 41, 0.6);
}

String

scss有许多处理字符串的函数,比如向字符串添加引号的quote()、获取字符串长度的string-length()和将内容插入字符串给定位置的string-insert()

p {
    &:after {
        content: quote(这是里面的内容);
    }
    background-color: unquote($string: "#F00");
    z-index:str-length("scss学习");
}

编译为

p {
    background-color: #F00;
    z-index: 6;
}
p:after {
    content: "这是里面的内容";
}

Math

数值函数处理数值计算,例如:percentage()将无单元的数值转换为百分比,round()将数字四舍五入为最接近的整数,min()max()获取几个数字中的最小值或最大值,random()返回一个随机数。

p {
    z-index: abs(-15); // 15
    z-index: ceil(5.8); //6
    z-index: max(5, 1, 6, 8, 3); //8
    opacity: random(); // 随机 0-1
}

编译为

p {
    z-index: 15;
    z-index: 6;
    z-index: max(5, 1, 6, 8, 3);
    opacity: 0.8636254167;
}

List

List函数操作Listlength()返回列表长度,nth()返回列表中的特定项,join()将两个列表连接在一起,append()在列表末尾添加一个值。

p {
    z-index: length(12px); //1
    z-index: length(12px 5px 8px); //3
    z-index: index(a b c d, c); //3
    padding: append(10px 20px, 30px); // 10px 20px 30px
    color: nth($list: red blue green, $n: 2); // blue
}

编译为

p {
    z-index: 1;
    z-index: 3;
    z-index: 3;
    padding: 10px 20px 30px;
    color: blue;
}

Map

Map函数操作Mapmap-get()根据键值获取map中的对应值,map-merge()来将两个map合并成一个新的mapmap-values()映射中的所有值。

$font-sizes: ("small": 12px, "normal": 18px, "large": 24px);
$padding:(top:10px, right:20px, bottom:10px, left:30px);
p {
    font-size: map-get($font-sizes, "normal"); //18px
    @if map-has-key($padding, "right") {
        padding-right: map-get($padding, "right");
    }
    &:after {
        content: map-keys($font-sizes) + " "+ map-values($padding) + "";
    }
}

编译为

p {
    font-size: 18px;
    padding-right: 20px;
}
p:after {
    content: '"small", "normal", "large" 10px, 20px, 10px, 30px';
}

selector

选择符相关函数可对选择css进行一些相应的操作,例如:selector-append()可以把一个选择符附加到另一个选择符,selector-unify()将两组选择器合成一个复合选择器。

@use 'sass:selector';

@debug selector.is-superselector("a", "a"); // true

// 可以直接使用@forward下的前缀
@debug selector-append("a", ".disabled"); // a.disabled
@debug selector-extend("a.disabled", "a", ".link"); // a.disabled, .link.disabled

.header {
    content: selector-append(".a", ".b", ".c") + '';
    content: selector-unify("a", ".disabled") + '';
}

编译为

.header {
    content: ".a.b.c";
    content: "a.disabled";
}

meta

meta提供一个mixin和一些原子级别的function,比如使用meta.calc-args获取方法的参数,meta.calc-name获取方法名。

meta.load-css

meta.load-css($url,$with:())mixin可以把$urlcss样式全部包含进来。注意,$url引入的函数,变量和mixinmeta.load-css()后的scss中并不能用,它只会返回编译后的css代码。它的第二个参数可以修改使用了!default的变量。

src/corners

$border-contrast: false !default;

code {
    background-color: #6b717f;
    color: #d2e1dd;
    @if $border-contrast {
        border-color: #dadbdf;
    }
}

index.scss

@use "sass:meta";

body.dark {
    @include meta.load-css("src/corners", $with: ("border-contrast": true));
}

编译为

body.dark code {
    background-color: #6b717f;
    color: #d2e1dd;
    border-color: #dadbdf;
}

function

@use "sass:meta";

@debug meta.calc-args(calc(100px + 10%)); // unquote("100px + 10%")
@debug meta.calc-args(clamp(50px, var(--width), 1000px)); // 50px, unquote("var(--width)"), 1000px

@debug meta.calc-name(calc(100px + 10%)); // "calc"
@debug meta.calc-name(clamp(50px, var(--width), 1000px)); // "clamp"

调试相关

@debug

@debug打印表达式的值,方便调试。

$font-sizes: 10px + 20px;
    $style: (
        color: #bdc3c7
    );
.container {
    @debug $style;
    @debug $font-sizes;
}

@error

@error显示致命错误

$colors: (
    blue: #c0392b,
    black: #2980b9
);

@function style-variation($style) {
    @error "Invalid color: '#{$style}'.";
    @if map-has-key($colors, $style) {
        @return map-get($colors, $style);
    }
}

.container {
    color: style-variation(white);
}

@warn

@warn显示警告性建议,会显示堆栈信息。

$colors: (
    blue: #c0392b,
    black: #2980b9
  );

@function style-variation($style) {
    @warn "Invalid color: '#{$style}'.";
    @if map-has-key($colors, $style) {
        @return map-get($colors, $style);
    }
}

.container {
    color: style-variation(white);
}

自检函数

自检相关函数,属于内置扩展meta下的方法,feature-exists()检查当前scss版本是否存在某个特性,variable-exists()检查当前作用域中是否存在某个变量,mixin-exists()检查某个mixin是否存在。自检函数通常用在代码的调试上,返回的是个布尔值。

$color:#F00;
@mixin padding($left:0, $top:0, $right:0, $bottom:0) {
    padding: $top $right $bottom $left;
}

.container {
    @if variable-exists(color) {
        color: $color;
    }
    @else {
        content: "$color不存在";
    }
    @if mixin-exists(padding) {
        @include padding($left: 10px, $right: 10px);
    }
}

编译为

.container {
    color: #F00;
    padding: 0 10px 0 10px;
}

结语

「看了这么久了,辛苦了,不过我也写了很久啦,大佬不妨点个赞再走吧。」

Reference

[1]https://link.juejin.cn/?target=https%3A%2F%2Fwww.yuque.com%2Fistao: https://link.juejin.cn/?target=https%3A%2F%2Fwww.yuque.com%2Fistao

[2]https://www.sass.hk/: https://link.juejin.cn/?target=https%3A%2F%2Fwww.sass.hk%2F

[3]https://sass-lang.com/documentation: https://link.juejin.cn/?target=https%3A%2F%2Fsass-lang.com%2Fdocumentation

[4]https://www.sass.hk/css2sass/: https://link.juejin.cn/?target=https%3A%2F%2Fwww.sass.hk%2Fcss2sass%2F

[5]https://www.sassmeister.com/: https://link.juejin.cn/?target=https%3A%2F%2Fwww.sassmeister.com%2F

[6]https://sass-lang.com/documentation/values/functions: https://link.juejin.cn/?target=https%3A%2F%2Fsass-lang.com%2Fdocumentation%2Fvalues%2Ffunctions

[7]https://sass-lang.com/install: https://link.juejin.cn/?target=https%3A%2F%2Fsass-lang.com%2Finstall

[8]https://juejin.cn/post/7048882600189886494: https://juejin.cn/post/7048882600189886494

[9]https://juejin.cn/post/7050360669316579341: https://juejin.cn/post/7050360669316579341

[10]https://juejin.cn/post/7049919311804104717: https://juejin.cn/post/7049919311804104717

[11]https://juejin.cn/post/7041097839711092744: https://juejin.cn/post/7041097839711092744

[12]https://juejin.cn/post/7028865719102079012: https://juejin.cn/post/7028865719102079012

本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/klfGf9v48Ne1i0bdZo8sUw

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  237227次阅读
vscode超好用的代码书签插件Bookmarks 2年以前  |  8063次阅读
 目录