CSS

226 阅读9分钟

1)、CSS 的顶层样式表

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

    • 所有@规则

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

         @charset "utf-8";
      
    • @import 用于引入一个 CSS 文件,除了 @charset 规则不会被引入,@import 可以引入另一个文件的全部内容。

         @import "mystyle.css";
         @import url("mystyle.css");
      
    • @media 就是大名鼎鼎的 media query 使用的规则了,它能够对设备的类型进行一些判断。在 media 的区块内,是普通规则列表。

         @media print {
             body { font-size: 10pt }
         }
      
    • @page 用于分页媒体访问网页时的表现设置,页面是一种特殊的盒模型结构,除了页面本身,还可以设置它周围的盒。

         @page {
           size: 8.5in 11in;
           margin: 10%;
      
           @top-left {
             content: "Hamlet";
           }
           @top-right {
             content: "Page " counter(page);
           }
         }
      
    • @counter-style 产生一种数据,用于定义列表项的表现。

          @counter-style triangle {
           system: cyclic;
           symbols: ‣;
           suffix: " ";
         }
      
    • @fontface 用于定义一种字体,icon font 技术就是利用这个特性来实现的。

         @font-face {
           font-family: Gentium;
           src: url(http://example.com/fonts/Gentium.woff);
         }
      
         p { font-family: Gentium, serif; }
      
    • @support 检查环境的特性,它与 media 比较类似。

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

    • @viewport 用于设置视口的一些特性,不过兼容性目前不是很好,多数时候被 HTML 的 meta 代替

    • @keyframes 产生一种数据,用于定义动画关键帧。

         @keyframes diagonal-slide {
           from {
             left: 0;
             top: 0;
           }
      
           to {
             left: 100px;
             top: 100px;
           }
      
         }
      
  • qualified rule 规则(普通规则) 主要是由选择器和声明区块构成。声明区块又由属性和值构成

    • 选择器:www.w3.org/TR/selector…

    • 声明(属性和值):www.w3.org/TR/css-vari…

      • 属性是由中划线、下划线、字母等组成的标识符,CSS 还支持使用反斜杠转义。我们需要注意的是:属性不允许使用连续的两个中划线开头,这样的属性会被认为是 CSS 变量。

      • 在 CSS Variables 标准中,以双中划线开头的属性被当作变量,与之配合的则是 var 函数:

        
           :root {
             --main-color: #06c;
             --accent-color: #006;
           }
           /* The rest of the CSS file */
           #foo h1 {
             color: var(--main-color);
           }
        
    • 值的部分,主要在标准 CSS Values and Unit,根据每个 CSS 属性可以取到不同的值,这里的值可能是字符串、标识符。CSS 属性值可能是以下类型。

      • CSS 范围的关键字:initial,unset,inherit,任何属性都可以的关键字。
      • 字符串:比如 content 属性。
      • URL:使用 url() 函数的 URL 值。
      • 整数 / 实数:比如 flex 属性。
      • 维度:单位的整数 / 实数,比如 width 属性。
      • 百分比:大部分维度都支持。
      • 颜色:比如 background-color 属性。
      • 图片:比如 background-image 属性。
      • 2D 位置:比如 background-position 属性。
      • 函数:来自函数的值,比如 transform 属性。一些属性会要求产生函数类型的值,比如 easing-function 会要求 cubic-bezier() 函数的值:CSS 支持一批特定的计算型函数:
        • max()
        • min()
        • clamp():则是给一个值限定一个范围,超出范围外则使用范围的最大或者最小值
        • toggle()
        • attr()
        • calc() :基本的表达式计算,它支持加减乘除四则运算。在针对维度进行计算时,calc() 函数允许不同单位混合运算,这非常的有用。例如:
             section {
               float: left;
               margin: 1em; border: solid 1px;
               width: calc(100%/3 - 2*1em - 2*1px);
             }
          

2)、CSS 选择器

