《重学前端》笔记--CSS语法规则

259 阅读6分钟

本文为winter发布在极客时间的《重学前端》的学习笔记。

大家支持正版喔:time.geekbang.org/column/arti…

导语

我们到W3C上搜索css相关可以得到98份CSS相关的标准,去掉Working Draft状态的标准,可以得到22份候选标准和6份推荐标准。

将这些规则整合之后,可以进行抽象,CSS的顶层样式表有两种规则:

  • at-rule,也就是at 规则
  • qualified rule,也就是普通规则

at 规则

at-rule由一个 @ 关键字和后续的一个区块组成,如果没有区块,则以分号结束。

@charset

@charset用于提示CSS文件使用的字符编码方式,它如果被使用,必须出现在最前面。这个规则只在给出语法解析阶段前使用,并不影响页面上的展示效果。

@charset "utf-8";
@charset "iso-8859-15";

在样式表中有多种方法去声明字符编码,浏览器会按照以下顺序尝试下边的方法(一旦找到就停止并得出结果):

  1. 文件的开头的Unicode byte-order字符值。
  2. 由Content-Type:HTTP header 中的 charset 属性给出的值或用于提供样式表的协议中的等效值。
  3. CSS @规则@charset。使用参考文档定义的字符编码:元素的 charset 属性。该方法在 HTML5 标准中已废除,无法使用。
  4. 假设文档是 UTF-8。

@import

@import用于引入一个CSS文件,在样式表中的所有其他有效规则和样式规则之前(忽略@charset)。除了该文件的@charset信息,其他内容全部引入。

// 格式
@import [ <url> | <string> ]
        [ supports( [ <supports-condition> | <declaration> ] ) ]?
        <media-query-list>? ;

// 示例
@import "mystyle.css";
@import url("mystyle.css");
@import url("fallback-layout.css") supports(not (display: flex));
@import url("narrow.css") handheld and (max-width: 400px);

思考:link 与 @import 的区别?

  • link是html标签,能被dom控制;@import是css方法,不能被dom控制
  • link能通过设置rel来引入其他资源,@import仅能引入css
  • 浏览器对link支持早于@import,@import可能会有兼容性问题

注:在chrome-86版本使用link和@import加载文件,没有出现@import阻塞css现象,两者效果相同,没出现FOUC(即Flash of Unstyled Content,亦浏览器样式闪烁,为css阻塞浏览器渲染导致)。IE中可能会不一样,但是现在没有IE,权做个记录。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title></title>
    <style>
      @import url(./test.css);
      @import url(./test-a.css);
      @import url(./test-b.css);
    </style>
  </head>

@media

@media就是大名鼎鼎的media query使用的规则了,它能够对设备的类型进行一些判断(具体规则可以参考这里)。在media的区块内,是普通规则列表。

@media screen and (min-width: 35em),
       print and (min-width: 40em) {
  #section_navigation { float: left; width: 10em; }
}

@page

@page用于分页媒体访问页面时(打印文档)的表现设置,页面是一种特殊的盒模型结构,除了页面本身,还可以设置它周围的盒。

你不能用@page规则来修改所有的CSS属性,而是只能修改margin,orphans,widow 和 page breaks of the document。对其他属性的修改是无效的。 --MDN,@page

@page {
  size: 8.5in 11in;
  margin: 10%;

  @top-left {
    content: "Hamlet";
  }
  @top-right {
    content: "Page " counter(page);
  }
}

@counter-style

@counter-style产生一种数据,用于定义列表项的表现。也可以参考MDN

@counter-style triangle {
  system: cyclic;
  symbols: ‣;
  suffix: " ";
}

.items {
   list-style: triangle;
}

items类的列表效果如下:

One
‣  Two
‣  Three

@key-frames

@key-frames产生一种数据,用于定义动画关键帧。配合animation-name使用,定义一个物体从开始到结束(0%/from 和100%/to)的动画。 也可以参考MDN

@keyframes diagonal-slide {
  from {
    left: 0;
    top: 0;
  }
  to {
    left: 100px;
    top: 100px;
  }
}

@font-face

@font-face用于定义一种字体,icon font技术就是利用这个特性来实现的。

@font-face {
  font-family: Gentium;
  src: url(http://example.com/fonts/Gentium.woff);
}

p { font-family: Gentium, serif; }

@support

@support可以指定依赖于浏览器中的一个或多个特定的CSS功能的支持声明。这叫特性查询。

@supports at-rule 由一组样式声明和一条支持条件构成。支持条件由一条或多条使用 逻辑与(and)、逻辑或(or)、逻辑非(not)结合的名称-值对(name-value pair)组成。可以使用圆括号调整操作符的优先级。 -- MDN,@support

@supports (transform-origin: 5% 5%) {
	...
}

如果transform-origin: 5% 5%是有效的值,则块内的样式则生效。

@namespace

@namespace用于跟XML命名空间配合的一个规则,表示内部的CSS选择器全都带上特定命名空间。

任何 @namespace 规则都必须在所有的 @charset 和 @import 规则之后, 并且在样式表中,位于其他任何 style declarations 之前。--MDN,@namespace

@namespace 可以用来定义默认命名空间。当定义过默认命名空间后, 所有的通配选择器和类型选择器(但不包括属性选择器,详情看下面的note)都只应用在这个命名空间的元素中。

@namespace 规则也可以用于定义命名空间前缀。当一个通配、类型、属性选择器前面有命名空间前缀修饰时,这个选择器将只匹配那些命名空间与 元素名或属性匹配 的元素。

@namespace url(http://www.w3.org/1999/xhtml);
@namespace svg url(http://www.w3.org/2000/svg);

/* 匹配所有的XHTML <a> 元素, 因为 XHTML 是默认无前缀命名空间 */
a {}

/* 匹配所有的 SVG <a> 元素 */
svg|a {}

/* 匹配 XHTML 和 SVG <a> 元素 */
*|a {}

@viewport

@viewport用于设置视口的一些特性.

该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性。

目前多数时候被HTML的meta代替,可以参考之前的文章

<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">

其它

这里还有一些不太推荐的at规则:

  • @color-profile 是 SVG1.0 引入的CSS特性,但是实现状况不怎么好。
  • @document 还没讨论清楚,被推迟到了CSS4中。
  • @font-feature-values 。

普通规则

普通规则主要是由选择器和声明区块构成。声明区块又由属性和值构成。

选择器

声明:属性和值

值可以分为函数和CSS属性值两种,这里重点介绍一些函数。

CSS支持一批特定的计算型函数:

  • calc() 基本的表达式计算,它支持加减乘除四则运算
  • max() 表示取两数中较大的一个
  • min() 表示取两数之中较小的一个
  • clamp() 是给一个值限定一个范围,超出范围外则使用范围的最大或者最小值
  • toggle() 在规则选中多于一个元素时生效,它会在几个值之间来回切换
  • attr() 返回选择元素的属性值
  • var() 通过--xx的格式来设置一个自定义属性,在值中通过var()来使用该自定义属性
  • rgb() 使用红(R)、绿(G)、蓝(B)三个颜色的叠加来生成各式各样的颜色
  • rgba() 使用红(R)、绿(G)、蓝(B)、透明度(A)的叠加来生成各式各样的颜色
  • linear-gradient() 创建一个线性渐变的图像
  • radial-gradient() 用径向渐变创建图像
  • repeating-linear-gradient() 用重复的线性渐变创建图像
  • repeating-radial-gradient() 用重复的径向渐变创建图像
  • ...

当然,上面的函数是一些常用的,更多的函数可以在这里查询。