CSS - 邂逅CSS

500 阅读10分钟

CSS表示层叠样式表(Cascading Style Sheet,简称:CSS) 是为网页添加样式的代码

CSS 也不是真正的编程语言,甚至不是标记语言。它是一门样式表语言

CSS的出现是为了美化HTML的,并且让结构(HTML)与样式(CSS)分离

  • 为HTML添加各种各样的样式,比如颜色、字体、大小、下划线等等
  • 对HTML进行布局,按照某种结构显示(CSS进行布局 – 浮动、flex、grid)

早期的网页都是通过HTML来编写的,但是我们希望HTML面可以更加丰富:

  • 这个时候就增加了很多具备特殊样式的元素:比如i、strong、del等等
  • 后来也有不同的浏览器实现各自的样式语言,但是没有统一的规划
  • 1994年,哈肯·维姆·莱和伯特·波斯合作设计CSS,在1996年的时候发布了CSS1
  • 直到1997年初,W3C组织才专门成立了CSS的工作组,1998年5月发布了CSS2
  • 在2006~2009非常流行 “DIV+CSS”布局的方式来替代所有的html标签
  • 从CSS3开始,所有的CSS分成了不同的模块(modules),每一个“modules”都有于CSS2中额外增加的功能,以及向后兼容
  • 直到2011年6月7日,CSS 3 Color Module终于发布为W3C Recommendation。

编写规则

语法规则

LCgadL.png

声明(Declaration)一个单独的CSS规则,如 color: red; 用来指定添加的CSS样式

  • 属性名(Property name):要添加的css规则的名称
  • 属性值(Property value):要添加的css规则的值

编写位置

CSS提供了3种方法,可以将CSS样式应用到元素上:

  1. 内联样式(inline style)
  2. 内部样式表(internal style sheet)
  3. 外部样式表(external style sheet)

内联样式

在原生的HTML编写过程中确实这种写法是不推荐的

在Vue的template中某些动态的样式是会使用内联样式的

内联样式表存在于HTML元素的style属性之中

CSS样式之间用分号;隔开,建议每条CSS样式后面都加上分号;

虽然最后一个样式的最后的分号可以省略 但是约定俗称 推荐加上最后一个样式的分号

 <div style="color: red; font-size: 40px;">content</div>

内部样式

如果将所有的样式全部使用内联样式来进行编写 会导致以下几个问题

  1. 样式过多 会导致代码的可读性变差
  2. 如果某些元素存在共同的样式,如果使用行内样式来进行样式的编写 会导致重复的样式代码过多

所以 CSS 提供了内部样式 的编写位置

即将CSS放在HTML文件<head>元素里的<style>元素之中

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    /* 通过选择器 将样式和元素进行关联 */
    .dv {
      color: red;
      font-size: 40px;
    }
  </style>
</head>
<body>
  <div class="dv">content</div>
</body>
</html>

外部样式

如果使用内部样式,其存在如下缺点:

  1. 全部都使用内部样式,会导致代码会变得越来越庞大,所以需要对CSS进行抽离,实现结构和样式的分离
  2. 如果某些样式在多个html页面中都存在,那么内部样式必然无法实现样式的复用

所以外部样式表(external style sheet) 是将css编写在一个后缀名为.css的独立文件中,并且通过<link>元素引入进来

使用外部样式表主要分成两个步骤:

第一步:将css样式在一个独立的css文件中编写(后缀名为.css)

第二步:通过<link>元素引入进来

css文件

.dv {
  color: red;
  font-size: 40px;
}

html文件

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!--
    link标签 --- 专门用来引入外部资源
    href --- hypertext reference
    rel --- relationship
  -->
  <link rel="stylesheet" href="./style.css">
</head>
<body>
  <div class="dv">content</div>
</body>
</html>

@import

如果存在多个外部css文件,一个个逐步引入

如果css文件过多,会导致引入的css文件之间难以进行管理

