# 基础

  • CSS(cascading style sheets,层叠样式表):多个样式可以作用在同一个 html 元素上,同时生效。

  • 将网页内容和样式进行分离

# 书籍推荐

# 引入方式

# inline style

内联样式。在每个 html 标签上面都有一个 style 属性,把 css 和 html 结合在一起,不推荐

<标签名 style="属性1:属性值1; 属性2:属性值2; 属性3:属性值3;"> 内容 </标签名>

# document style sheet

文档样式表,或称作 embed style sheet 即内嵌样式表

将 CSS 代码集中写在 HTML 文档的 <head> 头部标签中,并且用 <style> 标签定义

  • style 标签一般位于 head 标签中,当然理论上他可以放在 HTML 文档的任何地方
  • type="text/css" 在 html5 中可以省略。
  • 只能控制当前的页面,没有彻底分离
<head>
  <style>
    选择器(选择的标签) {
      属性1: 属性值1;
      属性2: 属性值2;
      属性3: 属性值3;
    }
  </style>
</head>

# external style sheet

外部样式表。将所有的样式放在一个或多个以**.css为扩展名的外部样式表文件中,通过<link>标签**将外部样式表文件链接到 HTML 文档中

  • link 是个单标签
  • link 标签需要放在 head 头部标签中,并且指定 link 标签的三个属性
  • 可以样式共享,复用
  • 可以使用到浏览器的缓存机制,从而加快网页的加载速度,提高用户的体验
<head>
  <link rel="stylesheet" href="css文件路径" />
</head>
属性 作用
rel 定义当前文档与被链接文档之间的关系,在这里需要指定为“stylesheet”,表示被链接的文档是一个样式表文件。
href 定义所链接外部样式表文件的 URL,可以是相对路径,也可以是绝对路径。
type 定义所链接文档的类型,在这里需要指定为“text/css”,表示链接的外部文件为 CSS 样式表。我们都可以省略

注意

在 external style sheet 的外部 CSS 文件中,有时有必要设置 CSS 文件的编码(如使用font-family的中文字体时)

@charset "UTF-8"; /*可在首行添加*/

style 标签中也可以引入外部 CSS 文件。还可以在 CSS 文件中引入其他 CSS 文件

对比来说使用 linkimport效率高,在现代框架中使用很多import是因为可以打包重新编译生成

<style>
  /* 二选一 */
  @import url(./css/style.css);/*也可以用引号括起来*/
  @import "./css/style.css";
</style>

# 总结

优先级相同的设置,由上到下,由外到内,优先级由低到高。 **后加载的优先级高,**就近原则或叠加

样式表 优点 缺点 使用情况 控制范围
内联样式 书写方便,权重高 没有实现样式和结构相分离 较少 控制一个标签(少)
内嵌样式 部分结构和样式相分离 没有彻底分离 较多 控制一个页面(中)
外链样式 完全实现结构和样式相分离 需要引入 最多,强烈推荐 控制整个站点(多)

# 选择器

可以通过 CSS Diner 练习

# 通用(通配符)选择器

匹配所有元素,降低页面响应速度,效率低,即使在清除样式时也应该所有元素都写上。

* {
  属性1: 属性值1;
  属性2: 属性值2;
  属性3: 属性值3;
}

# id 选择器

#idName {
  属性1: 属性值1;
  属性2: 属性值2;
  属性3: 属性值3;
}

# class 选择器

.class-name {
  属性1: 属性值1;
  属性2: 属性值2;
  属性3: 属性值3;
}

推荐使用中划线命名

# 元素选择器

元素名 {
  属性1: 属性值1;
  属性2: 属性值2;
  属性3: 属性值3;
}

# 属性选择器

使用场景:input 标签等。可以利用正则。如下 value 要加引号,即属性怎么写就怎么复制过来