选择器的基本意义是:根据一些特征,选中元素树上的一批元素。我们把选择器的结构分一下类,那么由简单到复杂可以分成以下几种。

  • 简单选择器:针对某一特征判断是否选中元素。

    • 【类型选择器和全体选择器】:根据一个元素的标签名来选中元素

          div {
      
          }
          //svg 和 HTML 中都有 a 元素,我们若要想区分选择 svg 中的 a 和 HTML中的a,就必须用带命名空间的类型选择器。
          svg|a {
               stroke:blue;
               stroke-width:1;
          }
          html|a {
               font-size:40px;
          }
      
    • 【id 选择器与 class 选择器】:id 选择器和 class 选择器都是针对特定属性的选择器。id 选择器是“#”号后面跟随 id 名,class 选择器是“.”后面跟随 class 名。

    • 【属性选择器】:根据 HTML 元素的属性来选中元素。

      • [att]:直接在方括号中放入属性名,是检查元素是否具有这个属性,只要元素有这个属性,不论属性是什么值,都可以被选中。
      • [att=val]精确匹配,检查一个元素属性的值是否是 val。
      • [att~=val]多种匹配,检查一个元素的值是否是若干值之一,这里的 val 不是一个单一的值了,可以是用空格分隔的一个序列。
      • [att|=val]开头匹配,检查一个元素的值是否是以 val 开头,它跟精确匹配的区别是属性只要以 val 开头即可,后面内容不管。
    • 【伪类选择器】:是一系列由 CSS 规定好的选择器,它们以冒号开头。伪类选择器有普通型和函数型两种。

      • 结构关系伪类选择器: root 伪类表示树的根元素,在选择器是针对完整的 HTML 文档情况,我们一般用 HTML 标签即可选中根元素。但是随着 scoped css 和 shadow root 等场景出现,选择器可以针对某一子树来选择,这时候就很需要 root 伪类了。
        • :empty 伪类表示没有子节点的元素,这里有个例外就是子节点为空白文本节点的情况。
        • :nth-child 和 :nth-last-child 这是两个函数型的伪类,CSS 的 An+B 语法设计的是比较复杂的,我们这里仅仅介绍基本用法。
        • :nth-last-child 的区别仅仅是从后往前数。
        • :first-child :last-child 分别表示第一个和最后一个元素。
        • :only-child 按字面意思理解即可,选中唯一一个子元素。
        • of-type 系列,是一个变形的语法糖,S:nth-of-type(An+B) 是:nth-child(|An+B| of S) 的另一种写法。以此类推,还有 nth-last-of-type、first-of-type、last-of-type、only-of-type。
      • 链接与行为伪类选择器:
        • :any-link 表示任意的链接,包括 a、area 和 link 标签都可能匹配到这个伪类。
        • :link 表示未访问过的链接,
        • :visited 表示已经访问过的链接。
        • :hover 表示鼠标悬停在上的元素。
        • :active 表示用户正在激活这个元素,如用户按下按钮,鼠标还未抬起时,这个按钮就处于激活状态。
        • :focus 表示焦点落在这个元素之上。
        • :target 用于选中浏览器 URL 的 hash 部分所指示的元素。
    • 【逻辑伪类选择器】:not 伪类

           *|*:not(:hover)
      
    • 【其他伪类选择器】

      • 国际化:用于处理国际化和多语言问题。
      • dirlang 音频 / 视频:用于区分音视频播放状态。play、pause
      • 时序:用于配合读屏软件等时序性客户端的伪类。current、 past、 future
      • 表格:用于处理 table 的列的伪类。nth-col、nth-last-col
  • 复合选择器:连续写在一起的简单选择器,针对元素自身特征选择单个元素根据选择器列表的语法,选择器的连接方式,可以理解为像四则运算一样有优先级。

    • 第一优先级无连接符号
    • 第二优先级“空格”“~”“+”“>”“||”
    • 第三优先级“,”
  • 复杂选择器:由“(空格)”“ >”“ ~”“ +”“ ||”等符号连接的复合选择器,根据父元素或者前序元素检查单个元素, 复杂选择器是针对节点关系的选择,它规定了五种连接符号:

    • “空格”:后代,表示选中所有符合条件的后代节点, 例如“ .a .b ”表示选中所有具有 class 为 a 的后代节点中 class 为 b 的节点。
    • “>” :子代,表示选中符合条件的子节点,例如“ .a>.b ”表示:选中所有“具有 class 为 a 的子节点中,class 为 b 的节点”。
    • “~” : 后继,表示选中所有符合条件的后继节点,后继节点即跟当前节点具有同一个父元素,并出现在它之后的节点,例如“ .a~.b ”表示选中所有具有 class 为 a 的后继中,class 为 b 的节点。
    • “+”:直接后继,表示选中符合条件的直接后继节点,直接后继节点即 nextSlibling。例如 “.a+.b ”表示选中所有具有 class 为 a 的下一个 class 为 b 的节点。
    • “||”:列选择器,表示选中对应列中符合条件的单元格。
  • 选择器列表:是用逗号分隔的复杂选择器序列;复杂选择器则是用空格、大于号、波浪线等符号连接的复合选择器;

  • 选择器的优先级

  • id 选择器的数目记为 a;

  • 伪类选择器和 class 选择器的数目记为 b;

  • 伪元素选择器和标签选择器数目记为 c;

  • “*” 不影响优先级。

3)、伪元素

伪元素本身不单单是一种选择规则,它还是一种机制。伪元素的语法跟伪类相似,但是实际产生的效果却是把不存在的元素硬选出来。

  • 目前兼容性达到可用的伪元素有以下几种。

    • ::first-line
    • ::first-letter
    • ::before
    • ::after
  • ::first-line 和 ::first-letter 是比较类似的伪元素,其中一个表示元素的第一行,一个表示元素的第一个字母。我们遇到的 HTML 结构要更为复杂,一旦元素中不是纯文本,规则就变得复杂了。CSS 标准规定了 first-line 必须出现在最内层的块级元素之内。因此,我们考虑以下代码。

       <div>
         <p id=a>First paragraph</p>
         <p>Second paragraph</p>
       </div>
    
       div>p#a {
           color:green;
       }
    
       div::first-line {
           color:blue;
       }
       //这段代码最终结果第一行是蓝色,因为 p 是块级元素,所以伪元素出现在块级元素之内,所以内层的 color 覆盖了外层的 color 属性。
    
       //如果我们把 p 换成 span,结果就是相反的
       <div>
         <span id=a>First paragraph</span><br/>
         <span>Second paragraph</span>
       </div>
       div>span#a {
           color:green;
       }
    
       div::first-line {
           color:blue;
       }
       //这段代码的最终结果是绿色,这说明伪元素在 span 之外。::first-letter 的行为又有所不同,它的位置在所有标签之内,
    

  • ::before 和 ::after 伪元素
    • 这两个伪元素跟前面两个不同的是,它不是把已有的内容套上一个元素,而是真正的无中生有,造出一个元素,
    • ::before 表示在元素内容之前插入一个虚拟的元素,::after 则表示在元素内容之后插入。
    • 要注意一点,::before 和 ::after 还支持 content 为 counter,如:
          <p class="special">I'm real element</p>
          p.special::before {
              display: block;
              content: counter(chapno, upper-roman) ". ";
          }