所以css内部一个@import关键字,可以在一个css文件中引入另一个css文件

/* 
	以下2种import的使用方式都是正确的
	@import引入的样式必须写在除注释和其它@import语句外的第一行,否则导入样式无效
*/

/*
  使用url函数引入另一个css样式
  1. 路径可以不加引号 --- 加不加无所谓
  2. 因为本质上依旧是css 所以需要以分号结尾
*/
@import url(./foo.css);

/*
  直接使用@import语法进行导入
  不使用url函数, 但是导入的路径必须使用引号包裹
  且必须以分号结尾
*/
@import './baz.css';

注释

/* 这是注释内容 */

补充

link

link元素是外部资源链接元素,规范了文档与外部资源的关系

link元素通常是在head元素中

最常用的链接是样式表(CSS),此外也可以被用来创建站点图标(比如 “favicon” 图标)

link元素常见的属性:

  1. href:此属性指定被链接资源的URL

    • URL 可以是绝对的,也可以是相对的
  2. rel:指定链接类型,常见的链接类型:developer.mozilla.org/zh-CN/docs/…

    • icon: 站点图标

    • stylesheet: CSS样式;

<!-- 引入外部样式表 -->
<link rel="stylesheet" href="./style.css">

<!-- 
	引入站点图标 也就是favicon
	站点的favicon一般推荐使用ico图标,当然png,jpeg格式的图片也是可以的
-->
<link rel="icon" href="./favicon.ico">

<!-- 
	dns-prefetch 在解析网页的时候,提前将对应的域名解析为ip地址
	而不是等到用户去访问某些资源的时候,再去进行解析
-->
<link rel="dns-prefetch" href="http://www.google.com">

<!--
	prefetch 在解析网页的时候,提前去加载对应的资源
-->
<link rel="prefetch" href="./images/avatar.jpg">

css中颜色表示方式

颜色关键字(color keywords)

使用是不区分大小写的标识符,它表示一个具体的颜色

例如 red,blue

有一个特别的关键字 为transparent, 表示的是透明色

例如: 默认的背景色 就是 transparent

其值等价于rbga(0, 0, 0, 0)

有一个特殊的关键字currentColor,或者可以将其理解为一个css变量,

其表示的是,当前元素所设置的颜色

如果当前元素没有设置颜色,那么其使用的就是其父辈盒子上所设置的颜色

如果实在找不到具体的颜色,那么其值就是浏览器的默认颜色

RGB颜色

RGB是一种色彩空间,通过R(red,红色)、G(green,绿色)、B(blue,蓝色)三原色来组成了不同的颜色

也就是通过调整这三个颜色不同的比例,可以组合成其他的颜色

RGB各个原色的取值范围是 0~255

当所有值变成0的时候,也就是rgb(0, 0, 0)的时候表示为黑色

当所有值变成255的时候,也就是rgb(255, 255, 255)的时候表示为白色

rgb的表示方式:

RGB颜色可以通过以#为前缀的十六进制字符和函数(rgb()、rgba())标记表示