属性 选择
[attr]🔥 带有以 attr 命名的属性的元素
[attr=value]🔥 带有以 attr 命名的,且值为 " value" 的属性的元素
[attr^=value] 表示带有以 attr 命名的,且值是以"value"开头的属性的元素。正则开始符号
[attr$=value] 表示带有以 attr 命名的,且值是以"value"结尾的属性的元素。正则结束符号
[attr*=value]🔥 表示带有以 attr 命名的,且值包含有"value"的属性的元素,不一定非要空格隔开
[attr~=value] 带有以 attr 命名的属性的元素,并且该属性是一个以空格作为分隔的值列表,其中至少一个值为"value"
[attr|=value] 带有以 attr 命名的属性的元素,属性值为“value”或是以“value-”为前缀("-"为连字符,Unicode 编码为 U+002D)开头。用来匹配lang简写代码(如 zh-CN,zh-TW 可以用 zh 作为 value)
[attr operator value i] 在带有属性值的属性选型选择器表达式的右括号(]括号)前添加用空格间隔开的字母 i(或 I)可以忽略属性值的大小写(ASCII 字符范围内的字母)

属性选择器可以配合其他选择器一起使用

若属性选择器写作[class~=value]则和类选择器表示一致

<style>
  [title] {
    font-size: 16px;
  }

  [title="p"] {
    color: skyblue;
  }

  [title*="pp"] {
    background-color: yellow;
  }
</style>
<div title="div">div1</div>
<p title="p">p1</p>
<p title="p pp">p2</p>
<div title="div">div2</div>

# 组合选择器

可以为任何选择器组合。下面除了并集、交集选择器,都是选择元素B

组合 选择
A, B 并集选择器(选择所有 A 元素和 B 元素
A.B 交集选择器div.one,选择class 属性包含onediv元素)
A B 后代选择器(选择 A 元素里面的所有 B 元素,A 可能多个,即使 A 一个,选择的 B 也可能多个)
A > B 儿子选择器(选择 A 元素里面的所有直接 B 元素,A 可能多个,即使 A 一个,选择的 B 也可能多个)
A ~ B 一般兄弟选择器B 是 A之后所有兄弟节点,A 可能多个,即使 A 一个,选择的 B 也可能多个
A + B 相邻兄弟选择器B 是 A 之后紧挨着的兄弟节点,A 可能多个,所以选择的 B 可能多个;否则 B 只有一个

# 伪类选择器 :

Pseudo(伪类)。添加到选择器的关键字,指定要选择的元素的特殊状态

# 动态伪类 🔥

  • :link 未被访问,可用于a,注意缓存引起的问题(通过时间戳可以解决)

  • :visited 已被访问,可用于a。由于隐私问题,只能用于修改a的颜色

  • :focus 拥有输入焦点的元素(能接收键盘输入)

    可用于除过hiddenradiocheckboxfileinput元素,selecttextareaa也可以使用

  • :hover 鼠标悬浮,常用,可用于任意元素

  • :active 鼠标点击不放(按下未弹起),可用于任意元素

注意

  • 为了确保生效,请按照 LVFHA 顺序声明(上面的顺序)
  • 因为 a 标签在浏览器中有默认样式,所以必须单独给 a 标签的单独伪类设置样式才能生效,且不能直接给a设置样式,否则造成给a的所有动态伪类设置了同一个样式!实际开发中就给 a 标签一个样式,再给 a:hover 一个样式即可足够

# 元素状态伪类 🔥

注意

不仅仅是input 标签,selecttextarea 之类也可以

  • :focus 看动态伪类
  • :checked 被选中,可用于input
  • :disabled禁用,可用于buttoninput

# 结构伪类 🔥