或者使用rgb函数来进行表示

  1. 十六进制符号: #RRGGBB[AA]

    • R(红)、G(绿)、B (蓝)和A (alpha 透明度)是十六进制字符(0–9、A–F);
    • A是可选的,A的默认值是ff
    • A的值的计算方式为 255 * rgba中的a中所表示的值
    • 比如,#ff0000等价于#ff0000ff
  2. 十六进制符号: #RGB[A]

    • R(红)、G(绿)、B (蓝)和A (alpha)是十六进制字符(0–9、A–F)
    • 三位数符号(#RGB)是六位数形式(#RRGGBB)的减缩版
    • 四位数符号(#RGBA)是八位数形式(#RRGGBBAA)的减缩版
    • 注意: 只有AABBCC才可以进行缩减成ABC
    • 如果是ABCDEE 是不可以进行缩减的 不可以缩减成ABCDE 也就是缩减后其长度只能为3位或者4位
  3. 函数符: rgb[a](R, G, B[, A])

    • R(红)、G(绿)、B (蓝)的类型为<number>(数字)
    • A(alpha)可以是0到1之间的数字,或者百分比,数字1相当于100%(完全不透明)
    • 对于使用HEX形式表示的颜色在经过浏览器解析之后最终会被转换为rgb[a](R, G, B[, A])的格式

在rbg(aa, bb, cc)中,将aa,bb, cc转换为他们对应的十六进制分别为AA, BB, CC

此时rbg(aa, bb, cc)对应的十六进制表示方式即为#AABBCC

例如 rgb(255, 255, 255) ==> #ffffff

  1. 其它表示方式 --- 了解

    在使用rbga表示颜色的时候,rgb也可以使用百分比表示,只不过此时有几点注意事项:

    1. rbg和alpha之间需要使用 斜杠 进行分割

    2. rbg之间需要使用空格分割,不要使用逗号分割

    3. 在rbg中如果任意一个使用了百分比表示,那么rbg必须全部使用百分比表示法

    4. 如果一个颜色需要表示通明度,那么推荐使用rgba函数,虽然使用rbg函数的效果一致,但是最终经过浏览器的解析后,使用rgb函数表示透明度的方式依旧会被转换为使用rgba函数来表示

      表示方式合法性描述
      rgb(50% 0% 0% / 50%);合法表现形式等价于 rgba(50% 0% 0% / 50%);
      rgb(50% 0% 0% / 0.5);合法表现形式等价于 rgba(50% 0% 0% / 0.5);
      rgb(127 0 0 / 50%);合法表现形式等价于 rgba(127 0 0 / 50%);
      rgb(127 0 0 / 0.5);合法表现形式等价于 rgba(127 0 0 / 0.5);
      rgb(50% 0 0 / 50%);不合法rgb如果其中一个使用了百分比,那么全部都需要使用百分比表示
    /* 以下形式都是合法的 */
    .box {
      color: rgb(50% 50% 50% / 50%);
      color: rgb(127 127 127 / 50%);
      color: rgb(127 127 127 / 0.5);
      /*
      	color: rgba(127, 127, 127, 50%); --- 推荐
      	在效果上,等同于
      	color: rgb(127, 127, 127, 50%); --- 不推荐
      
      	在经过浏览器解析后  rgb(127, 127, 127, 50%); 会被转换为 rgba(127, 127, 127, 50%);
      */
      color: rgba(127, 127, 127, 50%);
    }
    

浏览器渲染html和css的流程

LCjHyG.png

  1. 浏览器去请求对应的html文件

  2. 浏览器逐行去解析对应的html文件

  3. 如果遇到css,那么会去加载对应的css文件

  4. 此时css是不会阻塞页面html的解析 --- 因为html的dom解析和样式解析是可以完成分开的,互不影响

  5. 浏览器加载css后,解析css,解析完毕后形成CSSOM Tree

  6. 在解析css的同时,浏览器将页面结构解析为dom树 --- 以便于表示页面元素的嵌套和层级关系

  7. 当dom树解析完毕的时候, css如果没有解析完毕,此时浏览器会等待css的解析

    当然浏览器存在超时时间( timeout time ),如果超过超时时间,浏览器会抛弃css的解析,直接渲染html

  8. 当dom树和css全部解析完毕后,浏览器会将对应的样式应用到对应的dom节点(dom tree)上,这个过程被称之为附加(attachment)

  9. 附加完毕后,浏览器会形成一颗render tree

  10. 浏览器通过渲染render tree 从而在页面上显示最后的网页效果,这个过程被称之为display

实际渲染后,dom tree 和 render tree 不需要一定保持一致

例如 对于某一个元素设置了display: none的时候

这个元素依旧存在于dom tree中, 但是这个元素不存在于render tree中