选择器 例子 例子描述 CSS
:first-child🔥 p:first-child 选择属于其父元素的第一个子元素的为<p>的每个 <p> 元素。可能多个,因为每个节点都有可能是父元素。 2
:last-child🔥 p:last-child 选择属于其父元素的最后一个子元素为<p>的每个 <p> 元素。可能多个,因为每个节点都有可能是父元素。 3
:nth-child(n)🔥 p:nth-child(2);
n 也可以是关键字;
n 也可以是公式;
选择属于其父元素的第二个子元素的每个<p> 元素。
隔行换色,括号中参数替换为:even 偶数、odd 奇数。
2n,2n+1 等等。n 会从 0 开始(但是HTML中顺序是从1开始)
-n+5 代表0~5,排行榜中会使用
3
:nth-last-child(n) p:nth-last-child(2) 同上,从最后一个子元素开始计数。 3
:first-of-type🔥 p:first-of-type 选择属于其父元素的首个 <p> 元素的每个<p>元素。 3
:last-of-type🔥 p:last-of-type 选择属于其父元素的最后<p> 元素的每个 <p> 元素。 3
:nth-of-type(n)🔥 p:nth-of-type(2) 选择属于其父元素第二个 <p> 元素的每个 <p> 元素。 3
:nth-last-of-type(n) p:nth-last-of-type(2) 同上,但是从最后一个子元素开始计数。 3
:only-child🔥 body:only-child 父元素中该子元素只有一个!。<body>父元素的唯一子元素;不推荐直接写:only-child否则会造成选择了全部元素,因为<html>也属于Document的唯一子元素
:only-of-type🔥 body:only-of-type 父元素中该类型子元素只有一个!。<body>父元素中唯一该类型的子元素。
:root 根元素<html>,与直接写html{}效果一致
:empty 选择内容(html或文本)为空的元素,空格也算内容。为了显示可以给定一个高度和背景色

注意

:nth-child(n) 与 :nth-of-type(n) 都需要先获取到其父元素,区别在于

  • :nth-child(n) 先将所有子元素排序,然后找到符合 n 的,再找到匹配该子元素的(此时可能不匹配)
  • :nth-of-type(n) 先将指定的子元素排序,然后找到符合 n 的

注意 和后代选择器结合 以及 和交集选择器结合 时的区别

:nth-child(n)示例

<style>
  /*所有只要是第三个子元素*/
  /*:nth-child(3) {
  color: skyblue;
  }*/
  p:nth-child(3) {
    color: skyblue;
  }
</style>
<body>
  <div>
    <p>test1</p>
    <p>test2</p>
    <p>test3</p>
    <p>test4</p>
  </div>
  <div>
    <strong>strong1</strong>
    <strong>strong2</strong>
    <strong>strong3</strong>
    <strong>strong4</strong>
  </div>
  <p>
    <span>span1</span>
    <span>span2</span>
    <span>span3</span>
    <span>span4</span>
  </p>
</body>

# 目标伪类—锚点

很少使用

<style>
  :target {
    color: skyblue;
  }
</style>
<a href="#title1">去标题1</a>
<a href="#title2">去标题2</a>
<a href="#title3">去标题3</a>
<a href="#title4">去标题4</a>
<h3 id="title1">标题1</h3>
<h3 id="title2">标题2</h3>
<h3 id="title3">标题3</h3>
<h3 id="title4">标题4</h3>

# 空伪类

:empty

/* 选择所有空的 div 元素,即 div 里是空的 */
div:empty{
  
}

# 否定伪类

基本上不用

:not(x):x 可以是id、class、元素、通用、属性、伪类(除否定伪类)选择器。不支持组合选择器

/* body下除了 div 的其他元素 */
body :not(div){
  color: red;
}

/* 除了第三个li */
ul > li:not(:nth-of-type(3)){
  
}

# 语言伪类

基本上不用

# 伪元素选择器 ::

# 介绍

伪元素选择器可以帮助我们利用 CSS 创建新标签元素,而不需要 HTML 标签,从而简化 HTML 结构。

可以用:::,但是推荐使用前者,可以区别伪类和伪元素。

选择器 例子 例子描述 CSS
::first-letter p::first-letter 选择每个 <p> 元素内容的首字母。有属性设置限制 1
::first-line p::first-line 选择每个 <p> 元素内容的首行。有属性设置限制 1
::selection p::selection 选择每个 <p> 元素中被选中的字符 4
::before🔥 p::before 在每个 <p> 元素的内容之前插入内容,可以是文字、图片。 2
::after🔥 p::after 在每个 <p> 元素的内容之后插入内容,可以是文字、图片。 2

注意

  • before 和 after 创建一个元素,但是属于行内元素,且无法选中
  • 新创建的这个元素在文档树中是找不到的,所以我们称为伪元素
  • before 和 after 必须有 content 属性,可以是文字(直接写字符串)或图片url()
  • before 在父元素里面内容的前面创建元素,after 在父元素里面内容的后面插入元素
  • 伪元素选择器和标签选择器一样,权重为 1
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>

    <style>
      div {
        width: 200px;
        height: 200px;
        background-color: pink;
      }
      div::before {
        content: "111";
      }
      div::after {
        content: "999";
      }
    </style>
  </head>

  <body>
    <div>666</div>
  </body>
</html>

效果如下:

image-20200101142722750

# 伪元素字体图标

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <style>
      div {
        position: relative;
        width: 200px;
        height: 35px;
        border: 1px solid skyblue;
      }

      div::after {
        position: absolute;
        top: 7px;
        right: 10px;
        /* 可以用字体图标代替 */
        content: "x";
      }
    </style>
  </head>

  <body>
    <div></div>
  </body>
</html>

效果如下:

image-20200101144553702

# 仿视频遮罩功能

取代之前写的 mask 类

/* mask遮罩 */
.box .box-body ul li::before {
  /* 必须加content */
  content: "";
  /* 隐藏遮罩 */
  display: none;
  position: absolute;
  width: 228px;
  height: 270px;
  background: rgba(0, 0, 0, 0.4) url(./images/arr.png) no-repeat 100px 60px;
}

/* 鼠标经过li盒子时,才让其中的伪元素显示,和以往不同的写法,注意 */
.box .box-body ul li:hover::before {
  display: block;
}

# 清除浮动

看 float 中代码

# 特性

# 层叠性 🔥

解决样式冲突问题

  • 相同选择器设置相同的样式,此时就近样式就会**覆盖(层叠)**另一个冲突的样式。
  • 不同选择器设置相同的样式,需考虑选择器权重,权重还是相同则发生覆盖(层叠)

    选择器 权重
    继承 或 * 0,0,0,0
    元素(标签)选择器,伪元素选择器 0,0,0,1
    类选择器,伪类选择器,属性选择器 0,0,1,0
    ID 选择器 0,1,0,0
    行内样式 style 1,0,0,0
    !important; 1,0,0,0,0

权重注意点:

  • 权重是有 5 组数字组成,但是不会有进位

  • 等级判断从左向右,如果某一位数值相同,则判断下一位数值。

  • 继承的权重是 0, 如果该元素没有直接选中,不管父元素权重多高,子元素得到的权重都是 0。

    <style>
      #father { 
        color: red; 
      } 
      p { 
        color: pink;
      }
    </style>
    <div id="father">
      <p>此处颜色是pink</p>
    </div>
    
  • a 元素浏览器默认指定了样式,除非手动修改,否则继承父元素不起作用

    <style>
      body { 
        color: red 
      }
    </style>
    <body>
      <a href="#">此处还是蓝色</a>
    </body>
    
  • 权重叠加:如果是复合选择器,则会有权重叠加,需要计算权重。

    • div ul li ===> 0,0,0,3
    • .nav ul li ===> 0,0,1,2
    • a:hover ===> 0,0,1,1。⚠️ 这里是按照 2 个来计算的,属性选择器也是类似
    • .nav a ===> 0,0,1,1
    <style>
      /* .nav li  权重是 11 */
      .nav li {
        color: red;
      }
      /* 需求把第一个小li 颜色改为粉色加粗 ? */
      /* .pink  权重是 10    .nav .pink  20  */
      .nav .pink {
        color: pink;
        font-weight: 700;
      }
    </style>
    
    <ul class="nav">
      <li class="pink">人生四大悲</li>
      <li>家里没宽带</li>
      <li>网速不够快</li>
      <li>手机没流量</li>
      <li>学校没wifi</li>
    </ul>
    

# 继承性 🔥

  • 简化代码。字标签会继承父标签中的某些样式

    font-text-line-list-color 可以被继承,逐个查看 MDN 可知晓

    背景相关的,布局相关等的这些样式都不会被继承

  • 不能继承的属性,一般可以对该属性使用inherit值强制继承

  • 注意:属性继承的是计算值,并不是字面值

    <style>
      .class1 {
        font-size: 60px;
      }
      .class2 {
        font-size: 0.5em;
        /* 此时 p 元素的 font-size 继承的是 30px,不是 .5em,否则会变为 15px */
      }
    </style>
    <div class="class1">
      <div class="class2">
        <p>haha</p>
      </div>
    </div>
    
  • 可以使用开发者工具查看继承来的属性

    body {
      font: 12px/1.5 Microsoft YaHei;
    }
    
    • 行高可以跟单位也可以不跟单位

    • 如果子元素没有设置行高,则会继承父元素的行高为 1.5。此时子元素的行高为当前子元素的文字大小 * 1.5

      body 行高 1.5 这样写法最大的优势就是里面子元素可以根据自己文字大小自动调整行高

# 元素分类

# 块级元素 block element

  • 独占父元素一行,无论是否设置了 width
  • 高度、宽度(默认为父级容器宽度的 100%)、外边距、内边距都可以控制
  • 是一个容器盒子,里面可以放块级元素或行内元素
  • 文字类元素内不能使用块级元素,如 p 里不能放 div

常见的有:h1~h6、p、div、ul、ol、li、table、div 等

# 行内元素 inline element

  • 多个行内元素可以在父元素的同一行中显示,且基线对齐

  • 非替换元素的高、宽直接设置是无效的,默认宽度就是它本身内容的宽度替换元素可以设置

  • 跟其他行内元素在同一行显示,有空白缝隙,这是因为浏览器把空格换行也解析显示了。解决方案如下:

    • 可以一行显示(不推荐)

    • 可以用注释注释掉空格或换行符(不推荐)

      <span>span1</span><!--
      --><span>span2</span>
      
    • 设置父元素的font-size为0,然后在子元素中重新设置自己需要的font-size(不推荐)。Safari 也不支持。

    • 使用float(推荐),浮动后顶部对齐

  • 行内元素只能容纳文本或其他行内元素

  • 链接 a 里面不能再放 a。特殊情况 a 里面可以放块级元素,但是给 a 转换块级模式最安全

  • 为了照顾兼容性,行内元素尽量只设置左右内外边距,不设置上下内外边距。但转换为块级和行内块元素就都可设置

  • 行内元素可以区分替换元素(如img)和非替换元素

常见的有:a、strong、b、em、i、ins、u、del、s、span 等

注意

  • 以下属性对行内非替换元素不起作用,如:width, height

  • 以下属性对行内非替换元素的效果比较特殊

    padding-top, padding-bottom(上下多出的区域不占据DOM空间,即不会影响页面的布局)

    border-top, border-bottom(上下多出的区域不占据DOM空间,即不会影响页面的布局)

    margin-top**, **margin-bottom(上下多出的区域不占据DOM空间,即不会影响页面的布局)

    可以改为inline-block替换元素类型即可解决该问题

# 替换元素

# 非替换元素

# 总结

元素分类 具体元素 默认特征
块元素 替换元素
非替换元素 div, p, pre, h1~h6, ul, ol, li, dl, dt, dd, table, form, article, aside, footer, header, hgroup, main, mav, section, blockquote, hr 等
  • 独占父元素的一行
  • 可以随意设置宽高
  • 宽度默认为父容器100%,高度默认由内容决定
行内元素 替换元素 img, input, iframe, video, audio, embed, canvas, object 等
  • 跟其他行内元素在同一行显示,有空白缝隙
  • 可以随意设置宽高和内外边距
  • 默认宽高由内容决定
非替换元素 a, strong, span, code, label 等
  • 跟其他行内元素在同一行显示,有空白缝隙
  • 不可以随意设置宽高或内外边距
  • 默认宽高由内容决定
可以通过`display`属性改变

# 函数

# calc 计算

此 CSS 函数让你在声明 CSS 属性值时执行一些计算

width: calc(100% - 80px);

括号里面可以使用 + - * / 来进行计算