Skip to content

构建网站层叠样式表

第一章:CSS 基础

一、CSS3 样式设置规则

一个 CSS 样式设置规则由选择器和声明部分组成。介于“{}”中的所有内容为声明块。声明由属性值和属性两部分组成,其中属性和属性值以键值对形式出现。在遵循 CSS 样式规则同时,还需注意以下几点:

① CSS 样式中的类和 id 选择器严格区分大小写,属性和属性值不区分大小写。

② 多个属性之间必须用英文状态下的分号隔开,最后的分号可省略,但最好不要省略。

③ 如果属性的值由多个单词组成且中间包含空格,则必须为这个属性值加上英文状态下的引号。

二、CSS 样式调用

1. 行内样式表 / 内联样式表:<标签名称 style="样式属性1:属性值1; 样式属性2:属性值2; 样式属性...">

2. 内部样式表 / 嵌入样式表:将样式表通过 <style> 嵌入到 HTML 文件的 <head> 中。

3. 外部样式表 / 链接样式表:<link href="" rel="stylesheet" type="text/css">

CSS 文件如何引用其他 CSS 文件?

css
@import "css文件地址";
@import url('css文件地址');

@import 这种方式称为导入样式表。

@import 和 link 的区别是什么?

1)加载顺序:<link> 是 HTML 的一部分,当浏览器解析 HTML 时,会立即加载和应用 <link> 引入的 CSS。而 @import 是 CSS 的一部分,只有在浏览器加载并解析完包含 @import 的 CSS 文件后,才会去加载和应用 @import 引入的 CSS。因此,使用 @import 可能会导致页面在加载时出现闪烁(FOUC)。

2)兼容性:<link> 在所有浏览器中都被支持,而 @import 在一些老版本的浏览器中可能不被支持。

3)动态改变:<link> 元素可以通过 JavaScript 动态改变,例如改变 href 属性来加载不同的 CSS。而 @import 一旦被加载,就不能再通过 JavaScript 改变。

三、理论知识

1. 元素显示模式

CSS 把 HTML 元素主要分为两种类型:块级元素(Block-level Elements)和内联元素(Inline Elements)。

  1. 块级元素(Block-level Elements):这种类型的元素会在其前后创建新的行。块级元素通常用于包含内联元素和其他块级元素。例如:<div><h1> - <h6><p><form><header><footer><section><textarea><ul><ol><li><table><aside><article> 等。

  2. 内联元素(Inline Elements):这种类型的元素不会在其前后创建新的行。它们通常出现在块级元素中,用于包含文本或其他内联元素。例如:<span><a><input><label> 等。

  3. 内联块级元素(Inline-block Elements)。这种元素在布局上表现为内联元素,但是可以设置宽度和高度,例如:<img><button><td>

特点

  • 块级元素

    • 可以设置宽、高。

    • 宽度:独占一行,宽度是父元素的宽度。就算设置了也是独占一行。

      默认总宽度 = 父元素内容宽度 - 自身的左右外边距
      默认内容宽度 = 父元素内容宽度 - 自身的左右外边距 - 自身的左右边框 - 自身的左右内边距
    • 高度:默认高度被内容撑开,没有内容就没有高度。

    • 内容:块级元素可以包含其他块级元素和内联元素。但是,有一些特定的块级元素,如 <p>,不能包含其他块级元素。同理,<h1>~<h6> 等都是文字类块级标签,里面也不能放其他块级元素。

  • 内联元素 / 行内级元素

    • 宽、高直接设置是无效的。
    • 宽度:不独占一行,默认宽度被内容撑开,没有内容就没有宽度。
    • 高度:默认高度被内容撑开,没有内容就没有高度。
    • 内容:行内元素只能容纳文本或其他行内元素。特殊情况下,链接 <a> 里面可以放块级元素,但是给 <a> 转换一下块级模式最安全。
  • 内联块级元素 / 行内级替换元素

    • 可以设置宽、高。
    • 宽度:默认宽度被内容撑开,没有内容就没有宽度。
    • 高度:默认高度被内容撑开,没有内容就没有高度。
    • 和相邻行内元素(行内块)在一行上,但是他们之间会有空白缝隙。一行可以显示多个(行内元素特点)。

display 属性

这些都是元素的默认显示类型,可以使用 CSS 的 display 属性来改变元素的显示类型。

css
/* 转换为块元素 */
display: block;
/* 转换为行内元素 */
display: inline;
/* 转换为行内块 */
display: inline-block;

发散思维:display 本质是让任何元素设置任何样式。

2. 三大特性

  • 层叠性

  • 继承性:子元素可以继承父元素的样式。

    字体样式 font-size、font-weight、font-style、font-family、font

    文字颜色 color

    文本样式 letter-spacing、word-spacing、text-decoration、text-indent、text-align、line-height(vertical-align 不可以被继承)

    总结:text-,font-,line- 这些元素开头的可以继承,以及 color 属性。

  • 优先级 / 特异性 / 特定性

    选择器选择器权重
    继承或者 *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 (无穷大)

    计算方法:例如,如果一个规则的选择器是 #id .class element,那么它的特异性就是 (0, 1, 1, 1)。如果另一个规则的选择器是 #id .class .class,那么它的特异性就是 (0, 1, 2, 0)。因此,第二个规则的特异性高于第一个规则,因为 c 的值更大。

    使用规则:当多个规则可以应用到同一个元素时,浏览器会选择特异性最高的规则。如果特异性相同,那么在源代码中后出现的规则会被应用。

    注意点:

    ① 权重是有 4 组数字组成。不会有进位,而是按位进行。

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

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

属性值的计算过程

浏览器控制台显示的用户代理样式就是浏览器自己添加的样式。

优先级:直接设置的样式 > 继承的样式 > 自带的样式

3. 长度单位

CSS 中,单位分为绝对单位和相对单位。

单位解释
px逻辑像素
百分比慎用。用时查文档,看参照谁
em慎用。相对于当前元素的字体大小。如果到头都没有设置父元素的字体大小,则参照浏览器的默认字体大小(通常是16px)。不过,一般都会使用父元素的字体大小,因为该属性可以继承。
rem根元素字体大小的倍数
vw将视口宽度分成 100 份,设置占多少份
vh将视口高度分成 100 份,设置占多少份
vmax将视口宽高中较大的一个分成 100 份,设置占多少份
vmin将视口宽高中较小的一个分成 100 份,设置占多少份

尺寸的百分比

绝大部分可以书写尺寸的地方,都可以书写百分比。

百分比是一个相对单位,其相对于元素的参考系,比如:

  • 普通元素和 relative 的参考系为父元素的内容区域。
  • 绝对(固定)定位元素的参考系为父元素中第一个定位元素的 padding 区域。

下面罗列常见的百分比情况。

css 属性百分比相对于备注
width参考系的宽度
height参考系的高度参考系高度受本身宽度影响时,设置无效
padding参考系的宽度
border参考系的宽度
margin参考系的宽度

4. 颜色设置

① rgb

还有一种特殊的写法,包含了 a:rgb(r, g, b / a)

② rgba
r	red
g   green
b   blue
a   opacity 不透明度,取值0~1之间的小数,值越大越不透明,0表示完全透明,1表示完全不透明
③ hex

#RRGGBB[AA]

#RGB[A]

④ hsl
h	色相 取值0~360
s	饱和度 取值0%~100%
l	亮度 取值0%~100%
⑤ hsla
h	色相 取值0~360
s	饱和度 取值0%~100%
l	亮度 取值0%~100%
a   opacity 不透明度,取值0~1之间的小数,值越大越不透明,0表示完全透明,1表示完全不透明
⑥ 关键字

red、pink ……

5. CSS 值的类型

① 全局值

  • inherit:属性值会继承父元素的值。==> 主动继承
  • initial:将属性值重置为其默认值(CSS 规范定义的初始值)。不管父元素的样式如何,都会使用这个属性的默认值。
  • unset:根据属性是否是继承属性,决定是继承父元素的值还是使用默认值。
    • 如果该属性是继承属性(如 colorfont-family),则等同于 inherit。
    • 如果该属性是非继承属性(如 displaymargin),则等同于 initial。

② 自定义

③ 关键字

6. CSS 样式的字符编码

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

  1. 文件的开头的 Unicode byte-order(字节顺序标记)字符值。

    https://en.wikipedia.org/wiki/Byte_order_mark

  2. Content-Type:HTTP header 中的 charset 属性给出的值或用于提供样式表的协议中的等效值。

  3. CSS @规则:@charset

  4. 使用参考文档定义的字符编码:<link> 元素的 charset 属性。

    该方法在 HTML5 标准中已废除,无法使用。

  5. 假设文档是 UTF-8。


开发中推荐在 CSS 的开头编写 @charset 指定编码:

css
@charset "UTF-8";

7. CSS 编写顺序 & 代码规范 & CSS 不生效

编写顺序

定位

  • position: absolute
  • float: left / right
  • display: flex

元素的可见性

  • display: block / inline-block / inline/none
  • visibility / opacity

盒模型

  • width / height
  • box-sizing
  • margin/border / padding / content
  • box-shadow / text-shadow

字体、文本

  • font-* / text-*

背景

  • background-image / background-size / background-position / background-color ……

其他属性

  • transform / transition / overflow / white-space

代码规范

Aotu.io - 前端代码规范

CSS 不生效

1️⃣ 样式是否选中了该 html 标签。

2️⃣ 检查特异性。

3️⃣ CSS 属性是否使用正确

  • 浏览器不支持。
  • 该元素不支持。
  • 被复合属性覆盖了。

建议:多使用浏览器的开发者工具进行调试。

四、初始样式

1. Reset.css

有些标签默认含有内外边距,且不同浏览器大小也不一样。为了统一需要重置标签的 CSS 默认样式。

参考 reset CSS

html
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" />

2. Normalize.css

官网地址:http://necolas.github.io/normalize.css

GitHub:https://github.com/necolas/normalize.css

二者区别?Reset.css 把自己要重置的已经给我们写好了;Normalize.css 保留了必要的用户代理样式,并且统一了各个浏览器之间的差异。

如何选择?如果设计师参照了 normalize.css 就用它,否则就用 reset.css。一般还是 reset.css 使用的多。

五、参考文档

CSS 官方文档地址:W3C 标准和草案

CSS 推荐文档地址:MDN 文档

由于浏览器版本、CSS 版本等问题。查询某些 CSS 属性在哪些浏览器支持情况,可以到 Can I use... 查询 CSS 属性的可用性;这个网站在后续的 browserlist 工具中再详细说明。

第二章:选择器

一、基本选择器

1. 通配符选择器

也叫全局选择器。使用 * 可为所有元素设置样式。

css
* {
  text-decoration: none;
  color: #6c757d;
}

2. 标签选择

根据标签为元素设置样式。

css
h1 {
  color: red;
}

3. 类选择器

类选择器是为 一类状态声明样式规则,下面是把文本居中定义为类样式。

html
<style>
.text-center {
  text-align: center;
}
</style>

<h1 class="text-center">书籍</h1>
<h2 class="text-center">分类</h2>

4. ID 选择器

为有 id 属性的元素设置样式。

html
#container {
  background: red;
}

<h1 id="container">我是 h1 元素</h1>

注意:文档中 ID 应该是唯一的,虽然为多个元素设置同一个 ID 也可以产生样式效果,但这是不符合规范的。这种情况建议优先使用类选择器。

二、结构选择器

1. 后代选择器

HTML 中元素是以父子级、兄弟关系存在的。后代选择器指元素后的元素(不只是子元素,是后代元素)。

html
main article h2,main h1 {
  color: green;
}

<main>
  <article>
    <h2>JavaScript</h2> <!-- 选中 -->
    <aside>
      <h2>HTML</h2> <!-- 选中 -->
    </aside>
  </article>
  <h2>CSS</h2>
  <h1>Python</h1> <!-- 选中 -->
</main>

2. 子元素选择器

子元素选择器中选择子元素,不包括孙级及以下元素。

html
main article>h2 {
  color: green;
}

<main>
  <article>
    <h2>JavaScript</h2> <!-- 选中 -->
    <aside>
      <h2>HTML</h2>
    </aside>
  </article>
  <h2>CSS</h2>
  <h1>Python</h1>
</main>

3. 紧邻元素选择器

用于选择紧挨着的同级兄弟元素。

html
main article+h2 {
  color: green;
}

<main>
  <article>
    <h2>JavaScript</h2>
    <h2>Go</h2>
    <aside>
      <h2>HTML</h2>
    </aside>
  </article>
  <h2>CSS</h2> <!-- 选中 -->
  <h2>Java</h2>
  <h1>Python</h1>
</main>

4. 兄弟选择器

html
main article~h2 {
  color: green;
}

<main>
  <article>
    <h2>JavaScript</h2>
    <aside>
      <h2>HTML</h2>
    </aside>
  </article>
  <h2>CSS</h2> <!-- 选中 -->
  <h2>PHP</h2> <!-- 选中 -->
  <h1>Python</h1>
  <h2>Java</h2> <!-- 选中 -->
</main>

5. 并集选择器

也叫群组选择器。选择所有匹配 "元素1" 或 "元素2" 的元素,并对它们应用相同的样式声明。

css
元素1, 元素2 {
  样式声明;
}

6. 交集选择器

也叫多选择器。

css
/* 选择所有 class 为 item 的 div 元素 */
div.item {
}

/* 选择 ID 为 container 的 div 元素 */
div#container {
}

/* 选择同时具有 item 和 list-item 这两个 class 的所有元素 */
.item.list-item {
}

三、属性选择器

根据属性来为元素设置样式也是常用的场景。

选择器示例描述
[attribute][target]带有 target 属性所有元素。
[attribute=value][target=_blank]targe 属性 等于 "_blank" 的所有元素。
[attribute~=value][title~=topnav]title 属性包含单词 "topnav" 的所有元素。
[attribute|=value][title|=dots]title 属性值为 "dots"的单词,或以 - 连接的单词,如: dots-list。
[attribute*=value]a[src*="domain"]src 属性中包含 "domain" 字符的每个 a 元素。
[attribute^=value]a[src^="https"]src 属性值以 "https" 开头的每个 a 元素。
[attribute$=value]a[src$=".jpeg"]src 属性以 ".jpeg" 结尾的所有 a 元素。

只演示比较混淆的 *~ 属性选择器。

* 属性内部任何位置出现值的元素。

html
h2[name*="xxx"] {
  color: red;
}

<h2 name="xxx">xxx.com</h2>
<h2 name="xxx 的博客">xxx.com</h2>
<h2 name="xxx.com">xxx.com</h2>

<!-- 全选择 -->

~ 属性值中包含指定词汇的元素。

html
h2[name~="xxx"] {
  color: red;
}

<h2 name="xxx">xxx.com</h2>
<h2 name="xxx 的博客">xxx.com</h2>
<h2 name="xxx.com">xxx.com</h2>

<!-- 选中了前两个 -->

四、伪类选择器

1. 目标伪类选择器

:target

它会选择当前活动的(被链接指向的)元素。用于控制具有锚点目标元素的样式。

html
<style>
  div {
    height: 900px;
  }

  div:target {
    color: red;
  }
</style>

<a href="#desc">简介</a>
<div></div>
<div id="desc">
  内容管理系统
</div>

2. 动态伪类选择器

也叫链接伪类选择器。

  • a:link 选择器用来选择所有未被访问过的链接,这些链接的颜色将被设置为红色。
  • a:visited 选择器用来选择所有已经被访问过的链接,这些链接的颜色将被设置为绿色。
  • a:hover 选择器用来选择鼠标悬停在上面的链接,这些链接的颜色将被设置为蓝色。
  • a:active 选择器用来选择正在被点击或正在被用户激活的链接,这些链接的颜色将被设置为黄色。

请注意,这四个伪类选择器的顺序很重要,通常应该按照 :link -> :visited -> :hover -> :active 的顺序(简记为 LoVe/HAte 或者爱恨法则)来声明,以确保它们正确地工作。

html
<style>
  /*
    直接给 a 元素设置样式,相当于给 a 元素的所有动态伪类都设置了
  */
  a:link {
    color: red
  }

  a:visited {
    color: green
  }

  a:hover {
    color: blue
  }

  a:active {
    color: yellow
  }
</style>

<a href="https://www.xxx.com">xxx 的博客</a>

不只是链接可以使用伪类,其他元素也可以使用。下面是对表单的点击与获取焦点状态的样式设置。

html
<style>
  /*
    推荐顺序: link visited focus hover active
  */
  input:focus {
    background: green;
    outline: none;
  }

  input:hover {
    background: blue;
  }

  input:active {
    background: yellow;
  }
</style>

<input type="text">

3. UI 元素伪类选择器

  • E:checked:匹配用户界面上处于选中状态的元素 E。(用于 input type 为 radio 与 checkbox 时)。

    css
    /* 选中的复选框和单选按钮 */
    input[type="checkbox"]:checked {
      background: blue;
    }
    
    input[type="radio"]:checked {
      border: 2px solid green;
    }
    
    /* 选中的option元素 */
    option:checked {
      background: yellow;
    }
  • E:enabled:匹配用户界面上处于可用状态的表单元素。

  • E:disabled:匹配用户界面上处于禁用状态的表单元素。

4. 结构伪类

:root

它会选择文档的根元素。在 HTML 文档中,根元素就是 <html> 元素。

:root 选择器在 CSS 优先级中比普通的元素选择器(如 html)具有更高的优先级。

css
:root {
  font-size: 100px;
}
:empty

它会选择没有子元素的元素,包括那些没有文本内容的元素。

:empty 选择器只会选择真正空的元素。如果一个元素有空白字符,或者有注释,那么它不会被 :empty 选择器选中。

html
:empty {
  border: solid 2px red;
}

<p></p>
<p> </p>
:first-child

选择元素中 span 标签并且是第一个。

html
article span:first-child {
  color: red;
}

<article>
  <span>xxx.com</span> <!-- 选中 -->
  <aside>
    <span>sss.com</span> <!-- 选中 -->
    <span>aaa.com</span>
  </aside>
</article>
:first-of-type

选择类型是 span 的第一个元素。

html
article span:first-of-type {
  color: red;
}

<article>
  <aside>
    <span>sss.com</span> <!-- 选中 -->
    <span>aaa.com</span>
  </aside>
  <span>xxx.com</span> <!-- 选中 -->
</article>
:last-child

选择元素中 span 标签并且是最后一个。

html
article span:last-child {
  color: red;
}

<article>
  <span>sss.com</span>
  <aside>
    <strong>bbb.com</strong>
    <span>ccc.com</span> <!-- 选中 -->
  </aside>
  <span>aaa.com</span> <!-- 选中 -->
</article>
:last-of-type

选择类型为 span 的最后一个元素。

html
article span:last-of-type {
  color: red;
}

<article>
  <span>sss.com</span>
  <aside>
    <span>ccc.com</span> <!-- 选中 -->
    <strong>bbb.com</strong>
  </aside>
  <span>aaa.com</span> <!-- 选中 -->
</article>
:only-child

选择的是其父元素的唯一的子元素。如果一个元素是其父元素的唯一的子元素,无论这个元素是什么类型,:only-child 都会选择它。

html
<!-- 选择的是唯一子元素的 span 标签 -->
span:only-child {
  color: red;
}

<article>
  <span>sss.com</span>
  <aside>
    <span>aaa.com</span> <!-- 选中 -->
  </aside>
</article>
:only-of-type

选择的是其父元素的唯一的特定类型的子元素。如果一个元素是其父元素的唯一的特定类型的子元素,:only-of-type 就会选择它。

html
<!-- 选择同级中类型是 span 的唯一子元素 -->
article span:only-of-type {
  color: red;
}

<article>
  <span>sss.com</span> <!-- 选中 -->
  <aside>
    <span>aaa.com</span>
    <span>ccc.com</span>
  </aside>
</article>
:nth-child(n)

:nth-child(n) 的参数 n 也可以是一个公式。例如,li:nth-child(2n) 会选择所有偶数位置的 <li> 元素,li:nth-child(2n+1) 则会选择所有奇数位置的 <li> 元素。还有一些关键字可以使用,如 even 和 odd。

选择第二个元素并且是 span 标签的。

html
article span:nth-child(2) {
  color: red;
}

<article>
  <span>aaa.com</span>
  <aside>
    <span>bbb.com</span>
    <span>ccc.com</span> <!-- 选中 -->
  </aside>
  <span>ddd.com</span>
</article>

计算数量 - n 为 0/1/2/3... ,下面是隔列变色。

html
table tr>td:nth-child(2n+1) {
  background: green;
  color: white;
}
...

<table border="1">
  <tr>
    <td>ccc.com</td>
    <td>ddd.com</td>
    <td>雨下田上</td>
    <td>yxts.com</td>
    <td>yxts</td>
  </tr>
</table>

从第三个开始设置样式。

css
table tr>td:nth-child(n+3) {
  background: rgb(128, 35, 2);
  color: white;
}

设置前三个元素。

css
table tr>td:nth-child(-n+3) {
  background: rgb(128, 35, 2);
  color: white;
}

奇数元素 - 选择奇数单元格。

html
table tr>td:nth-child(odd) {
  background: green;
  color: white;
}

<table border="1">
  <tr>
    <td>eee.com</td>
    <td>aaa.com</td>
    <td>ccc</td>
    <td>fff</td>
    <td>ddd</td>
  </tr>
</table>

偶数元素 - 选择偶数单元格。

html
table tr>td:nth-child(even) {
  background: green;
  color: white;
}

<table border="1">
  <tr>
    <td>eee.com</td>
    <td>aaa.com</td>
    <td>ccc</td>
    <td>fff</td>
    <td>ddd</td>
  </tr>
</table>
:nth-of-type(n)

:nth-of-type(n) 参数 n 是从 1 开始的。:nth-child(2n+1) 参数 n 是从 0 开始的。

选择第二个 span 元素,不管中间的其他元素。

html
article span:nth-of-type(2) {
  color: red;
}

<article>
  <span>aaa.com</span>
  <aside>
    <span>bbb.com</span>
    <span>ccc.com</span> <!-- 选中 -->
  </aside>
  <span>ddd.com</span> <!-- 选中 -->
</article>
:nth-last-child(n)

从最后一个元素开始获取。

html
table tr>td:nth-last-child(2n+1){
  background: green;
  color: white;
}

<table border="1">
  <tr>
    <td>eee.com</td> <!-- 选中 -->
    <td>aaa.com</td>
    <td>ccc</td> <!-- 选中 -->
    <td>fff</td>
    <td>ddd</td> <!-- 选中 -->
  </tr>
</table>

取最后两个元素。

css
main>ul li:nth-last-child(-n+2) {
  color: red;
}
:nth-last-of-type(n)

从最后一个元素开始选择 span 标签 。

html
article span:nth-last-of-type(1) {
  background: red;
  color: white;
}

<article>
  <span>aaa.com</span>
  <aside>
    <span>bbb.com</span>
    <span>ccc.com</span> <!-- 选中 -->
  </aside>
  <span>ddd.com</span> <!-- 选中 -->
  <p name="xxx.com">xxx.com</p>
</article>

5. 否定伪类选择器

:not(selector)

选择 <ul> 标签下的 <li> 子元素,但不包括第一个 <li> 子元素。

html
ul>li:not(:nth-child(1)) {
  background: red;
}

<ul>
  <div>今天的不开心就到此为止吧,明天依旧要光芒万丈啊!宝贝~ --海绵宝宝</div>
  <li>eee.com</li>
  <li>aaa.com</li> <!-- 选中 -->
  <li>ddd</li> <!-- 选中 -->
</ul>

五、伪元素选择器

  • E:first-letter/E::first-letter:设置对象内的第一个字符的样式。
  • E:first-line/E::first-line:设置对象内的第一行的样式。
  • E::placeholder:设置对象文字占位符的样式。
  • E::selection:设置对象被选择时的样式(鼠标选中的文字添加样式)。
  • E:before/E::before:设置在对象前(依据对象树的逻辑结构)发生的内容。用来和 content 属性一起使用。
  • E:after/E::after:设置在对象后(依据对象树的逻辑结构)发生的内容。用来和 content 属性一起使用。

小贴士:在 CSS3 中,为了区分伪类和伪元素,推荐使用两个冒号 :: 来表示伪元素。

详细解释下 before 和 after

before 和 after 创建一个元素,但是属于行内元素。新创建的这个元素在文档树中是找不到的,所以我们称为伪元素。

语法:element::before {}

before 和 after 必须有 content 属性。

before 在父元素内容的前面创建元素,after 在父元素内容的后面插入元素。

伪元素选择器和标签选择器一样,权重为 1。

第三章:常见 CSS 属性

一、文本相关属性

记忆口诀:转、空、处、对、装、省。

1. text-decoration

1)CSS2.1

text-decoration 用于设置文字的装饰线。decoration 是装饰、装饰品的意思。

text-decoration 有如下常见取值。

  • none:无任何装饰线。可以去除 a 元素默认的下划线。
  • underline:下划线。
  • overline:上划线。
  • line-through:中划线(删除线)。

备注:a 元素有下划线的本质是被添加了 text-decoration 属性。

2)CSS3

text-decoration 在 CSS3 变成了复合属性。

css
text-decoration: text-decoration-line || text-decoration-style || text-decoration-color;

注意:所有浏览器均支持 CSS2.1 中的 text-decoration 属性。在 CSS3 中,该属性定义被移植到其新的分解属性 text-decoration-line 上。

  • text-decoration-line:设置文本装饰线的位置。

    取值

    none:指定文字无装饰(默认值)

    underline:指定文字的装饰是下划线

    overline:指定文字的装饰是上划线

    line-through:指定文字的装饰是贯穿线

    blink(已弃用):文本闪烁(文本交替处于显示与隐藏状态)

  • text-decoration-style:文本装饰线条的形状。

    取值

    solid:实线(默认)

    double:双线

    dotted:点状线条

    dashed:虚线

    wavy:波浪线

  • text-decoration-color:文本装饰线条的颜色。

2. text-transform

text-transform 用于设置文字的大小写转换。Transform 单词是使变形、变换、形变。

text-transform 有几个常见的值。

  • capitalize:资本化的意思。将每个单词的首字符变为大写。
  • uppercase:将每个单词的所有字符变为大写。
  • lowercase:将每个单词的所有字符变为小写。
  • none:没有任何影响。

实际开发中用 JavaScript 代码转化的更多。

3. text-indent

text-indent 用于设置第一行内容的缩进。

css
text-indent: 2em; /* 刚好是缩进 2 个文字 */

em 是一个相对单位,就是当前元素 ( font-size ) 文字的大小。如果当前元素没有设置大小,则会按照父元素的文字大小。

注意:text-indent 主要设计用于块级元素。对 inline-block 元素有效。对 inline 元素无效。

4. text-align

text-align:直接翻译过来设置文本的对齐方式。

MDN:定义行内内容(例如文字)如何相对它的块父元素对齐。

常用的值。

  • left:左对齐。
  • right:右对齐。
  • center:正中间显示。
  • justify:两端对齐。
  • start:相当于 left。
  • end:相当于 right。

实测发现,可以把文本、图片按指定方式对齐。但 div 元素无法起作用,为什么?因为官方文档说了,只对行内级和行内块元素有效。

5. text-align-last

text-align-last 文本最后一行的对齐方式(如果只有一行,既是第一行,也是最后一行)。

有几个常见的值。

  • auto:无特殊对齐方式。 (默认值)
  • left:内容左对齐。
  • center:内容居中对齐。
  • right:内容右对齐。
  • justify:内容两端对齐。
  • start:内容对齐开始边界。
  • end:内容对齐结束边界。

6. text-shadow

参数顺序为:水平偏移,垂直偏移,模糊度,颜色。

在线阴影调试网站:Text Shadow CSS Generator Online

7. white-space

设置元素是否保留文本间的空格、换行;指定文本超过边界时是否换行。

white-space 有几个常见的值。

  • normal:连续的空白符会被合并。源码中的换行符会被当作空白符来处理。并根据填充行框盒子的需要来换行。
  • nowrap:和 normal 一样合并空白符,但阻止源码中的文本换行。(强制显示一行)
  • pre:连续的空白符会被保留。仅在遇到换行符或 <br> 元素时才会换行。
  • pre-wrap:连续的空白符会被保留。在遇到换行符或 <br> 元素时,或者根据填充行框盒子的需要换行。
  • pre-line:连续的空白符会被合并。在遇到换行符或 <br> 元素时,或者根据填充行框盒子的需要换行。

8. text-overflow

设置文本内容溢出容器时的状态。

  • clip:这是默认值。当文本溢出时,它将被剪切,并且溢出的部分不会显示。
  • ellipsis:当文本溢出时,溢出的部分将被替换为省略号(...)。

text-overflow 属性适用于块级元素和替换内联元素。

  • 块级元素是那些默认占据其父元素全部宽度的元素,例如 <div><p><h1><h6> 等。

  • 替换内联元素是那些内部内容由元素的属性决定的元素,例如 <img><input><textarea> 等。

请注意,text-overflow 属性只有在以下条件都满足时才会生效:

① 元素的 white-space 属性值阻止了文本的自动换行,例如 nowrap 或 pre。

② 元素的 overflow 属性值不是 visible。

9. letter-spacing、word-spacing

letter-spacing(对中文有效)、word-spacing(对中文无效)分别用于设置字母、单词之间的间距。

默认是 0,可以设置为负数。

10. writing-mode

用于指定文本的书写方向。writing-mode 有几个常见的值。

  • horizontal-tb:这是默认值。文本从左到右水平书写,行从上到下堆叠。
  • vertical-rl:文本从上到下垂直书写,行从右到左堆叠。
  • vertical-lr:文本从上到下垂直书写,行从左到右堆叠。

11. overflow-wrap

CSS3 以前,名字是 word-wrap。

  • normal:默认值。浏览器不会强制折断不能被分割的字符串。
  • break-word:浏览器会在不能被分割的字符串到达边界时强制进行折断。

二、字体相关属性

1. font-size

font-size 决定文字的大小。

常见的设置。

  • 具体数值单位。比如 100px 。
  • 使用 em 单位。1em 代表 100%、2em 代表 200%、0.5em 代表 50%。这里的 em 相对父元素的字体大小设置。
  • 百分比。基于父元素的 font-size 计算,比如 50% 表示等于父元素 font-size 的一半。

2. font-family

font-family 用于设置文字的字体名称。

可以设置 1 个或者多个字体名称,多个用英文逗号隔开。浏览器会选择列表中第一个该计算机上有安装的字体,或者是通过 @font-face 指定的可以直接下载的字体。

3. font-weight

font-weight 用于设置文字的粗细(重量)。

常见的取值:

  • 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900,每一个数字表示一个重量。
  • normal:等于 400。
  • bold:等于 700。

备注:strong 、b 、h1 ~ h6 等标签的 font-weight 默认就是 bold。

4. font-style

font-style 用于设置文字的常规、斜体显示。

常见的取值:

  • normal:常规显示。
  • italic (斜体) :用字体的斜体显示,通常会有专门的字体。(如果这个字体样式有设计的斜体,就使用它,否则使用 CSS 的斜体)
  • oblique (倾斜) :文本倾斜显示,仅仅是让文字倾斜。(不管字体样式是否有专门的斜体字体,都是用 CSS 的斜体)

备注:em 、i 等元素的 font-style 默认就是 italic。

5. font-variant

font-variant 可以影响小写字母的显示形式。variant 是变形的意思。

可以设置的值如下。

  • normal:常规显示。
  • small-caps:将小写字母替换为缩小过的大写字母。

6. line-height

line-height 用于设置文本的行高。

行高可以先简单的理解为一行文字所占据的高度。

行高的严格定义:两行文字基线( baseline )之间的间距。

基线( baseline ) :与小写字母 x 最底部对齐的线。

应用实例:假设 div 中只有一行文字,如何让这行文字在 div 内部垂直居中?让 line-height 等同于 height。

简写

font 是一个缩写属性。font 属性可以用来作为 font-style, font-variant, font-weight, font-size, line-height 和 font-family 属性的简写。

css
font: font-style font-variant font-weight font-size/line-height font-family;

规则:

  • font-style、font-variant、font-weight 可以随意调换顺序,也可以省略。
  • /line-height 可以省略。如果不省略,必须跟在 font-size 后面。
  • font-size、font-family 不可以调换顺序,不可以省略。

注意:line-height 要写在 font 复合属性的后面。为什么?因为 line-height 是 font 复合属性的子属性,font 会覆盖前面的 line-height。

css
p {
  line-height: 1.5;
  font: 16px Arial, sans-serif;
}

在这个例子中,font 复合属性会覆盖之前设置的 line-height。实际效果相当于:

css
p {
  line-height: normal; /* 默认值 */
  font-size: 16px;
  font-family: Arial, sans-serif;
}

三、背景处理

1. background-color

一般情况下,元素背景颜色默认值是 transparent(透明),也可以手动指定背景颜色为透明色。

css
background-color: transparent;

2. background-image

css
background-image: none | url(url)

注意:背景图片后面的地址,千万不要忘记加 URL,同时里面的路径不要加引号。

3. background-origin

背景图片原点。可以设置的值如下。

  • border-box:从 border 区域(含 border)开始显示背景图像。
  • padding-box(默认值):从 padding 区域(含 padding)开始显示背景图像。
  • content-box:从 content 区域开始显示背景图像。

4. background-clip

指定对象的背景图像向外裁剪的区域。可以设置的值如下。

  • border-box(默认值):包括边框。

  • padding-box:不含边框,包括内边距。

  • content-box:内容区域。

  • text:从前景内容的形状(比如文字)作为裁剪区域向外裁剪,如此即可实现使用背景作为填充色之类的遮罩效果。

5. background-repeat

背景图片是否重复。可以设置的值如下。

  • repeat(默认值):水平与垂直重复。
  • repeat-x:水平重复。
  • repeat-y:垂直重复。
  • no-repeat:不重复。
  • space:背景图片对称均匀分布。

6. background-attachment

设置背景是否随滚动轴移动。可以设置的值如下。

  • scroll(默认值):背景图像相对于元素本身固定,不会随元素内容滚动。当页面滚动时,背景图像随元素一起滚动。
  • local:背景图像相对于元素的内容固定。如果一个元素拥有滚动机制,背景图像会随着元素的内容一起滚动。背景图像相对于可滚动的区域定位。
  • fixed:背景固定。如果设置了这个,那么背景图将会以视口定位。只有当元素位置与背景图重合时,才显示。

7. background-position

在坐标轴上移动图像。原点在元素左上角。

css
background-position: x y;

参数代表的意思是:x 坐标和 y 坐标。可以使用方位名词或者精确单位。

参数值说明
length百分数 | 由浮点数字和单位标识符组成的长度值(精确单位)
positiontop丨center丨bottom丨left丨center丨right(方位名词)

设置规则:

① 参数是方位名词

  • 如果指定的两个值都是方位名词,则两个值前后顺序无关,比如 left top 和 top left 效果一致。
  • 如果只指定了一个方位名词,另一个值省略,则第二个值默认居中对齐。

② 参数是精确单位

  • 如果参数值是精确坐标,那么第一个肯定是 x 坐标,第二个一定是 y 坐标。
  • 如果只指定一个数值,那该数值一定是 x 坐标,另一个默认垂直居中。

③ 参数是混合单位

  • 如果指定的两个值是精确单位和方位名词混合使用,则第一个值是 x 坐标,第二个值是 y 坐标。

注意:

① background-position 值也可以设置百分比。比如 background-position: 20% 10%; 就会在图片和元素上各自找到 20% 10% 的位置,然后重合。

② background-position 有两个子属性,分别是 background-position-x 与 background-position-y。

8. background-size

背景图像的尺寸。可以设置的值如下。

  • 长度:用长度值指定背景图像大小。不允许负值。可以只设置宽度,高度会自动计算。

  • 百分比:用百分比指定背景图像大小。不允许负值(参照设置背景图片的元素)。

  • cover:将背景图像等比缩放到完全覆盖容器,背景图像有可能超出容器。

  • contain:将背景图像等比缩放到宽度或高度与容器的宽度或高度相等,背景图像始终被包含在容器内。可能会漏出部分区域。

  • auto:背景图像的真实大小。

简写

当使用简写属性时,没有特定的书写顺序,一般习惯约定顺序为:

css
background: bg-color bg-image bg-repeat bg-attachment bg-position / bg-size bg-origin bg-clip

① 如果想在复合属性中写 bg-size,必须写 bg-position,哪怕设置为 0 0

② bg-origin 与 bg-clip 值是重复的。如果写一个值,相当于同时设置;如果写两个值,先原点后范围。

多背景

css
background: url(test1.jpg) no-repeat scroll 10px 20px/50px 60px content-box padding-box,
           url(test1.jpg) no-repeat scroll 10px 20px/70px 90px content-box padding-box,
           url(test1.jpg) no-repeat scroll 10px 20px/110px 130px content-box padding-box #aaa;

如果位置重合,先写的背景图会显示在上面。

background-color 只能有一个值,且只能应用于最底层(最后一个)背景层。

背景颜色永远在最底层(所有背景图片都会显示在背景颜色之上)。

四、鼠标样式

语法:

css
cursor: [ [<url> [<x> <y>]?]*, ] <keyword>;


/* 例子 */
.interactive-element {
  cursor: url('custom.cur'),
          url('custom.png') 5 5,
          url('interactive.gif'),
          pointer;          /* 默认状态 */
}

.interactive-element:hover {
  cursor: grab;            /* 悬停状态, 此状态会覆盖 .interactive-element 状态 */
}

.interactive-element:active {
  cursor: grabbing;        /* 点击状态 */
}

cursor 属性 keyword 可取的属性值如下。

属性值描述
default小箭头(默认)
pointer小手
zoom-in放大(放大镜)
move移动
grab抓取
text文本
not-allowed禁止
wait等待(圆圈加载)
crosshair十字准线(框选)
help帮助

五、列表样式

这些属性只能给 ul、ol、li 设置。

1. list-style-type

disc         实心点
circle       圆圈
square       小方框
decimal      数字
lower-roman  小写罗马字
upper-roman  大写罗马字
lower-alpha  小写字母
upper-alpha  大写字母

2. list-style-position

list-style-type 显示位置。

inside   表示在li里面
outside  表示在li外面

3. list-style-image

使用图片替换 list-style-type。语法:list-style-image: url('图片路径');

简写

css
/* list-style 复合属性,值没有顺序要求 */
list-style: type position image;

/* 一般这样使用,来清除默认样式 */
list-style: none;

六、表格样式

1. border-collapse

用于设置表格边框的合并方式。它有两个可能的值:

  • separate(默认):边框被分开。每个单元格都有自己的边框。可使用 border-spacing 属性来设置边框之间的距离。border-spacing 属性用于设置单元格与单元格之间的距离,也就是单元格边框之间的空隙。这个属性只在 border-collapse 属性值为 separate 时有效。
  • collapse:边框被合并为一个单一的边框。这会消除单元格之间的空隙。

2. table-layout

表格布局方式。

  • auto(默认):浏览器会自动计算表格的布局。首先,浏览器会根据表格单元格中的内容来设置列宽,然后,如果表格的宽度超过了其父元素的宽度,浏览器会调整列宽以使表格适应其父元素的宽度。这是默认值。

  • fixed:表格和列的宽度是由 table 和 col 元素的宽度或第一行单元格的宽度来设置的。后续行中的单元格不会影响列的宽度。

    1. 如果 table 有明确宽度(width),浏览器把这总宽度分配给各列。
    2. 如果有 col / colgroup 指定列宽,优先采用。
    3. 否则看第一行的各单元格,用它们的指定宽度。
    4. 最后没有指定第一行的各单元格宽度,也没有指定 table 宽度,就会退回 auto 模式。
    html
    <table>
      <colgroup>
        <col style="width: 100px;">
        <col style="width: 200px;">
        <col style="width: 150px;">
      </colgroup>
      <thead>
        <tr>
          <th>列1</th>
          <th>列2</th>
          <th>列3</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>数据1</td>
          <td>数据2</td>
          <td>数据3</td>
        </tr>
      </tbody>
    </table>

3. border-spacing

用于设置表格单元格之间的距离。这个属性只对 border-collapse 属性设置为 separate 的表格有效。可以接受一个或两个值:

  • 当只有一个值时,这个值会同时应用于水平和垂直间距。
  • 当有两个值时,第一个值应用于水平间距,第二个值应用于垂直间距。

4. caption-side

用于指定表格标题 <caption> 的位置。

  • top(默认):标题显示在表格的上方。
  • bottom:标题显示在表格的下方。

5. empty-cells

用于设置是否显示表格中空单元格的边框和背景。

  • show(默认):显示空单元格的边框和背景。
  • hide:不显示空单元格的边框和背景。

第四章:盒子模型

一、有哪些?

1. content 内容

设置内容是通过宽度和高度设置的。

  • 宽度设置:width

  • 高度设置:height

注意:对于行内级非替换元素来说,设置宽高是无效的。

另外,还可以设置如下属性。

min-width:最小宽度。无论内容多少,宽度都大于或等于 min-width。

max-width:最大宽度。无论内容多少,宽度都小于或等于 max-width。

移动端适配时,可以设置最大宽度和最小宽度。

下面两个属性不常用。

min-height:最小高度,无论内容多少,高度都大于或等于 min-height。

max-height:最大高度,无论内容多少,高度都小于或等于 max-height。

2. padding 内边距

padding 属性用于设置盒子的内边距,通常用于设置边框和内容之间的间距。不能为负值。

padding 包括四个方向,所以有如下的取值。

  • padding-top:上内边距
  • padding-right:右内边距
  • padding-bottom:下内边距
  • padding-left:左内边距

padding 单独编写是一个缩写属性:

css
padding: padding-top, padding-right, padding-bottom, padding-left;

padding 缩写属性是从零点钟方向开始,沿着顺时针转动的,也就是上右下左。

padding 并非必须是四个值,也可以有其他值。

注意:如果块级元素没有指定 width 属性,则此时 padding 不会撑开盒子的宽度;行内元素、行内块元素不管有没有设置 width 都会增加。对于高度都会增加元素的总高度。

3. border 边框

边框相对于 content / padding / margin 来说特殊一些。

  • 边框具备宽度 width;
  • 边框具备样式 style;
  • 边框具备颜色 color;
1)设置边框的方式

边框宽度

border-top-width 、border-right-width 、border-bottom-width 、border-left-width

border-width 是上面 4 个属性的简写属性。

边框颜色

border-top-color 、border-right-color 、border-bottom-color 、border-left-color

border-color 是上面 4 个属性的简写属性。

边框样式

border-top-style 、border-right-style 、border-bottom-style 、border-left-style

border-style 是上面 4 个属性的简写属性。

2)边框的样式设置值

边框的样式有很多,我们可以了解如下的几个:

groove:凹槽、沟槽。边框看上去好象是雕刻在画布之内。

ridge:山脊,和 grove 相反。边框看上去好象是从画布中凸出来。

3)同时设置的方式

如果我们相对某一边同时设置宽度、样式、颜色,可以进行如下设置:

  • border-top
  • border-right
  • border-bottom
  • border-left

border:统一设置 4 个方向的边框。

边框颜色、宽度、样式的编写顺序任意。

4)border-radius 圆角

border-radius 常见的值。

  • 数值:通常用来设置小的圆角,比如 6px;
  • 百分比:通常用来设置一定的弧度或者圆形。百分比是参照元素自身的宽度和高度。
css
border-radius: 左上角的圆角半径 右上角的圆角半径 右下角的圆角半径 左下角的圆角半径;

border-radius 事实上是一个缩写属性。将这四个属性 border-top-left-radius 、 border-top-right-radius 、 border-bottom-right-radius ,和 border-bottom-left-radius 简写为一个属性。

开发中比较少见一个个圆角设置。如果一个元素是正方形,设置 border-radius 大于或等于 50% (百分比值是相对于元素自身的宽度和高度的) 时,就会变成一个圆。

5)边框图片

边框图片学习推荐的博客:MCLIBRE - 免费课程材料

              掘金 LXLong

[1] border-image-source

用来定义边框要使用的图像。通过该属性可以指定一个图像来替换边框的默认样式,当 border-image-source 属性的值为 none 或者指定的图像不可用时,则会显示边框默认的样式。

CSS
border-image-source:none | <image>

如果仅使用此属性,则图像将显示在元素的所有四个角中。那怎么办?

[2] border-image-slice

用来分割通过 border-image-source 属性加载的图像。

css
border-image-slice:[ <number> | <percentage> ]{1,4} && fill?

数值表示图像被裁剪到离边缘多远的地方。

取值:
  • 一到四个数值(不带单位的百分比或数字):这些值在位图图像中被解释为像素,或在矢量图像中被解释为坐标。
  • <percentage>:用百分比的形式指定图像边框的宽度。参照图像边框区域的宽和高进行换算,不允许负值。
  • fill:默认中间图像不显示,设置 fill 值会导致使用图像的中间部分填充元素。

border-image-slice 属性设置图像的裁剪方式,但图像的大小缩放到边框的宽度。

[3] border-image-width

用来设置通过 border-image-source 属性加载的图像宽度。

css
border-image-width:[ <length> | <percentage> | <number> | auto ]{1,4}

特殊值:

  • <percentage>:用百分比的形式指定图像边框的宽度。参照图像边框区域的宽和高进行换算,不允许负值。
  • 不带单位的数字:将值乘以元素边框的大小 border-width。
  • auto:取 border-image-slice 定义的值。

一般设置 border-width 与 border-image-slice 大小一样。如果 border-width 值大于 border-image-slice,那么边框图像在 border-width 里面。否则在 border-width 外面,占据 padding 和 width,就像他们的背景一样,不占空间。

不设置 border-image-width 值,那么边框图像自动适应 border-width 大小。

[4] border-image-outset

用来定义图像边框相对于边框的偏离(使图像边框延伸到盒子模型以外)。

css
border-image-outset:[ <length> | <number> ]{1,4}

取值:

  • length:用具体的数值加单位的形式指定图像边框向外偏移的距离,不允许为负值。
  • number:不带单位的数字。表示将值乘以元素边框的大小 border-width。
[5] border-image-repeat

用来设置如何填充使用 border-image-slice 属性分割的图像边框。

css
border-image-repeat:[ stretch | repeat | round | space ]{1,2}

取值:

  • stretch:图像会拉伸或收缩以占用全部空间。
  • repeat:图像重复,占用全部空间(图像可能会截断)。
  • round:图像重复,并根据需要拉伸或收缩,占用全部空间。
  • space:图像尽可能多地重复,多余的空间分布在图像之间(图像不会拉伸或收缩)。
简写

border-image 是五个 border-image-* 属性的简写。

css
border-image: source slice [/width] [/outset] repeat;

4. margin 外边距

1)是什么

margin 属性用于设置盒子的外边距,通常用于元素和元素之间的间距。

margin 包括四个方向,所以有如下的取值。

  • margin-top:上内边距。

  • margin-right:右内边距。

  • margin-bottom:下内边距。

  • margin-left:左内边距。

margin 单独编写是一个缩写属性:margin: margin-top、margin-right、margin-bottom、margin-left

margin 缩写属性是从零点钟方向开始,沿着顺时针转动的 , 也就是上右下左。

margin 也并非必须是四个值,也可以有其他值。

2)注意

外边距合并 / 折叠:相邻块元素垂直外边距的合并。

当上下相邻的两个块元素(兄弟关系)相遇时,如果上面的元素有下外边距 margin-bottom,下面的元素有上外边距 margin-top ,则他们之间的垂直间距不是 margin-bottom 与 margin-top 之和。取两个值中的较大者这种现象被称为相邻块元素垂直外边距的合并。

**外边距塌陷 / 上下传递:**嵌套块元素垂直外边距的塌陷。

margin-top 传递:对于两个嵌套关系(父子关系)的块元素,父元素有上外边距,同时子元素也有上外边距,此时父元素会塌陷较大的外边距值。

margin-bottom 传递:如果块级元素的底部线和父元素的底部线重合,并且父元素的高度是 auto ,那么这个块级元素的 margin-bottom 值会传递给父元素。

关键点:① 最上面元素的上外边距、最下面元素的下外边距会塌陷到父元素。② 外边距塌陷只会发生在块级元素上。

解决方案:
① 可以为父元素定义上边框。
② 可以为父元素定义上内边距。
③ 父元素开启 BFC:可以为父元素添加 overflow:hidden。
还有其他方法,比如浮动、固定,绝对定位的盒子不会有塌陷问题。

备注:也有说法把外边距合并归为外边距塌陷 / 折叠。

3)负值问题

假如有两个 div 盒子。

垂直:给第一个设置 margin-top: -20px,第一个盒子会上移动 20px,第二个盒子跟随第一个盒子也上移动 20px。

水平:给第一个设置 margin-left: -20px,第一个盒子会左移动 20px,第二个盒子跟随第一个盒子也左移动 20px。

垂直:给第一个设置 margin-bottom: -20px,第一个盒子不动,第二个盒子会上移 20px。

水平:给第一个设置 margin-right: -20px,第一个盒子不动,第二个盒子会左移 20px。

二、其他

1. 盒子属性在行内非替换元素的特殊性

1)示例

内边距(padding):上下会被撑起来,但是不占据空间。

边框(border):上下会被撑起来,但是不占据空间。

外边距(margin):上下的 margin 是不生效的。

W3C 这样制定的意义何在?行内非替换元素是在段落里面的,如果给任何一个行内非替换元素添加 border、margin 这些会影响原来的结果,从而影响整体的美感。
例子源码,点击查看
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>盒子属性在行内非替换元素的特殊性</title>
  <style>
    .box {
      background-color: #f00;
      color: #fff;
      font-weight: 700;

      /* 内容:width/height 压根没有生效  */
      width: 100px;
      height: 100px;

      /* 内边距:padding 上下会被撑起来,但不占空间  */
      /* padding: 50px; */

      /* 边框:border 上下会被撑起来,但不占空间  */
      /* border: 50px solid orange; */

      /* 外边距:margin 上下会不生效 */
      margin: 50px;
    }
  </style>
</head>

<body>
  <span class="box">哈哈哈哈哈</span>呵呵呵
  <div>dddddd</div>
</body>
</html>
2)结论

行内非替换元素的注意事项

  • 以下属性对行内级非替换元素不起作用

    width、height、margin-top、margin-bottom

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

    padding-top、padding-bottom、上下方向的 border

2. 轮廓线 / 外轮廓

外轮廓不是盒子的一部分,不影响元素的尺寸和位置。

  • outline-width:外廓线宽度

    精确值:用长度值来定义轮廓的厚度。不允许负值。

    名词:medium - 定义默认宽度的轮廓。 thin - 定义比默认宽度细的轮廓。 thick - 定义比默认宽度粗的轮廓。

  • outline-style:外廓线风格

    none:无轮廓。与任何指定的 <outline-width> 值无关。

    dotted:点状轮廓。

    dashed:虚线轮廓。

    solid:实线轮廓

    double:双线轮廓。两条单线与其间隔的和等于指定的 <outline-width> 值。

    groove:3D 凹槽轮廓。

    ridge:3D 凸槽轮廓。

    inset:3D 凹边轮廓。

    outset:3D 凸边轮廓。

  • outline-color:外廓线颜色。

  • outline-offset:外廓线的偏移量。取值长度单位。

outline 复合属性。给元素周围绘制一条轮廓线。

css
outline: outline-width || outline-style || outline-color;

a 元素在 focus 后,有 outline,添加 outline: none; 去除。

给表单添加 outline: 0; 或者 outline: none; 样式之后,就可以去掉默认的 focus 后黑色或蓝色边框。

3. 阴影

box-shadow 是一个 CSS 属性,用于给元素添加阴影效果。它可以接受多个值,用于设置阴影的偏移量、模糊半径、扩展半径和颜色。

css
box-shadow: h-offset v-offset [blur spread color inset];

解释:

  • h-offset:水平偏移量。正值会将阴影向右偏移,负值会将阴影向左偏移。
  • v-offset:垂直偏移量。正值会将阴影向下偏移,负值会将阴影向上偏移。
  • blur:模糊半径。值越大,阴影的边缘就越模糊。
  • spread:扩展半径。正值会使阴影扩大,负值会使阴影缩小。
  • color:阴影的颜色。
  • inset:将外部阴影改为内部阴影。

注意:box-shadow 也支持指定多层阴影,使用英文逗号分割即可。

在线阴影调试网站:Box Shadow CSS Generator

4. 盒模型

CSS3 中可以通过 box-sizing 来指定盒模型,这样计算盒子大小的方式就发生了改变。

可以分成两种情况:

  • box-sizing: content-box; 盒子大小为 width + padding + border
  • box-sizing: border-box; 盒子大小为 width

如果盒子模型改为了 box-sizing: border-box;, 那 padding 和 border 就不会撑大盒子了(前提 padding 和 border 不会超过 width 宽度)。

标准盒模型:元素的 width 和 height 只包括内容的宽度和高度,不包括内边距和边框。

怪异盒模型:元素的 width 和 height 包括了内容、内边距和边框。

第五章:CSS 定位

一、是什么?

定位是将盒子定在某一个位置。所以定位也是在摆放盒子,按照定位的方式移动盒子。定位 = 定位模式 + 边偏移。

定位模式:用于指定一个元素在文档中的定位方式。

边偏移:决定了该元素的最终位置。

top、bottom、left、right 和 position。且只能应用于块级元素。设置百分比值,参考系为包含块。

包含块

绝对定位的元素其实是以他的包含块元素为基准进行定位的,但是元素 position 设置的不同,其包含块也会引起变化。

① 如果一个元素自身的 position 属性是 static 或者是 relative,它的包含块就是离他最近的祖先元素(块级容器、格式化上下文的创建者,如表格单元格、行内块元素)的内容区域。

② 如果一个元素自身的 position 属性是 absolute,它的包含块就是离他最近的拥有定位属性(值不为 static)元素的 padding 区域。

③ 如果一个元素自身的 position 属性是 fixed,那么它的包含块就是初始化包含块(通常是视口)。

④ 如果由内向外找不到包含块条件的元素,那么 html(根元素)被称作为初始包含块。

二、定位方式

1. 静态定位 static

默认情况下,元素都是按照 normal flow(标准流、常规流、正常流、普通流、文档流【 document flow 】)进行排布。

从左到右、从上到下按顺序摆放好。互相之间不存在层叠现象。

html
<body>
  <span>span1</span>
  <img src="images/cube.jpg" alt="">
  <span style="display: inline-block">span2</span>
  <div>div</div>
  <p>p</p>
  <span style="display: inline-block">span</span>
  <strong>strong</strong>
  <h1>h1</h1>
  <span>span3</span>
  <span style="display: inline-block">span4</span>
  <span>span5</span>
</body>

这种标准流布局在 CSS 中称为静态定位。

css
position: static;

left 、right 、top 、bottom 没有任何作用。

2. 相对定位 relative

相对定位是元素按照 normal flow 布局,但可以通过 left、right、top、bottom 进行定位。

定位参照对象是元素自己原来的位置。原来在标准流的位置继续占有(相对定位并没有脱标),后面的盒子仍然以标准流的方式对待它。

left、right、top、bottom 用来设置元素的具体位置,对元素的作用如下图所示。

应用场景:在不影响其他元素位置的前提下,对当前元素位置进行微调。

3. 绝对定位 absolute

1)是什么?

元素脱离 normal flow(脱离标准流、脱标),不再占有原先的位置。可以通过 left、right、top、bottom 进行定位。定位参照对象是最邻近的定位祖先元素。如果找不到这样的祖先元素参照对象是视口。

定位元素(positioned element)是 position 值不为 static 的元素。也就是 position 值为 relative 、absolute 、fixed 的元素。

下面三个条件满足任何一个时,使用绝对定位:

① 元素出现在一个天马行空的位置

② 元素存在,但不影响其他元素的排列

③ 单个元素在某个区域内水平垂直居中

开发技巧:子绝父相

在绝大数情况下,子元素的绝对定位都是相对于父元素进行定位。如果希望子元素相对于父元素进行定位,又不希望父元素脱标,常用解决方案是:

  • 父元素设置 position: relative(让父元素成为定位元素,而且父元素不脱离标准流)。
  • 子元素设置 position: absolute。

简称为 “子绝父相”。

2)绝对定位元素的特点

绝对定位元素是将 position 设置为 absolute / fixed 元素。

特点一

  • 脱离标准流:不再受标准流的约束。不再严格按照从上到下、从左到右排布。
  • 成为绝对定位元素:不再严格区分块级 ( block )、行内级 ( inline )、行内块级 ( inline block ) 的很多特性都会消失。
  • 可以随意设置宽高。宽高默认由内容决定。
  • 不再给父元素汇报宽高数据。
  • 脱标元素内部默认还是按照标准流布局。

特点二

绝对定位元素( absolutely positioned element )

  • position 值为 absolute 或者 fixed 的元素。

对于绝对定位元素来说。

  • 定位参照对象的宽度 = left + right + margin left + margin right + 绝对定位元素的实际占用宽度。
  • 定位参照对象的高度 = top + bottom + margin top + margin bottom + 绝对定位元素的实际占用高度。

如果希望绝对定位元素的宽高和定位参照对象一样,可以给绝对定位元素设置以下属性。

left: 0 、right: 0 、top: 0 、bottom: 0 、margin: 0 (默认值)

如果希望绝对定位元素在定位参照对象中居中显示,可以给绝对定位元素设置以下属性。

left: 0 、right: 0 、top: 0 、bottom: 0 、margin: auto

另外,还得设置具体的宽高值(宽高小于定位参照对象的宽高)。

注意:绝对定位的元素无法再设置浮动。

4. 固定定位 fixed

固定定位是元素固定于浏览器可视区的位置。

固定定位的特点

  • 以浏览器的可视窗口为参照点移动元素。
  • 跟父元素没有任何关系。
  • 不随滚动条滚动。
  • 固定定位不在占有原先的位置。

固定定位也是脱标的,其实固定定位也可以看做是一种特殊的绝对定位。

开发技巧:固定在版心右侧位置

1)让固定定位的盒子 left: 50%(固定定位元素的百分比值总是相对于视口),走到浏览器可视区(也可以看做版心) 的一半位置。

2)让固定定位的盒子 margin-left: 正值 版心宽度的一半距离。 多走版心宽度的一半位置。

就可以让固定定位的盒子贴着版心右侧对齐了。

必知必会:设置定位元素(绝对和固定)在包含块中水平垂直都居中

方案一:

css
position: absolute/fixed;
left: 50%;
top:50%;
margin-left: -自身总宽度/2;
margin-top: -自身总高度/2;

方案二:

css
position: absolute/fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;

5. 粘性定位 sticky

另外还有一个定位的值是 position: sticky,比其他定位要新一些。

sticky 是一个大家期待已久的属性。可以看做是相对定位和固定绝对定位的结合体。

它允许被定位的元素表现得像相对定位一样,直到它滚动到某个阈值点。当达到这个阈值点时,就会变成固定绝对定位。

sticky 是相对于最近的滚动祖先包含滚动视口的。

粘性定位的特点

  • 以浏览器的可视窗口为参照点移动元素(固定定位特点)。
  • 粘性定位占有原先的位置(相对定位特点)。
  • 必须添加 top 、left、right、bottom 其中一个才有效。
  • 跟页面滚动搭配使用。 兼容性较差,IE 不支持。

三、层叠顺序 z-index

z-index 属性用来设置定位元素的层叠顺序(仅对定位元素有效)。取值可以是正整数、负整数、auto (默认值) 。

堆叠上下文

在 CSS 中,堆叠上下文(Stacking Context)是一个三维的概念,它决定了元素如何在页面的 z 轴(深度)上排列。在同一堆叠上下文中,元素的堆叠顺序由 z-index 属性决定。

创建新的堆叠上下文的一些常见方式包括:

  • 根元素(HTML 文档的根元素)总是创建一个新的堆叠上下文。
  • 元素的 position 属性值为 absolute 或 relative 并且 z-index 值不是 auto。
  • 元素的 position 属性值为 fixed 或 sticky。
  • 元素的 opacity 属性值小于 1。
  • 元素的 transform、filter、perspective、clip-path、mask、mask-image、mask-border 属性值不是 none。
  • z-index 属性值不为 auto 的 flex 元素(父元素 display: flex|inline-flex)。
  • ……

比较规则

  • 普通元素 < 浮动元素 < 定位元素。

  • 在同一堆叠上下文中,z-index 值较大的元素会覆盖 z-index 值较小的元素。如果两个元素的 z-index 值相同,那么后出现在 HTML 代码中的元素会覆盖先出现的元素。

  • 如果元素 B 和元素 C 处于不同的堆叠上下文,那么无论 B 的 z-index 值如何,它都无法覆盖 C,除非 B 所处的堆叠上下文在 C 的堆叠上下文之上。

    点我查看代码

    A 元素相对定位;B、C 元素绝对定位。

    html
    <!-- 左边 -->
    <body>
      <div class="a">       <!-- relative -->
        A z-index: auto
        <div class="b">     <!-- absolute -->
          B z-index: 100
        </div>
      </div>
      <div class="c">       <!-- absolute -->
        C z-index: 80
      </div>
    </body>
    
    <!-- 右边 -->
    <body>
      <div class="a">
        A z-index: 20
        <div class="b">
          B z-index: 100
        </div>
      </div>
      <div class="c">
        C z-index: 80
      </div>
    </body>
  • 在同一堆叠上下文中,子元素一定覆盖父元素,不管父元素 z-index 值多大。

    点我查看代码
    html
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <title>Z-Index 1</title>
      <style>
        div {
          padding: 25px;
          font-size: larger;
        }
    
        #box1 {
          background-color: chocolate;
          width: 200px;
          height: 100px;
          margin-bottom: -50px;
        }
    
        #content {
          background-color: gold;
          width: 200px;
          height: 100px;
          margin-left: 50px;
          z-index: 6;
          position: relative;
        }
    
        #box2 {
          background-color: cyan;
          width: 200px;
          height: 100px;
          margin-top: -50px;
          z-index: 3;
          position: relative;
        }
    
        #box2-3 {
          background-color: green;
          width: 200px;
          height: 100px;
          padding-left: 150px;
          left: 180px;
          top: -50px;
          z-index: 1;
          position: absolute;
        }
      </style>
    </head>
    
    <body>
      <div id="box1">
        Box 1
      </div>
    
      <div id="content">
        Content <br />
        z-index: 6; <br />
        position: relative;
      </div>
    
      <div id="box2">
        <br /><br />
        Box 2 <br />
        z-index: 3; <br />
        position: relative;
        <div id="box2-3">
          Box 2-3 <br />
          z-index: 1; <br />
          position: absolute;
        </div>
      </div>
    </body>
    
    </html>

四、附加 - inset 属性

inset 是一个 CSS 简写属性,用于同时设置元素的 top、right、bottom 和 left 属性。旨在简化定位元素的代码。

1. 语法

css
/* 所有边都使用相同值 */
inset: all;

/* [top/bottom] [right/left] */
inset: vertical horizontal;

/* [top] [horizontal] [bottom] */
inset: top horizontal bottom;

/* [top] [right] [bottom] [left] */
inset: top right bottom left;

2. 常见应用场景

css
/* 不对称定位 */
.asymmetric {
  position: fixed;
  inset: 0 0 auto auto; /* 固定在右上角 */
  width: 200px;
  height: 100px;
}

/* 创建全覆盖层 */
.overlay {
  position: absolute;
  inset: 0;
}

/* 居中定位元素 */
.centered {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 50%;
  height: 50%;
}

3. 实际案例 - 模态框

css
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal-content {
  position: relative;
  width: 80%;
  max-width: 500px;
  background: white;
  padding: 20px;
  border-radius: 8px;
}

第六章:CSS 高级技巧

一、元素的显示与隐藏

方法一:使用 display: none;,这会使元素及其内容完全消失,不占用任何空间。

css
display: none;

方法二:使用 visibility: hidden;,这会使元素不可见,但它仍然占用空间。且不可以响应绑定的事件。

css
visibility: hidden;

方法三:使用 opacity: 0;,这会使元素完全透明,但它仍然占用空间,并且可以交互(例如,点击或悬停) , 影响子元素。

opacity 用于改变元素的不透明度。值范围是 0 到 1。0 表示元素完全透明,1 表示元素完全不透明。

css
opacity: 0;

方法四:rgba 设置颜色 , 将 a 的值设置为 0。

rgba 的 a 设置的是 alpha 值 , 可以设置透明度 , 不影响子元素。

二、内容溢出

CSS 属性名功能属性值
overflow设置溢出内容的显示方式visible:显示,默认值。
hidden:隐藏。
scroll:滚动条。
auto:自动。
overflow-xx 轴方向溢出内容的显示方式同上
overflow-yy 轴方向溢出内容的显示方式同上

auto 和 scroll 的区别

① scroll 不论内容是否会溢出,都有滚动条。

② auto 只有内容溢出才会显示滚动条。

三、vertical-align 属性

官方解释

vertical-align 用来指定行内(inline)、行内区块(inline-block)、表格单元格 td、th(table-cell)盒子的垂直对齐方式。

注意:如果元素里只有文本,不能让文本垂直居中。主要用于让行内块和行内元素与同行文本如何对齐。

语法

css
vertical-align : baseline | top | middle | bottom | <percentage> | <length> | sub | super

baseline 神秘面纱

vertical-align 默认值是 baseline。但是 baseline 都是谁呢?

  • 文本的 baseline 是字母 x 的下方。

  • 对于 inline-block 元素,其默认的 baseline(基线)位置是在元素的底部。如果该 inline-block 元素有 margin-bottom,那么 baseline 就是 margin-bottom 的底边。

  • inline-block 有文本时,baseline 是最后一行文本的 x 的下方。

重要取值解释

  • top:把行内级盒子的顶部跟 line boxes 顶部对齐。
  • bottom:把行内级盒子的底部跟 line boxes 底部对齐。
  • middle:行内级盒子的中心点与父盒基线加上 x-height 一半的线(x 中线)对齐。
  • <percentage>:把行内级盒子提升或者下降一段距离(距离相对于 line-height 计算/元素高度),0% 意味着同 baseline 一样。
  • <length>:把行内级盒子提升或者下降一段距离,0cm 意味着同 baseline 一样。
    • 正值 = 向上偏移。
    • 负值 = 向下偏移。

使用场景

CSS 的 vertical-align 属性经常用于设置图片或者表单(行内块/行内级元素)和文字垂直对齐。

应用一:文本、图片、表单默认的 vertical-align 是基线对齐。

应用二:图片底侧会有一个空白缝隙,原因是行内块元素会和文字的基线对齐。解决方法:

① 给图片添加 vertical-align:middle | top| bottom 等。(推荐)

② 把图片转换为块级元素 display: block;

③ 设置图片父元素的字体大小为 0(四线距离为 0)。

四、精灵图

精灵技术就是把多个小图片整合到一张大图片中。这个大图片也称为精灵图(sprites)或者雪碧图。

作用:减少网络的请求次数。因为图片只要下载一次就好,不用再分别去下载那些小图。

使用精灵图核心:

① 使用精灵图的时候需要精确测量,每个小背景图片的大小和位置。

② 移动背景图片位置,此时可以使用 background-position。移动的距离就是这个目标图片的 x 和 y 坐标。

注意:网页中的坐标有所不同。因为一般情况下都是往上往左移动,所以数值是负值。

css
.sprite {
  background: url(imgs/example.png) no-repeat -433px -51px;
  width: 33px;
  height: 33px;
}

精灵图坐标获取:生成精灵表的 CSS

精灵图生成:CSS 精灵生成器工具

五、字体样式 / 图标

1. 字体样式

1)格式
css
@font-face {
  font-family: <identifier>;
  src: <fontsrc> [<string>] [, <fontsrc> [<string>]]*;
  [<font>];
}
2)相关参数
  • identifier:字体名称。
  • fontsrc:此值指的是你自定义的字体的存放路径,可以是相对路径也可以是绝路径。
  • string:字体的格式,主要用来帮助浏览器识别。format(fontType)
  • [<font>]; 表示一组可选的字体描述符,它们用来定义字体的特性。
css
@font-face {
  font-family: 'diyfont';
  /* font-display: fallback; */
  src: url('diyfont.eot'); /* IE9兼容模式 */
  src: url('diyfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
       url('diyfont.woff') format('woff'), /* chrome、firefox opera  safari  IE9+ 最佳格式 */
       url('diyfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+ IE9+ */
       url('diyfont.svg#fontname') format('svg'); /* iOS 4.1- */
}

/* 使用 */
.box {
  font-family: "diyfont";
}

font-display 用来控制在自定义字体(通过 @font-face 引入)下载和渲染之前,页面上的文字该如何进行展示,以及字体加载完成后如何切换。常见取值:

  1. block

    • 在较长的一段时间内(称为“阻塞期”或 block period),文字会处于“不可见”或“空白”状态,等待自定义字体加载完。
    • 如果自定义字体在这段时间内加载完,就会直接用该字体渲染文字。
    • 若超过这段时间仍未加载完,则先使用后备字体(fallback font)显示文字,但当自定义字体最终加载成功后,依然会把文字替换为自定义字体。
  2. swap

    • 一开始就用后备字体先显示文字。
    • 当自定义字体加载完成后,直接把已经显示的文字“切换”到自定义字体(会有一次明显的字体切换过程)。
  3. fallback

    • 有一个非常短的阻塞期(例如 100ms 左右),如果在这个极短时间内字体加载完,则直接使用自定义字体。
    • 否则,浏览器就会使用后备字体进行展示,并且不会再切换到自定义字体。
    • 也就是说如果字体加载得太慢,页面就不会再改用自定义字体了。

中文字体免费下载和在线预览-字体天下

在线字体编辑器

2. 字体图标

推荐网址

在线字体图标下载推荐网址:https://www.iconfont.cn
                https://www.flaticon.com
                https://www.iconninja.com

使用方法

  • 方法一:使用 Unicode。

  • 方法二:使用类选择器。

    html
    <!-- y ma -->
    <style>
    @font-face {
      font-family: "iconfont"; /* Project id 4837240 */
      src: url('iconfont.woff2?t=1757334687231') format('woff2'),
           url('iconfont.woff?t=1757334687231') format('woff'),
           url('iconfont.ttf?t=1757334687231') format('truetype');
    }
    
    .iconfont {
      font-family: "iconfont" !important;
      font-size: 16px;
      font-style: normal;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }
    
    .icon-snails:before {
      content: "\e610";
    }
    </style>
    
    <!-- 使用 -->
    <span class="iconfont icon-snails"></span>

六、CSS 三角

网页中常见一些三角形,使用 CSS 就可以画出来,不必做成图片或字体图标。

方法一

在 CSS 中,可以使用边框来创建一个三角形。例如,创建一个向上的三角形:

css
.triangle-up {
  width: 0;
  height: 0;
  /* 三角形高度 */
  border-bottom: 100px solid red;
  /* 三角形宽度是这两个值相加 */
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
}

方法二

先画一个向下的三角形,然后旋转朝上。

css
.box {
  box-sizing: border-box;

  width: 100px;
  height: 100px;

  border: 50px solid orange;
  /* border-right-color: blue;
     border-bottom-color: aqua;
     border-left-color: blueviolet; */

  border-right-color: transparent;
  border-bottom-color: transparent;
  border-left-color: transparent;

  /* 旋转 */
  transform-origin: center 25%;
  transform: rotate(180deg);
}

简化代码:

css
.box {
  box-sizing: border-box;

  width: 100px;
  height: 100px;

  border: 50px solid transparent;
  border-top-color: orange;

  /* 旋转 */
  transform-origin: center 25%;
  transform: rotate(180deg);
}

七、溢出的文字省略号显示

1. 单行文本溢出显示省略号

需要注意父级元素或者需要省略号的元素要有宽度,否则此设置无效。

css
/* 1.先强制一行内显示文本 */
white-space: nowrap;
/* 2.超出的部分隐藏 */
overflow: hidden;
/* 3.文字用省略号替代超出的部分 */
text-overflow: ellipsis;

2. 多行文本溢出显示省略号

多行文本溢出显示省略号,有较大兼容性问题,适合于 webKit 浏览器或移动端(移动端大部分是 webkit 内核)。

css
overflow: hidden;
text-overflow: ellipsis;
/* 弹性伸缩盒子模型显示 */
display: -webkit-box;
/* 设置或检索伸缩盒对象的子元素的排列方式 */
-webkit-box-orient: vertical;
/* 限制在一个块元素显示的文本的行数 */
-webkit-line-clamp: 2;

八、浏览器兼容性

1. 提高兼容性的设置

1)使用最新版 IE 渲染

html
<meta http-equiv="X-UA-Compatible" content="IE=Edge">

2)让双核浏览器默认使用 webkit 内核

html
<meta name="renderer" content="webkit">

2. CSS hack / IE hack

由于不同厂商的浏览器,或者是同一个浏览器不同的版本(IE),对 css 的解析和认识不完全一样可能会导致不同浏览器显示的效果不相同,那么我们需要针对某个浏览器,去写不同的样式,让代码能够兼容所有的浏览器。

1)CSS 属性前缀法
css
*color  /*ie 5,6,7*/
+color  /*ie 5,6,7*/
#color  /*ie 5,6,7*/
_color  /*ie 5,6*/
color\0:  /*ie 9,10,11*/
color\9:ie  /*ie 6,7,8,9,10*/
color\9\0  /*ie 8,9,10*/
2)选择器前缀法
css
/*ie 5,6*/
*div{
}

/*ie 7*/
*+div{
}

3. IE 条件注释

IE 中的条件注释对 IE 的版本和非 IE 版本有优秀的区分能力。

条件注释的基本结构和 HTML 的注释 <!-- --> 是一样的。因此 IE 以外的浏览器将会把它们看作是普通的注释而完全忽略它们。

IE9 以及 IE9 以下浏览器可以识别条件注释。

比较符号

lt     表示    <
gt     表示    >
gte    表示    >=
lte    表示    <=
!      表示    !=

案例

html
<!--[if IE 8]>仅IE 8可见<![endif]-->

<!--[if gt IE 8]>仅IE 8以上可见<![endif]-->

<!--[if lt IE 8]>仅IE 8以下可见<![endif]-->

<!--[if gte IE 8]>IE 8及以上可见<![endif]-->

<!--[if lte IE 8]>IE 8及以下可见<![endif]-->

<!--[if !IE 8]>非IE 8的IE可见<![endif]-->

<!--[if !IE]><!--> 您使用不是 Internet Explorer <!--<![endif]-->

下面是 Bootstrap 文档(Bootstrap 版本 3.4)。

4. CSS3 私有前缀

在 CSS3 中,由于一些属性和功能还没有得到标准化或者被所有浏览器所支持,为了实现这些新功能,浏览器厂商会在属性名称前加上私有前缀。这些私有前缀只在该浏览器中生效,其他浏览器会忽略它们。

以下是一些常见的浏览器私有前缀:

  • Webkit:用于 Chrome、Safari 等基于 Webkit 内核的浏览器,前缀为 -webkit-
  • Mozilla:用于 Firefox 浏览器,前缀为 -moz-
  • Microsoft:用于 Internet Explorer 和 Edge 浏览器,前缀为 -ms-
  • Opera:用于 Opera 浏览器,前缀为 -o-

第七章:CSS 布局

一、元素浮动

1. 认识浮动

float 属性可以指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。

float 属性最初只用于在一段文本内浮动图像,实现文字环绕的效果。但是早期的 CSS 标准中并没有提供好的左右布局方案,因此在一段时间里面它成为网页多列布局的最常用工具。

注意
绝对定位、浮动都会让元素脱离标准流,以达到灵活布局的效果。
绝对定位、浮动都会让元素的 display 改为 block。

设置浮动

可以通过 float 属性让元素产生浮动效果,float 的常用取值。

  • none:不浮动,默认值。
  • left:向左浮动。
  • right:向右浮动。

2. 浮动规则

  • 脱离标准流。

  • 不在区分块级 / 行级 / 行内级元素。浮动元素有自己的显示特点了。

    • 可以随意设置宽高,默认宽度会根据内容进行计算。

    • 可以随意设置 margin 与 padding。因为不存在外边距的高度塌陷与合并问题了。

    • 设置左右外边距 auto 不在居中了。

    • 不会被父元素当作行内级元素处理了。也就是 text-align: center 无法使浮动元素水平居中。

  • 停止浮动规则:朝着向左或向右方向移动,直到遇到父级的边界或者是上一个浮动元素或者是上一个不浮动兄弟元素就停下来。

    自动换行:如果水平方向剩余的空间不够显示浮动元素,浮动元素将向下移动,直到有充足的空间为止。

    带圆圈的数字标记着浮动元素浮动之前的位置。

  • 浮动元素不能与行内级内容层叠,行内级内容将会被浮动元素推出。

    比如行内级元素、inline-block 元素、块级元素的文字内容。

  • 行内级元素、inline-block 元素浮动后,其顶部将与所在行的顶部对齐。

  • 定位元素会层叠在浮动元素上面。

开发技巧

去除行内级元素间隙有:① 删除换行;② 父级元素 font-size 设置为 0,子元素 font-size 设置为 x px;③ 使用浮动去除;④ display: flex;

行内块元素底部的空白:① 父级元素 font-size 设置为 0;② vertical-align: bottom;③ 图片设置为块元素。

行内块元素垂直对齐问题
1)如果行内块元素中没有文字,该元素的底部与基线对齐。
2)如果行内块元素中有一行文字,文字与外面的基线对齐,进而影响行内块元素的位置。
3)如果行内块元素中有多行文字,最后一行文字与外面的基线对齐,进而影响行内块元素的位置。
解决方案:给行内块元素设置 vertical-align,值不是 baseline 都可以解决问题。

元素居中
行内级元素使用 text-align: center;line-height: px;
行内块级使用 text-align: center;vertical-align: middle;。里面的文字使用 line-height: px; 垂直居中。
块级元素水平使用 margin: 0 auto;,垂直需要精确计算。
浮动元素在父元素里居中,垂直水平都需要精确计算。

3. 清除浮动

1)问题

浮动的元素会脱离文档流,按照指定的方向发生移动,遇到父级的边界或者是上一个浮动元素或者是上一个不浮动兄弟元素就停下来。所以,浮动元素前面的元素不会受到影响,后面的兄弟元素和父元素会受到影响。

  • 后面的兄弟元素会当做浮动的元素不存在,可能会与浮动元素位置发生重合。
  • 父元素高度塌陷问题:浮动的元素脱离父级区域,无法撑开父元素的高度,造成父元素高度塌陷。进而会影响到父元素后面的兄弟元素,造成布局问题。
2)解决手段
  1. 父级设置高度:给浮动元素的父级设置高度 height(不推荐使用)

    缺点:很多情况下元素的高度都是不确定的。

  2. 以浮制浮:给浮动元素的父元素设置浮动,原理是开启 BFC(不推荐使用)

    缺点:只有在父级需要浮动的时候,可以这么清除,否则父级的浮动会继续影响其他元素。

  3. 使用 overflow 属性:给包含浮动元素的父元素设置 overflow 属性为 auto 或 hidden 也可以清除浮动。这是因为设置 overflow 属性会创建一个新的块格式化上下文(BFC),这可以清除内部的浮动。

    缺点:元素超出的时候,会隐藏超出部分。但这种方式简单快捷。

    css
    .parent {
      overflow: auto;
    }
  4. 使用 clear 属性:可以在浮动元素后面添加一个元素,并设置其 clear 属性为 left、right 或 both。这会使新元素清除前面浮动元素的浮动效果,防止它与浮动元素重叠。

    缺点:增加额外的结构,不符合语义化标准。

    html
    <div style="float: left;">我是浮动元素</div>
    <div style="clear: both;"></div>
  5. 使用伪元素:这是一种更现代的方法,通常被称为 "clearfix hack"。可以给包含浮动元素的父元素添加一个伪元素,并设置其 clear 属性为 both。

    css
    .clearfix::after {
      content: ""; /* 必须拥有content属性,内容为空 */
      display: block; /* 必须块标签才能清浮动,此处也可写table */
      clear: both; /* 清除浮动 */
      height: 0; /* 伪元素的高度为 0,不占据空间 */
      visibility: hidden; /* 伪元素不可见 */
    }
    
    /* 兼容旧版本的IE浏览器(主要是IE6和IE7) */
    .clearfix {
      /*
        通过 zoom: 1 触发 hasLayout 机制,hasLayout 使容器包含浮动元素
        * 是一种 CSS Hack,仅在 IE6 和 IE7 中生效。
      */
      *zoom: 1;
    }

    然后给需要清除浮动的元素的父元素添加 clearfix 类:

    html
    <div class="clearfix">
      <div style="float: left;">我是浮动元素</div>
    </div>

二、Flex 布局

1. 认识 flexbox

Flexbox 翻译为弹性盒子。弹性盒子是一种用于按行或按列布局元素的一维布局方法。元素可以膨胀以填充额外的空间,收缩以适应更小的空间。

通常我们使用 Flexbox 来进行布局的方案称之为 flex 布局。

flex 布局( Flexible 布局、弹性布局)是目前 web 开发中使用最多的布局方案。特别在移动端可以说已经完全普及。在 PC 端也几乎已经完全普及和使用,只有非常少数的网站依然在用浮动来布局。

为什么需要 flex 布局呢?

长久以来,CSS 布局中唯一可靠且跨浏览器兼容的布局工具只有 floats 和 positioning。但是这两种方法本身存在很大的局限性,并且他们用于布局实在是无奈之举。

2. 专业术语

重要概念

开启了 flex 布局的元素叫 flex container。flex container 里面的直接子元素叫做 flex item。伸缩项目都是块级格式上下文 (BFC) 。

当 flex container 中的子元素变成了 flex item 时,具备以下特点:

  • flex item 的布局将受 flex container 属性的设置来进行控制和布局。

  • flex item 不再严格区分块级元素和行内级元素。

  • flex item 默认情况下是包裹内容的,但是可以设置宽度和高度。

其 CSS 实现方式是设置 display 属性为 flex 或者 inline-flex 可以成为 flex container。

  • flex:flex container 以 block-level 形式存在。
  • inline-flex:flex container 以 inline-level 形式存在。

注意:如果一个元素既是 flex item,又是 flex container,他的显示特点还是以 flex item 为准。

布局模型

3. flex 相关的属性

应用在 flex container 上的 CSS 属性。

  • flex-direction
  • flex-wrap
  • flex-flow
  • justify-content
  • align-items
  • align-content

应用在 flex items 上的 CSS 属性。

  • order

  • align-self

  • flex-grow

  • flex-shrink

  • flex-basis

  • flex

4. flex container 属性

1)flex-direction

flex items 默认都是沿着 main axis(主轴)从 main start 开始往 main end 方向排布。

flex-direction 决定了 main axis 的方向,有 4 个取值。

row(默认值)、row-reverse、column、column-reverse

2)flex-wrap

flex-wrap 决定了 flex container 是单行还是多行。

  • nowrap(默认):单行。

  • wrap:多行。

  • wrap-reverse:多行。对比 wrap,cross start 与 cross end 相反(大白话就是新的行不是在原行的下方,而是在原行的上方)。

3)flex-flow

flex-flow 属性是 flex-direction 和 flex-wrap 的简写。

顺序任意,并且都可以省略。

4)justify-content

justify-content 决定了 flex items 在 main axis 上的对齐方式。

  • flex-start(默认值):与 main start 对齐。
  • flex-end:与 main end 对齐。
  • center:居中对齐。
  • space-between:flex items 之间的距离相等。与 main start 、main end 两端对齐。
  • space-around:flex items 之间的距离相等。flex items 与 main start 、main end 之间的距离是 flex items 之间距离的一半。
  • space-evenly:flex items 之间的距离相等。flex items 与 main start 、main end 之间的距离等于 flex items 之间的距离。
5)align-items

align-items 决定了 flex items 在 cross axis 上的对齐方式。

  • normal:在弹性布局中,效果和 stretch 一样。
  • stretch(默认值):当 flex items 在 cross axis 方向的 size 为 auto 时,会自动拉伸至填充 flex container。
  • flex-start:与 cross start 对齐。
  • flex-end:与 cross end 对齐。
  • center:居中对齐。
  • baseline:与基准线对齐。
6)align-content

align-content 决定了多行 flex items 在 cross axis 上的对齐方式,用法与 justify-content 类似。

  • stretch(默认值):与 align-items 的 stretch 类似。
  • flex-start:与 cross start 对齐。
  • flex-end:与 cross end 对齐。
  • center:居中对齐。
  • space-between:flex items 之间的距离相等。与 cross start 、cross end 两端对齐。
  • space-around:flex items 之间的距离相等。flex items 与 cross start 、cross end 之间的距离是 flex items 之间距离的一半。
  • space-evenly:flex items 之间的距离相等。flex items 与 cross start 、cross end 之间的距离等于 flex items 之间的距离。

在伸缩盒中,要想实现居中,怎么办?

justify-content: centeralign-items: center (用于需要居中元素的父元素)

这种方式也作用于 flex 容器里的文字,也就是说可以让文字在容器内水平垂直居中。

margin: auto (用于需居中的元素)

很纳闷?为什么 margin: auto 也可以实现垂直居中???

因为伸缩盒布局中没有横纵轴之分。四个方向都是平等的,都是平分的。且主侧轴也能来回换方向。

5. flex-item 属性

1)order

order 决定了 flex items 的排布顺序。

可以设置任意整数(正整数、负整数、0),值越小就越排在前面。默认值是 0。

2)align-self

flex items 可以通过 align-self 覆盖 flex container 设置的 align-items。

auto(默认值):遵从 flex container 的 align-items 设置。

stretch、flex-start、flex-end、center、baseline,效果跟 align-items 一致。

3)flex-grow

flex-grow 决定了 flex items 如何扩展、拉伸、成长。

可以设置任意非负数字(正小数、正整数、0),默认值是 0。

当 flex container 在 main axis 方向上有剩余 size 时,flex-grow 属性才会有效。

如果所有 flex items 的 flex-grow 总和 sum 超过 1,每个 flex item 扩展的 size 为 flex container 的剩余 size * (flex-grow / sum)

flex items 扩展后的最终 size 不能超过 max-width / max-height。

4)flex-shrink

flex-shrink 决定了 flex items 如何收缩、缩小。

可以设置任意非负数字(正小数、正整数、0),默认值是 1。

当 flex items 在 main axis 方向上超过了 flex container 的 size,flex-shrink 属性才会有效。

如果所有 flex items 的 flex-shrink 总和超过 1,每个 flex item 收缩的 size 为:

亏空长度 = 总共 flex items 的长度 - flex container 的 size

每个 flex items 缩的长度 = 亏空长度 * ([自己设置的长度 * 收缩比例] / 亏空长度与每个 flex-item 的 flex-shrink 相乘后相加)

// ***********************************************************************************************
假设有三个 items,item01 设置的宽度为 100、item02 设置的宽度为 200、item03 设置的宽度为 300。
容器的宽度为 500。
item01 的 flex-shrink 为 5、item02 的 flex-shrink 为 3、item03 的 flex-shrink 为 2。

			原来的主轴长度    收缩比率      瓜分比重        最后长度
.item01         100            5        500/1700     100-100*5/17
.item02         200            3        600/1700     200-100*6/17
.item03         300            2        600/1700     300-100*6/17

亏空长度: 100
分母:    100*5 + 200*3 + 300*2 = 1700

flex items 收缩后的最终 size 不能小于 min-width / min-height。

5)flex-basis

flex-basis 用来设置 flex items 在 main axis 方向上的 base size(伸缩之前的大小)。取值如下。

  • auto(默认值):基础尺寸由元素的内容或设置的 width/height 决定。
  • 具体的宽度数值。

决定 flex items 最终 base size 的因素,从优先级高到低。

  • max-width / max-height / min-width / min-height
  • flex-basis
  • width / height
  • 内容本身的 size
6)flex 属性

flex 是 flex-grow || flex-shrink || flex-basis 的简写,flex 属性可以指定 1 个, 2 个或 3 个值。

flex = 
  none         |
  [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]

/*
  <...> 表示一个值的类型或者一个特定的值。
  || 表示“或者”,表示可以选择其中的一个或多个值。
  ? 表示前面的值是可选的。
  [...] 表示这是一个值的集合,可以选择其中的一个或多个。
*/
/*
  常见写法:
  如果缩写为 flex: 1 , 则其计算值为 1 1 0。表示设置的 width 与 height 无效,宽度为 0,但可以平均分配剩下的空间与收缩。
  如果缩写 flex: auto , 则其计算值为 1 1 auto
  如果 flex: none , 则其计算值为 0 0 auto
  如果 flex: 0 auto 或者 flex: initial , 则其计算值为 0 1 auto,即 flex 初始值
*/
  • 单值语法:值必须是以下之一
    • 一个 <flex-grow> 的有效值:此时简写会扩展为 flex: <flex-grow> 1 0
    • 一个 <flex-basis> 的有效值:此时简写会扩展为 flex: 1 1 <flex-basis>
    • 关键字 none 或者全局关键字之一。
  • 双值语法:
    • 第一个值必须是一个 flex-grow 的有效值。例如,缩写为 flex: 1 , 则其计算值为 1 1 0
    • 第二个值必须是以下之一:怎么区分这两个?flex-basis 有单位,如 px,而 flex-shrink 无单位。
      • 一个 flex-shrink 的有效值:此时简写会扩展为 flex: <flex-grow> <flex-shrink> 0
      • 一个 flex-basis 的有效值:此时简写会扩展为 flex: <flex-grow> 1 <flex-basis>
  • 三值语法:值必须按照以下顺序指定
    • 一个 flex-grow 的有效值。
    • 一个 flex-shrink 的有效值。
    • 一个 flex-basis 的有效值。

案例分析

html
<ul class="flex">
  <li>a</li>
  <li>b</li>
  <li>c</li>
</ul>

<style>
  .flex{display:flex;width:800px;margin:0;padding:0;list-style:none;}
  .flex :nth-child(1){flex:1 1 300px;}
  .flex :nth-child(2){flex:2 2 200px;}
  .flex :nth-child(3){flex:3 3 400px;}
</style>

<!--
本例定义了父容器宽(即主轴宽)为800px,由于子元素设置了伸缩基准值flex-basis,相加300+200+400=900,那么子元素将会溢出900-800=100px;
由于同时设置了收缩因子,所以加权综合可得300*1+200*2+400*3=1900px;
于是我们可以计算a,b,c将被移除的溢出量是多少:
a被移除溢出量:(300*1/1900)*100,即约等于16px
b被移除溢出量:(200*2/1900)*100,即约等于21px
c被移除溢出量:(400*3/1900)*100,即约等于63px
最后a,b,c的实际宽度分别为:300-16=284px, 200-21=179px, 400-63=337px
-->

仍然是上面这个例子,不过将容器的宽度改成了 1500px。

html
<ul class="flex">
  <li>a</li>
  <li>b</li>
  <li>c</li>
</ul>

<style>
.flex{display:flex;width:1500px;margin:0;padding:0;list-style:none;}
.flex :nth-child(1){flex:1 1 300px;}
.flex :nth-child(2){flex:2 2 200px;}
.flex :nth-child(3){flex:3 3 400px;}
</style>

<!--
本例定义了父容器宽(即主轴宽)为1500px,由于子元素设置了伸缩基准值flex-basis,相加300+200+400=900,那么容器将有1500-900=600px的剩余宽度;
于是我们可以计算a,b,c将被扩展量是多少:
a的扩展量:(1/(1+2+3))*600,即约等于100px
b的扩展量:(2/(1+2+3))*600,即约等于200px
c的扩展量:(3/(1+2+3))*600,即约等于300px
最后a,b,c的实际宽度分别为:300+100=400px, 200+200=400px, 400+300=700px

从本例能看出:
当「flex-basis」在「flex」属性中不为0时(包括值为auto),此时伸缩基准值等于自身内容宽度;「flex子项」将分配容器的剩余空间(剩余空间即等于容器宽度减去各项的伸缩基准值)
当「flex-basis」在「flex」属性中等于0时,「flex子项」将分配容器的所有空间(因为各项的伸缩基准值相加等于0,剩余空间等于容器宽度减去各项的伸缩基准值,即减0,最后剩余空间值等于容器宽度),所以可以借助此特性,给各子项定义「flex: n」来进行按比例均分容器总宽度
-->

三、网格系统

1. 是什么?

Grid 是一个强大的布局系统,它用于创建二维布局,可以处理行和列。CSS Grid 布局是一个基于网格的布局系统,用于创建复杂的用户界面设计。它是 CSS3 的一个模块,首次在 2017 年被大多数现代浏览器支持。

Grid 布局系统允许定义行和列,并将元素放置在这些定义的网格中。还可以指定元素占用一个或多个网格单元,这使得创建复杂的布局变得更加简单和直观。

2.专业术语

重要概念

  • 网格容器:设置元素为 display: grid 或者 display: inline-grid
  • 网格项:网格容器的直接子元素。
  • 显示网格:通过 grid-template-columnsgrid-template-rows 属性明确定义的网格。在你的代码中,grid-template-columns: 100px 50px 100px;grid-template-rows: 80px auto 80px; 定义了一个显示网格,它有三列和三行。
  • 隐式网格:当网格项目的数量超过了显示网格的单元格数量,或者当一个网格项目被放置在显示网格之外时,网格容器会自动通过添加网格线来生成额外的网格轨道,这些额外的轨道和线条形成了隐式网格。隐式网格的大小可以通过 grid-auto-columnsgrid-auto-rows 属性来设置。

布局模型

  • Grid 线是构成 Grid 结构的“线”,包括行和列的 Grid 线(编号为 1, 2, 3, ...)。
  • Grid 单元格是两条相邻的行 Grid 线和两条相邻的列 Grid 线之间的空间。
  • Grid 轨道是两条相邻 Grid 线之间的空间。
  • Grid 区域是由四条 Grid 线(两条行和两条列的 Grid 线)围成的总空间。

3. 网格容器属性

1)网格轨道

grid-template-rows:定义每一行的高度。例如,grid-template-rows: 50px 50px; 会创建一个两行的 Grid,每行的高度都是 50px。

grid-template-columns:定义每一列的宽度。例如,grid-template-columns: 100px 200px; 会创建一个两列的 Grid,第一列宽度为 100px,第二列宽度为 200px。

grid-template-rows 与 grid-template-columns 除了指定长度,还可以指定以下值:

  • none:不创建显式网格。所有列将被隐式生成,它们的尺寸将由 grid-auto-columns 属性决定。

  • max-content:让网格轨道“和它包含的最宽的元素一样宽”。

  • min-content:让网格轨道“和它包含的最窄的元素一样宽”,但不会导致溢出。

  • auto:由内容决定。

单位

  • 固定宽度:px 等。
  • 百分比:相对于 Grid 容器的大小来计算的。
  • 弹性尺寸 fr(fraction):定义列或行的大小,这个单位表示可用空间的一部分。例如,grid-template-columns: 1fr 2fr; 会创建一个两列的 Grid,第一列宽度为可用空间的 1/3,第二列宽度为可用空间的 2/3。
  • repeat 函数。
  • 尺寸关键字。
  • 尺寸函数。

案例

css
.container {
  grid-template-columns: 40px 50px auto 50px 40px;
  /* e.g. 
    1fr 1fr
    minmax(10px, 1fr) 3fr
    repeat(5, 1fr)
    repeat(auto-fill, 1fr)
    50px auto 100px 1fr
  */
  grid-template-rows: 25% 100px auto;
  /* e.g.
    min-content 1fr min-content
    100px 1fr max-content
  */
}

当将一个元素设置为 CSS 网格(grid)时,可以使用正数和负数的索引来引用网格线。正数索引从 1 开始,从左到右(对于列)或从上到下(对于行)递增。负数索引从 -1 开始,从右到左(对于列)或从下到上(对于行)递增。

还可以显式命名这些行与列名。

css
.container {
  grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
  grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
}

请注意,一行可以有多个名称。例如,这里的第二行将有两个名称:row1-end 和 row2-start。

css
.container {
  grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];
}

如果出现相同的名称怎么办?

css
.container {
  /*
    grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start];
  */
  grid-template-columns: repeat(3, 20px [col-start]);
}

如果多行共享相同的名称,则可以通过其行名和计数来引用它们。

css
.item {
  grid-column-start: col-start 2;
}
2)grid-template-areas

允许通过一个 ASCII 符号来定义网格布局。

这个属性的值是一个或多个字符串,每个字符串代表一行,每个字符串中的每个单词代表一个网格区域。同一个单词在多个字符串中重复出现,表示这个网格区域跨越了多行或多列。可取值:

  • <grid-area-name>:这是用 grid-area 指定的网格区域的名称。
  • .:一个句号表示一个空的网格单元格。
  • none:表示没有定义任何网格区域。

案例

css
.container {
  display: grid;
  grid-template-columns: 50px 50px 50px 50px;
  grid-template-rows: auto;
  grid-template-areas:
    "header header header header"
    "main main . sidebar"
    "footer footer footer footer";
}

.item-a {
  grid-area: header;
}
.item-b {
  grid-area: main;
}
.item-c {
  grid-area: sidebar;
}
.item-d {
  grid-area: footer;
}

注意:在这个语法中并没有命名线,只是命名了区域。当使用这个语法时,区域两端的线实际上会自动获得命名。如果网格区域的名称是 foo,那么区域的起始行线和起始列线的名称将是 foo-start,它的最后一行线和最后一列线的名称将是 foo-end。这意味着一些线可能会有多个名称,比如上面例子中最左边的线,它将有三个名称:header-start、main-start 和 footer-start。因为它是 header、main 和 footer 这三个区域的起始列线。

3)grid-template [了解]

grid-template-rowsgrid-template-columnsgrid-template-areas 的简写属性。

简单语法

css
grid-template: none | <grid-template-rows> / <grid-template-columns>;
  • none:将这三个属性都设置为它们的初始值。
  • <grid-template-rows> / <grid-template-columns>:分别将 grid-template-rowsgrid-template-columns 设置为指定的值,并将 grid-template-areas 设置为 none。

复杂语法

还接受一个更复杂但非常方便的语法来指定所有三个属性。这里有一个例子:

css
.container {
  grid-template:
    [row1-start] "header header header" 25px [row1-end]
    [row2-start] "footer footer footer" 25px [row2-end]
    / auto 50px auto;
}

这等同于:

css
.container {
  grid-template-rows: [row1-start] 25px [row1-end row2-start] 25px [row2-end];
  grid-template-columns: auto 50px auto;
  grid-template-areas:
    "header header header"
    "footer footer footer";
}

由于 grid-template 不会重置隐式网格属性(grid-auto-columnsgrid-auto-rowsgrid-auto-flow),在大多数情况下,可能希望重置这些属性,所以建议使用 grid 属性而不是 grid-template

4)row-gap / column-gap

设置 Grid 行之间的间隙。这个间隙是透明的,不能放置 Grid 项目。

旧语法:grid-row-gap / grid-column-gap。

为什么要去掉 graid 关键字?因为这个属性也可以在 flex 布局中使用。

5)gap

"row-gap" 和 "column-gap" 的简写形式。

css
gap: <row-gap> <column-gap>;

旧语法:grid-gap。

6)justify-items

控制 Grid 容器中的项目在水平线(行轴)上的对齐方式。

接受以下值:

  • start:项目与所在列的起始边对齐。
  • end:项目与所在列的结束边对齐。
  • center:项目在所在列中居中。
  • stretch(默认值):如果项目的宽度未被指定,或者指定为 auto,那么项目将拉伸以填满整个列。
7)align-items

控制 Grid 容器中的项目在垂直线(列轴)上的对齐方式。

接受以下值:

  • start:项目与所在行的起始边对齐。
  • end:项目与所在行的结束边对齐。
  • center:项目在所在行中居中。
  • stretch(默认值):如果项目的高度未被指定,或者指定为 auto,那么项目将拉伸以填满整个行。
8)justify-content

控制整个 Grid(包括所有项目)在其容器内的水平对齐方式。这个属性只有在 Grid 的总宽度小于其容器的宽度时才会生效。

接受以下值:

  • start:Grid 与容器的左边对齐。
  • end:Grid 与容器的右边对齐。
  • center:Grid 在容器中居中。
  • stretch(默认值):拉伸。
  • space-around:每个 Grid 项目的两侧都有相等的空间,这意味着项目之间的空间是项目与容器边缘空间的两倍。
  • space-between:项目之间有相等的空间,第一个项目与容器的左边对齐,最后一个项目与容器的右边对齐。
  • space-evenly:项目之间和项目与容器边缘之间都有相等的空间。
9)align-content

控制整个 Grid(包括所有项目)在其容器内的垂直对齐方式。这个属性只有在 Grid 的总高度小于其容器的高度时才会生效。

接受以下值:

  • start:Grid 与容器的顶部对齐。
  • end:Grid 与容器的底部对齐。
  • center:Grid 在容器中居中。
  • stretch(默认值):拉伸。
  • space-around:每个 Grid 项目的上下都有相等的空间,这意味着项目之间的空间是项目与容器边缘空间的两倍。
  • space-between:项目之间有相等的空间,第一个项目与容器的顶部对齐,最后一个项目与容器的底部对齐。
  • space-evenly:项目之间和项目与容器边缘之间都有相等的空间。
10)place-items

"align-items" 和 "justify-items" 的简写形式。

css
place-items: <align-items> / <justify-items>;
11)place-content

"align-content" 和 "justify-content" 的简写形式。

css
place-content: <align-content> / <justify-content>;
12)grid-auto-columns / grid-auto-rows

指定任何自动生成的网格轨道(也称为隐式网格轨道)的大小。当网格项多于网格中的单元格,或者当一个网格项被放置在显式网格之外时,会创建隐式轨道。

css
/*
  grid-auto-columns: 设置隐式列轨道的大小。
  grid-auto-rows: 设置隐式行轨道的大小。
  track-size: 长度,百分比,或者网格中剩余空间的一部分(使用 fr 单位)
*/
grid-auto-columns: <track-size> ...;
grid-auto-rows: <track-size> ...;

为了说明隐式网格轨道是如何创建的,想象一下这样的情况:创建了一个 2 x 2 的网格。

css
.container {
  grid-template-columns: 60px 60px;
  grid-template-rows: 90px 90px;
}

但现在假设你使用 grid-columngrid-row 来定位你的网格项,像这样:

css
.item-a {
  grid-column: 1 / 2;
  grid-row: 2 / 3;
}
.item-b {
  grid-column: 5 / 6;
  grid-row: 2 / 3;
}

我们告诉 .item-b 从列线 5 开始,到列线 6 结束,但我们从未定义过列线 5 或 6。因为我们引用了不存在的线,所以会创建宽度为 0 的隐式轨道来填补空白。我们可以使用 grid-auto-columnsgrid-auto-rows 来指定这些隐式轨道的宽度:

css
.container {
  grid-auto-columns: 60px;
}

注意:这两个属性只影响隐式轨道,不影响 grid-template-columnsgrid-template-rows 定义的显式轨道。

13)grid-auto-flow

控制网格布局中未明确放置的网格项的自动放置算法(流动机制)。取值:

  • row(默认):告诉自动放置算法按顺序填充每一行,并在必要时添加新的行。
  • column:告诉自动放置算法按顺序填充每一列,并在必要时添加新的列。
  • dense:告诉自动放置算法如果后来有更小的项目,尝试在网格的早期位置填充空洞。
css
grid-auto-flow: row | column | row dense | column dense;

考虑以下 HTML:

html
<section class="container">
  <div class="item-a">item-a</div>
  <div class="item-b">item-b</div>
  <div class="item-c">item-c</div>
  <div class="item-d">item-d</div>
  <div class="item-e">item-e</div>
</section>

定义了一个有五列两行的网格,并将 grid-auto-flow 设置为 row(这也是默认值):

css
.container {
  display: grid;
  grid-template-columns: 60px 60px 60px 60px 60px;
  grid-template-rows: 30px 30px;
  grid-auto-flow: row;
}

将项目放置在网格上时,仅指定其中两个项目的位置:

css
.item-a {
  grid-column: 1;
  grid-row: 1 / 3;
}
.item-e {
  grid-column: 5;
  grid-row: 1 / 3;
}

因为我们将 grid-auto-flow 设置为 row。我们的网格将如下所示。注意我们没有放置的三个项目(item-b、item-c 和 item-d)是如何沿着可用的行流动的:

如果我们将 grid-auto-flow 设置为 column。item-b、item-c 和 item-d 将沿着列向下流动:

14)grid [了解]

用于一次性设置以下所有的子属性:grid-template-rowsgrid-template-columnsgrid-template-areasgrid-auto-rowsgrid-auto-columnsgrid-auto-flow

注意:在单个 grid 声明中,你只能指定显式网格属性或隐式网格属性。

取值:

  • none:将所有子属性设置为其初始值。
  • <grid-template>:与 grid-template 的简写方式相同。
  • <grid-template-rows> / [ auto-flow && dense? ] <grid-auto-columns>?:将 grid-template-rows 设置为指定的值。如果 auto-flow 关键字在斜杠的右边,它将 grid-auto-flow 设置为 column。如果还指定了 dense 关键字,自动放置算法将使用“密集”打包算法。如果省略了 grid-auto-columns,它将被设置为 auto。
  • [ auto-flow && dense? ] <grid-auto-rows>? / <grid-template-columns>:将 grid-template-columns 设置为指定的值。如果 auto-flow 关键字在斜杠的左边,它将 grid-auto-flow 设置为 row。如果还指定了 dense 关键字,自动放置算法将使用“密集”打包算法。如果省略了 grid-auto-rows,它将被设置为 auto。

具体书写格式参照 MDN:grid 属性

以下两个代码块都是等价的。

它还接受一个更复杂但非常方便的语法,一次性设置所有内容。你指定 grid-template-areasgrid-template-rowsgrid-template-columns,所有其他子属性都设置为其初始值。

css
.container {
  grid: [row1-start] "header header header" 1fr [row1-end]
        [row2-start] "footer footer footer" 25px [row2-end]
        / auto 50px auto;
}

这等价于:

css
.container {
  grid-template-areas:
    "header header header"
    "footer footer footer";
  grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end];
  grid-template-columns: auto 50px auto;    
}

4. 网格项属性

1)grid-column-start

指定网格项目在网格中的位置。

  • auto:自动放置项目(默认)。
  • <lineName>:从名为 <lineName> 的行线开始放置项目。
  • <number><lineName> <number>:例如 3 或 my-line 3。从第 <number> 行线开始放置项目(如果 <number> 是负数,则从后往前数)。如果指定了 <lineName>,那么只计数带有该名称的行线。
  • span <number>span <lineName> <number>(一般只在 grid-*-end 属性中使用):例如 span 3span my-line 3。将项目的行结束线放置在距离行开始线 <number> 行线的位置。如果指定了 <lineName>,那么只计数带有该名称的行线。
2)grid-column-end
3)grid-row-start
4)grid-row-end
5)grid-row

"grid-row-start" 和 "grid-row-end" 的简写形式。

css
grid-row: <grid-row-start> / <grid-row-end>;
6)grid-column
css
grid-column: <grid-column-start> / <grid-column-end>;
7)grid-area

指定网格项目在网格中的位置。用于以下两种情况:

  • 作为 grid-row-startgrid-column-startgrid-row-endgrid-column-end 四个属性的简写形式。例如,grid-area: 1 / 2 / 3 / 4; 相当于 grid-row-start: 1; grid-column-start: 2; grid-row-end: 3; grid-column-end: 4;
  • 引用通过 grid-template-areas 属性定义的网格区域的名称。例如,如果你在网格容器中定义了 grid-template-areas: "header header header" "main main .",那么你可以在网格项目中使用 grid-area: header;grid-area: main; 来指定项目应该放置在哪个区域。
8)justify-self

控制网格项目在其所在网格区域的水平线(行轴)上的对齐方式。

它的可能值包括:

  • start:使项目对齐到网格区域的开始边缘。
  • end:使项目对齐到网格区域的结束边缘。
  • center:使项目在网格区域中居中。
  • stretch(默认值):使项目填满整个网格区域。
9)align-self

控制网格项目在其所在网格区域的垂直线(列轴)上的对齐方式。

它的可能值包括:

  • start:使项目对齐到网格区域的开始边缘。
  • end:使项目对齐到网格区域的结束边缘。
  • center:使项目在网格区域中居中。
  • stretch(默认值):使项目填满整个网格区域。
10)place-self

align-selfjustify-self 这两个属性的简写形式。

css
place-self: <align-self> <justify-self>;

只提供一个值,那么这个值会同时应用到 align-selfjustify-self

5. 特殊单位 & 函数

1)fr

fr:表示“剩余空间的一部分”。

2)尺寸关键字

在设置行和列的大小时,可以使用所有长度,如 px、rem、% 等,但也还有:

  • min-content:内容的最小大小。想象一行文本,如 "E pluribus unum",min-content 可能是 "pluribus" 这个词的宽度。

  • max-content:内容的最大大小。上面的句子,max-content 是整个句子的长度。

  • auto:这个关键字很像 fr 单位,除了在分配剩余空间时,它们在大小上“输给” fr 单位。

    auto 轨道会根据其内容自动调整尺寸,而 fr 单位则分配剩余的可用空间。

    在空间分配顺序上,浏览器会先满足 auto 轨道的内容需求,然后才将剩余空间分配给 fr 轨道。如果内容需要更多空间,fr 轨道可能会被压缩以确保内容正常显示。

    例如,在一个 500px 宽的网格中设置 '1fr auto',如果 auto 列的内容需要 200px,那么 auto 列会获得 200px,剩余的 300px 会分配给 1fr 列。

3)尺寸函数
  • fit-content(length) 函数使用可用的空间,但永远不会小于 min-content,也不会大于 max-content

    css
    min(max-content, max(min-content, length))
  • minmax() 设置了轨道尺寸的最小值和最大值。例如:grid-template-columns: minmax(100px, 1fr) 3fr

    特殊值:

    • max-content:内容在不换行情况下的理想宽度(自然宽度)

    • min-content:内容可能的最小宽度,通常由最长单词或不可断行内容决定

    • auto:作为 max 值时类似于 max-content;作为 min 值时,考虑内容 min-content 尺寸和元素 min-width/min-height 约束。

  • min()

  • max()

4)repeat() 与关键字

repeat(count, trackSizes):可以为 trackSizes 指定多个长度。

  • 对于 count,可以指定一个数字,也可以指定以下特殊值:

    • auto-fill:自动计算可以放入容器的最大轨道数,保留所有轨道,包括空轨道。
    • auto-fit:与 auto-fill 创建相同数量的轨道,但会折叠空轨道,让有内容的轨道扩展填充空间。
  • 对于 trackSizes,可以指定一个长度,也可以指定以下特殊值:

    • minmax()
    • max-content:让网格轨道“和它包含的最宽的元素一样宽”。
    • min-content:让网格轨道“和它包含的最窄的元素一样宽”,但不会导致溢出。
    • auto:由内容决定。

案例

css
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;

/* 更简单的写法: */
grid-template-columns: repeat(8, 1fr);

/* 尤其是当: */
grid-template-columns: repeat(8, minmax(10px, 1fr));

但是当 repeat() 与关键字结合使用时,可以变得更加高级:

  • auto-fill:在一行上尽可能多地放置列,即使它们是空的。
  • auto-fit:将所有列适应到空间中。优先扩展列以填充空间,而不是空列。

auto-fill 与 auto-fit 区别?

css
.container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}

如果容器的宽度是 330px,那么浏览器会创建四列,三列宽度为 100px,最后一列是空的,宽度为 30px。

但是,如果你将 auto-fill 更改为 auto-fit

css
.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}

在这种情况下,浏览器仍然会创建三列,但是每列的宽度会增加到 110px,以填充整个容器的宽度,而不是创建一个新的空列。

这引出了 CSS Grid 中最著名的代码片段,也是所有 CSS 技巧中最伟大的之一:

css
/*
  这个网格会创建尽可能多的列,每列的宽度至少为 250px,但如果有额外的空间,列的宽度可以增加。
  如果某些列没有内容,它们将会消失,剩下的列会扩大以填充剩余的空间。
*/
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));

四、多列布局

设置给包裹元素(容器)的 CSS 属性

CSS 属性名含义
column-count列数数字
column-width列宽长度
ps: 宽度不一定是设置的值,他会容器宽度先减去 column-gap,然后剩下的用于列宽
columns同时设置列数和列宽空格分隔两个值
ps: 最后谁计算的列数小就取谁。
column-gap列间距长度
column-rule-style列分隔线风格同 border-style
column-rule-color列分隔线颜色颜色
column-rule-width列分隔线宽度长度
column-rule列分隔线复合属性空格分隔两个值

设置给子元素的 CSS 属性

CSS 属性名含义
column-span跨列none: 不跨列,默认值。
all: 跨所有列。
-webkit-column-break-before (了解)设置元素前面是否断列(另起一列)auto: 自动,默认值。
always: 必须断列。
avoid: 必须不断列。
-webkit-column-break-after (了解)设置元素后面是否断列auto: 自动,默认值。
always: 必须断列。
avoid: 必须不断列。
-webkit-column-break-inside (了解)设置元素内部是否断列auto: 自动,默认值。
avoid: 必须不断列。

第八章:视觉特效

⚠️ 行内标签设置变换没有效果。

一、2D 转换

转换(transform)是 CSS3 中具有颠覆性的特征之一,可以实现元素的位移、旋转、缩放等效果。

  • 移动:translate
  • 旋转:rotate
  • 缩放:scale

转换(transform)可以简单理解为变形。

二 维坐标系

1. 转换之移动 translate

选项说明
translate(x,y)定义 2D 转换。
translateX(x)定义转换,只是用 X 轴的值。
translateY(y)定义转换,只是用 Y 轴的值。

注意:

  • translate 最大的优点是不会影响到其他元素的位置。

  • translate 与转换中心点 transform-origin 无关。

  • translate:(50%,50%); 中的百分比单位是相对于自身元素的。因此,利用这个可以让绝对定位元素在父元素里水平垂直居中。

    css
    .parent {
      position: relative;
    }
    
    .child {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }

2. 转换之旋转 rotate

选项说明
rotate(angle)定义 2D 旋转,在参数中规定角度。

注意:

  • rotate 里面是度数,单位 deg。比如 rotate(45deg);
  • 角度为正时顺时针,负时为逆时针。
  • 默认旋转的中心点是元素的中心点。

转换中心点 transform-origin

css
transform-origin: x y;

注意:

  • 后面的参数 x 和 y 用空格隔开。

  • x y 默认转换的中心点是元素的中心点。

  • 还可以给 x y 设置像素或者方位名词(top bottom left right center)。

3. 转换之缩放 scale

sacle 缩放最大的优势:可以设置转换中心点缩放,默认以中心点缩放的,而且不影响其他盒子。

选项说明
scaleX(x)x 方向缩放。
scaleY(y)y 方向缩放。
scale(x,y)定义 2D 缩放转换。

例子:

  • transform:scale(1,1) :宽和高都放大一倍,相当于没有放大。

  • transform:scale(2,2) :宽和高都放大了 2 倍。

  • transform:scale(2) :只写一个参数,第二个参数则和第一个参数 一样,相当于 scale(2,2)

  • transform:scale(0.5,0.5) :缩小。

注意:
缩放是把元素整体缩放,不单单是里面的文字。
缩放也是与转换中心点 transform-origin 有关。

4. 倾斜

函数解释
skewX(angle)定义沿着 X 轴的 2D 倾斜转换。
skewY(angle)定义沿着 Y 轴的 2D 倾斜转换。
skew(x-angle,y-angle)定义沿着 X 和 Y 轴的 2D 倾斜转换。

例子:

  • transform:skew(10deg) :仅沿着 x 轴倾斜。

5. 综合写法

同时使用多个转换,其格式为:transform: translate() rotate() scale() …… 等。

其顺序会影转换的效果。所以谨记【先旋转会改变坐标轴方向,当我们同时有位移和其他属性的时候,记得要将位移放到最前】。

二、3D 转换

> 总结 > > 需要设置给变换元素本身:transform、transform-origin、backface-visibility > > 需要设置给变换元素的父元素:transform-style、perspective、perspetive-origin > > 变换原点如果只设置一个值,另一个值默认为 center。

1. 3D 移动

选项说明
translateZ(z)定义 3D 转换,只是用 Z 轴的值。
translate3d(x,y,z)定义 3D 转换。

translform:translateZ(100px):仅仅是在 Z 轴上移动。

  • translateZ 的正值表示元素在 3D 空间中向观察者(屏幕前方)移动,也就是“往外”移动。
  • translateZ 的负值表示元素在 3D 空间中向远离观察者(屏幕后方)移动,也就是“往里”移动。

备注:有了透视,才能看到 translateZ 引起的变化。

2. 3D 特定属性

透视 perspective

在 2D 平面产生近大远小视觉立体,但效果是二维的。如果想要在网页产生 3D 效果需要透视。

景深是指定观察者与「z=0」平面(屏幕)的距离,使具有三维位置变换的元素产生透视(理解成 3D 物体投影在 2D 平面内)效果。

模拟人类的视觉位置,可认为安排一只眼睛去看。透视我们为视距:视距就是人的眼睛到屏幕的距离。距离视觉点越近的在电脑平面成像越大,越远成像越小。透视的单位是像素。

简单来说就是在平面描绘物体的空间关系的方法。

注意:透视写在被观察元素的父盒子上面的。

d:就是视距,视距就是一个 距离人的眼睛到屏幕的距离。

z:就是 z 轴,物体距离屏幕的距离,z 轴越大(正值)我们看到的物体就越大。

perspective-origin 设置透视点的位置

用法:

如果提供两个参数,第一个用于横坐标,第二个用于纵坐标。 如果只提供一个参数,该值将用于横坐标;纵坐标将默认为 center。

取值:

left right center 或者 <lenght> <percentage>

top bottom center 或者 <lenght> <percentage>

指定元素背面面向用户时是否可见

取值:

visible: (默认) 指定元素背面可见。 hidden:指定元素背面不可见

注意:

决定一个元素背面面向用户时是否可见,需要直接在该元素上定义 backface-visibility 属性,而不能在其父元素上,因为该属性默认为不可继承。

3. 3D 旋转

3D 旋转指可以让元素在三维平面内沿着 x 轴、y 轴、z 轴或者自定义轴进行旋转。

  • transform:rotateX(45deg):沿着 x 轴正方向旋转 45 度。

  • transform:rotateY(45deg):沿着 y 轴正方向旋转 45deg。

  • transform:rotateZ(45deg):沿着 Z 轴正方向旋转 45deg。

  • transform:rotate3d(x,y,z,deg):沿着自定义轴旋转 deg 为角度。

    前三个参数分别是是否沿着 x y z 轴旋转,取值 0 和 1。

x、y、z 轴的正方向是什么?

左手准则:左手的手拇指指向 x / y / z 轴的正方向。其余手指的弯曲方向就是该元素沿着 x / y / z 轴旋转的方向。

4. 3D 缩放

选项说明
scaleZ(z)z 轴方向缩放
scale3Z(x, y, z)必须三个值

受限于屏幕的屏幕,3D 缩放目前没有任何效果。

5. 3D 呈现

控制子元素是否开启三维立体环境。

transform-style: flat; 子元素不开启 3d 立体空间(默认的)。

transform-style: preserve-3d; 子元素开启立体空间。

代码写给父级,但是影响的是子盒子。这个属性很重要,后面必用。

三、动画

动画(animation)是 CSS3 中具有颠覆性的特征之一,可通过设置多个节点(关键帧【keyframes】)来精确控制一个或一组动画,常用来实现复杂的动画效果。

相比较过渡,动画可以实现更多变化,更多控制,连续自动播放等效果。动画是使元素从一种样式逐渐变化为另一种样式的效果。可以改变任意多的样式、任意多的次数。

备注:在 JS 中,可以监听元素的 transitionstart 和 transitionend 事件,从而在过渡开始和过渡结束时做一些别的事情。

1. 快速入门

1)用 keyframes 定义动画

在 keyframes 中规定某项 CSS 样式,就能创建由当前样式逐渐改为新样式的动画效果。

css
/* 如果动画 0% 样式与本来的样式一致,可以省略 0% 样式 */
@keyframes 动画名称 {
  0% {
    width:100px;
  }
  100% {
    width:200px;
  }
}

0% 是动画的开始;100% 是动画的完成。这样的规则就是动画序列。

可以用百分比来规定变化发生的时间,或用关键词 from 和 to,等同于 0% 和 100%。

2)元素使用动画

css
/* 调用动画 */
animation-name: 动画名称;
/* 持续时间 */
animation-duration: 持续时间;

2. 常用属性

属性属性值描述
@keyframes规定动画。
animation所有动画属性的简写属性,除了animation-play-state 属性。
animation-name关键字名字,多个使用逗号分隔规定 keyframes 动画的名称。(必须的)
animation-duration时间单位:s、ms规定动画完成一个周期所花费的秒或毫秒,默认是 0。(必须的)
animation-timing-function曲线运动、分步运动规定动画的速度曲线,默认是 'ease'。
animation-delay时间单位:s、ms规定动画何时开始,默认是 0。
animation-iteration-count数字、infinite 表示无限次规定动画被播放的次数,默认是 1,还有 infinite。
animation-directionnormal:默认值。
reverse:反向。
alternate:交替运动。
alternate-reverse:反向交替。
规定动画是否在下一周期逆向播放。
animation-play-staterunning:正在运动。
paused:暂停运动
规定动画是否正在运行或暂停。默认是 'running'。
animation-fill-modenone:默认值。
forwards:结束后处于结束帧样式。
backwards:开始前处于起始帧样式。
both:同时设置 forwards 和 backwards。
规定动画结束后状态,保持 forwards;回到起始 backwards。

速度曲线细节

animation-timing-function 规定动画的速度曲线,默认是 "ease"。

取值描述
linear动画从头到尾的速度是相同的。匀速
ease默认。动画以低速开始,然后加快,在结束前变慢。
ease-in动画以低速开始。
ease-out动画以低速结束。
ease-in-out动画以低速开始和结束。
steps()指定了时间函数中的间隔数量(步长)

简写

css
animation: 动画名称 持续时间 运动曲线 何时开始 播放次数 是否反方向 动画起始或者结束的状态;
          动画名称 持续时间 运动曲线 何时开始 播放次数 是否反方向 动画起始或者结束的状态;

注意:

简写属性里面不包含 animation-play-state。

暂停动画:animation-play-state: puased; 经常和鼠标经过等其他配合使用。

想要动画走回来,而不是直接跳回来:animation-direction: alternate。

盒子动画结束后,停在结束位置:animation-fill-mode: forwards。

四、过渡延迟

不是所有 css 属性都支持中间值的属性(有过渡效果)。查看可动画处理的 CSS 属性

常见的可以被过渡的属性:颜色属性、具有长度值、百分比的属性、值是数字的属性(如 z-index opacity outline-offset 等)、变形系列属性、阴影、渐变。

谁做过渡给谁加。

1. transition-property

设置对象中参与过渡的属性。

  • none:不指定过渡的 css 属性。
  • all:所有可以进行过渡的 css 属性(默认值)。
  • IDENT:指定要进行过渡的 css 属性,如果提供多个属性值,以逗号进行分隔。

2. transition-duration

设置对象过渡的持续时间,如果提供多个属性值,以逗号进行分隔。

3. transition-timing-function

设置对象中过渡的动画类型。

取值:

  • ease:平滑过渡。等同于贝塞尔曲线 (0.25, 0.1, 0.25, 1.0)

  • linear:线性过渡。等同于贝塞尔曲线 (0.0, 0.0, 1.0, 1.0)

  • ease-in:由慢到快。等同于贝塞尔曲线 (0.42, 0, 1.0, 1.0)

  • ease-out:由快到慢。等同于贝塞尔曲线 (0, 0, 0.58, 1.0)

  • ease-in-out:由慢到快再到慢。等同于贝塞尔曲线 (0.42, 0, 0.58, 1.0)

  • cubic-bezier(number, number, number, number):特定的贝塞尔曲线类型,4 个数值需在 [0, 1] 区间内。

    在线制作贝塞尔曲线:https://cubic-bezier.com

  • step-start:等同于 steps(1, start) 。表示动画被分割成 1 步,动画在每个步骤的开始就立即跳到下一个状态。

  • step-end:等同于 steps(1, end) 。表示动画被分割成 1 步,动画在每个步骤的结束时才跳到下一个状态。

  • steps(integer [, [ start | end ] ]?):接受两个参数的步进函数。第一个参数必须为正整数,指定函数的步数。第二个参数取值可以是 start 或 end,指定每一步的值发生变化的时间点。第二个参数是可选的,默认值为 end。

4. transition-delay

设置对象延迟过渡的时间。

简写

transition 检索或设置对象变换时的过渡。是一个复合属性。

css
transition: property1 duration1 timing-function1 delay1,
            property2 duration2 timing-function2 delay2;

顺序要求:transition: transition-duration [transition-delay]。其他无要求。

五、其他

1. 渐变

1)线性渐变

语法

css
linear-gradient(方向/角度, color1, color2......);

取值

<方向/角度>:用角度值或关键字指定渐变的方向。
    to left: 设置渐变为从右到左。相当于 270deg。
    to right:设置渐变从左到右。相当于 90deg。
    to top:  设置渐变从下到上。相当于 0deg。
    to bottom: 设置渐变从上到下。相当于 180deg。这是默认值,等同于留空不写。

<color>:用于指定渐变的起止颜色。
    <color>:  指定颜色。
    <length>: 用长度值指定起止色位置。不允许负值。
    <percentage>: 用百分比指定起止色位置。

示例

css
background-image: linear-gradient(#fff, #333); /* 从上到下 */

background-image: linear-gradient(to bottom, #fff, #333); /* 从上到下 */
background-image: linear-gradient(to top, #333, #fff); /* 从下到上 */
background-image: linear-gradient(to right bottom, #FF0000, #FFF200, #1E9600); /* 从左上到右下 */

background-image: linear-gradient(45deg, #FF0000, #FFF200, #1E9600); /* 从起点从225度到45度结束的渐变 */
background-image: linear-gradient(180deg, #fff, #333); /* 从上到下 */

设置位置参数。

css
background-image: linear-gradient(#69f 20%, #fd44ff);
background-image: linear-gradient(#69f 50%, #fd44ff);
background-image: linear-gradient(#69f 20%, #fd44ff 80%);
background-image: linear-gradient(#69f 50%, #fd44ff 50%);

还可以配置多种颜色,及颜色都配置起止值。例如:

css
/* 0-25%,25%-50%,50%-75%,75%-100% */
background-image: linear-gradient(#69f 25%,#fd44ff 50%,#f64f59 75%, #fbd786);
/* 0-25%,25%-50%,50%-75%,75%-100% */
background-image: linear-gradient(#69f 25%,#fd44ff 25% 50%,#f64f59 50% 75%, #fbd786 75%);
2)径向渐变

了解即可。

语法

css
radial-gradient(shape size at position, color1, color2......);

取值

<shape> 确定圆的类型
    circle:指定圆形的径向渐变。
    ellipse (默认):指定椭圆形的径向渐变。

<size>
    closest-side:指定径向渐变的半径长度为从圆心到离圆心最近的边。
    closest-corner:指定径向渐变的半径长度为从圆心到离圆心最近的角。
    farthest-side:指定径向渐变的半径长度为从圆心到离圆心最远的边。
    farthest-corner:指定径向渐变的半径长度为从圆心到离圆心最远的角 (默认值)。

<circle-size> circle 接受该值作为 size
    <length>:用长度值指定正圆径向渐变的半径长度。不允许负值。一个参数则为圆形。

<ellipse-size> ellipse 接受该值作为 size
    <length>:用长度值指定椭圆径向渐变的横向或纵向半径长度。不允许负值。两个参数(参数值不相同)则为椭圆。
    <percentage>:用百分比指定椭圆径向渐变的横向或纵向半径长度。不允许负值。

<position> 确定圆心的位置。如果提供2个参数,第一个表示横坐标,第二个表示纵坐标;如果只提供一个,第二值默认为50%,即center
    <percentage>:用百分比指定径向渐变圆心的横坐标值。可以为负值。
    <length>:用长度值指定径向渐变圆心的横坐标值。可以为负值。
    left:设置左边为径向渐变圆心的横坐标值。
    center:设置中间为径向渐变圆心的横坐标值。
    right:设置右边为径向渐变圆心的横坐标值。
    <percentage>:用百分比指定径向渐变圆心的纵坐标值。可以为负值。
    <length>:用长度值指定径向渐变圆心的纵坐标值。可以为负值。
    top:设置顶部为径向渐变圆心的纵坐标值。
    center:设置中间为径向渐变圆心的纵坐标值。
    bottom:设置底部为径向渐变圆心的纵坐标值。

<color> 用于指定渐变的起止颜色:
    <color>:指定颜色。
    <length>:用长度值指定起止色位置。不允许负值
    <percentage>:用百分比指定起止色位置。不允许负值

示例

css
radial-gradient(circle, #f00, #ff0, #080);
radial-gradient(circle at center, #f00, #ff0, #080);
radial-gradient(circle at 50%, #f00, #ff0, #080);
radial-gradient(circle farthest-corner, #f00, #ff0, #080);
3)重复渐变
  • repeating-linear-gradient():重复线性渐变。参数同 linear-gradient()
  • repeating-radial-gradient:重复径向渐变。参数同 radial-gradient()

2. 滤镜

1)filter
css
filter: 滤镜函数(参数);
滤镜函数描述
blur()设置模糊度,值是 radius。值越大越模糊,百分比无效。
brightness()设置亮度,值是数字或者百分比,0 全黑,1 无效果,可以比 1 大,默认 1。
saturate()设置饱和度,值是数字或者百分比,0 完全不包含,1 无效果,可以比1大,默认 1。
contrast()设置对比度,值是 0~1 之间的数字或者百分比,0 全灰,1 无效果,可以比 1 大,默认 1。
grayscale()设置灰度,使用 0~1 之间的数字或百分比,值越大灰度越高,0 无效果,1 灰度最高,默认 0。
sepia()设置深褐色度,使用 0~1 之间的数字或百分比,值越大深褐色度越高,0 无效果,1 灰度最高,默认 0。
hue-rotate()设置色相旋转,值是 0~360deg 之间的角度。
invert()设置反转,使用 0~1 之间的数字或百分比,0 无效果,1 彻底反转,默认 0。
opacity()设置不透明度,使用 0~1 之间的数字或百分比,0 完全不透明,1 彻底透明,默认 0。
drop-shadow()设置阴影,需要设置偏移位置、模糊值、颜色。
url()使用 svg 设置滤镜。
2)backdrop-filter
css
/*
  允许你为一个元素背后的区域添加 XXX 效果。
  blur(10px) 是一个模糊滤镜,它会使元素后面的内容产生模糊效果。
*/
backdrop-filter: blur(10px);

backdrop-filter 常见的应用场景:在一张图片上面有个遮罩层,给遮罩层使用 rgba 设置半透明效果,且还想给这个遮罩层下面的元素添加 filter 效果,那么就可以给遮罩层应用 backdrop-filter 属性。

第九章:移动端开发

一、基本概念

1. meta 标签

1)视口

视口(viewport)就是浏览器显示页面内容的屏幕区域。 视口可以分为布局视口、视觉视口和理想视口。

布局视口 layout viewport

一般移动设备的浏览器都默认设置了一个布局视口,用于解决早期的 PC 端页面在手机上显示的问题。iOS, Android 基本都将这个视口分辨率设置为 980px,所以 PC 上的网页大多都能在手机上呈现,只不过元素看上去很小,一般默认可以通过手动缩放网页。

视觉视口 visual viewport

它是用户正在看到的网站的区域。我们可以通过缩放去操作视觉视口,但不会影响布局视口,布局视口仍保持原来的宽度。

理想视口 ideal viewport

为了使网站在移动端有最理想的浏览和阅读宽度而设定理想视口。对设备来讲,是最理想的视口尺寸。

meta 视口标签的主要目的:布局视口的宽度应该与理想视口的宽度一致,简单理解就是设备有多宽,我们布局的视口就多宽。

2)网页设置完美视口
html
<meta name="viewport"
      content="width=device-width, user-scalable=no,
               initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

meta 视口标签的 content 属性可以包含以下几种设置:

  • width:控制视口的宽度。常见的值有 device-width(设备的宽度)和具体的像素值。
  • user-scalable:设置用户是否可以缩放页面。常见的值有 yes(可以缩放)和 no(不能缩放)。
  • initial-scale:设置页面首次加载时的缩放级别。常见的值是 1,表示不缩放。
  • maximum-scale:设置页面可以被缩放的最大程度。
  • minimum-scale:设置页面可以被缩放的最小程度。

2. 像素

1)屏幕

移动设备与 PC 设备最大的差异在于屏幕,这主要体现在屏幕尺寸和屏幕分辨率两个方面。

通常我们所指的屏幕尺寸,实际上指的是屏幕对角线的长度(一般用英寸来度量)。

而分辨率则一般用像素来度量(px),表示屏幕水平方向和垂直方向的像素数,例如 1920*1080 指的是屏幕垂直方向和水平方向分别有 1920 和 1080 个像素点而构成。

2)长度单位

在 Web 开发中可以使用 px(像素)、em、pt(点)、in(英寸)、cm(厘米)作为长度单位,我们最常用 px(像素)作为长度单位。

我们可以将上述的几种长度单位划分成相对长度单位和绝对长度单位。

3)像素密度

DPI(Dots Per Inch)是印刷行业中用来表示打印机每英寸可以喷的墨汁点数,计算机显示设备从打印机中借鉴了 DPI 的概念。由于计算机显示设备中的最小单位不是墨汁点而是像素,所以用 PPI(Pixels Per Inch)值来表示屏幕每英寸的像素数量。我们将 PPI、DPI 都称为像素密度,但 PPI 应用更广泛,DPI 在 Android 设备比较常见。

Retina 即视网膜屏幕,苹果注册的命名方式,意指具有较高 PPI(大于 320)的屏幕。

思考:在屏幕尺寸(英寸)固定时,PPI 和像素大小的关系?

结论:屏幕尺寸固定时,当 PPI 越大,像素的实际大小就会越小;当 PPI 越小,像素实际大小就越大。

4)设备像素比

希望在不同 PPI 的设备上看到的图像内容差不多大小,所以这时我们需要一个新的单位,这个新的单位能够保证图像内容在不同的 PPI 设备看上去大小应该差不多,这就是独立像素。

在 iOS 设备上叫 PT(Point),Android 设备上叫 DIP(Device independent Pixel)或 DP。简单点,通称为设备像素比 (DPR)。

两者之间的关系由设备像素比定义:DPR = 物理像素 / 逻辑像素

  • 普通屏幕:DPR = 1(1 个 CSS 像素 = 1 个物理像素)
  • Retina 屏幕:DPR = 2(1 个 CSS 像素 = 2×2 物理像素)
  • 超高清屏:DPR = 3(1 个 CSS 像素 = 3×3 物理像素)

可以通过 window.devicePixelRatio 获取到当前屏幕上的 DPR 值。计算方法是物理像素数量 ÷ CSS像素数量。

javascript
window.devicePixelRatio; // 返回 2, 表示 1 个 CSS 像素 = 2 × 2 = 4 个物理像素
5)像素
[1] 物理像素

物理像素是显示设备上的实际像素点,也称为"设备像素":

  • 屏幕上实际存在的发光点。
  • 由硬件决定,固定不变。
  • 不同设备的物理像素密度差异很大。
[2] 逻辑像素 / 设备独立像素

开发者针对不同的屏幕很难进行较好的适配,编写程序必须了解用户的分辨率来进行开发。所以在设备像素之上,操作系统为开发者进行抽象,提供了逻辑像素的概念。

比如你购买了一台显示器,在操作系统上是以 1920x1080 的设置的显示分辨率,那么无论你购买的是 2k、4k 的显示器,对于开发者来说,都是 1920x1080 的大小。

js
// 获取电脑的逻辑分辨率
window.screen.width;
window.screen.height;
[3] CSS 像素

CSS 中我们经常使用的单位也是 pixel,它在默认情况下等同于设备独立像素(也就是逻辑像素)。毕竟逻辑像素才是面向我们开发者的。

3. 断点

在开发当中,我们需要先选择一个逻辑分辨率(宽高)为基准来设置 CSS 元素大小,这样操作系统就会按照 DPR 来换算为真实的物理像素。需要注意,当缩放网页时,DPR 会改变,但 PPI 不会改变。

/* 断点参考 */
480 1024 1920

480 768 1024 1280 1440
一般网站不需要上面的精细分布,会使用三个断点:480 768/1024 1440

640px 1080px

768px 992px 1200px

4. 二倍图

"二倍图"是指像素密度为 2 的图像,也被称为"Retina"图像。这种图像的特点是它的像素密度是普通图像的两倍,因此在高分辨率的显示器上看起来更清晰。

例如,如果你有一个 100x100 像素的图像,它的二倍图版本应该是 200x200 像素的。但是在 CSS 中,你仍然将这个 200x200 像素的图像显示为 100x100 像素的大小,这样它在高分辨率的显示器上看起来就会更清晰。

以下是如何在 CSS 中使用二倍图的一个例子:

css
.logo {
  background-image: url('logo.png');
  background-size: 100px 100px;
  width: 100px;
  height: 100px;
}

@media only screen and (-webkit-min-device-pixel-ratio: 2), 
       only screen and (min-resolution: 192dpi) {
  .logo {
    background-image: url('logo@2x.png');
  }
}

首先设置了 .logo 元素的背景图像为 logo.png,然后在一个媒体查询中,将像素密度为 2 或更高的设备的背景图像设置为 logo@2x.png。这样,高分辨率的设备就会显示更清晰的图像。

类比,也有多倍图,只是二倍图多见。

二、移动端适配

1. 单独制作移动端页面(主流)

1)解决方案
  • 方案一:百分比布局,也叫流式布局。

  • 方案二:rem 单位 + 动态 html 的 font-size。

    • rem 单位 + 媒体查询

      点我查看代码
      css
      @media screen and (min-width: 320px) {
        html {
          font-size: 20px;
        }
      }
      
      @media screen and (min-width: 375px) {
        html {
          font-size: 24px;
        }
      }
      
      // ......
    • rem 单位 + 编写 js 来实时改变 font-size

      js
      // 1.获取html的元素
      const htmlEl = document.documentElement
      
      function setRemUnit() {
        // 2.获取html的宽度(视口的宽度)
        const htmlWidth = htmlEl.clientWidth
        // 3.根据宽度计算一个html的font-size的大小
        const htmlFontSize = htmlWidth / 10
        // 4.将font-size设置到html上
        htmlEl.style.fontSize = htmlFontSize + "px"
      }
      // 保证第一次进来时, 可以设置一次font-size
      setRemUnit()
      
      // 当屏幕尺寸发生变化时, 实时来修改html的font-size
      window.addEventListener("resize", setRemUnit)

      其实上面代码不用我们编写,在 GitHub 已经有人编写好了,我们拿来用就行,就是 lib-flexible。不过该库作者也不推荐使用了。推荐使用更好的 vw。

  • 方案三:vw 单位。

  • 方案四:flex 的弹性布局。

2)px 转 rem、vw
[1] px 转 rem
  • 方案一:less 或者 scss 函数

    less
    .pxToRem(@px) {
      result: 1rem * (@px / 37.5);
    }
    
    .box {
      width: .pxToRem(100)[result];
      height: .pxToRem(100)[result];
      background-color: orange;
    }
    
    p {
      font-size: .pxToRem(14)[result];
    }
  • 方案二:postcss-pxtorem(用于转为 rem);postcss-px-to-viewport-8-plugin(用于转为 vw)

  • 方案三:VSCode 插件【px to rem & rpx & vw (cssrem)】

[2] px 转 vw
css
/*
  假设设计稿是 375px,那么根元素字体大小为 37.5px
  转为 vw 是 font-size: 10vw;
  以前计算是 100px÷37.5px=2.667rem,现在是 2.667rem = 2.667*10vw = 26.67vw
  因为 1rem=37.5px   1vw=3.75px
  如果之前使用过 rem,需要转为 vw,根元素字体大小可以不设置,只需要把 rem 单位换位 vw,然后乘 10 即可
*/

html {
  font-size: 10vw; /* 设计稿宽度÷10 */
}

2. 响应式页面兼容移动端

  • 媒体查询
  • bootstarp

第十章:响应式布局

一、媒体查询

1. 基础

1)媒体类型
描述
all (默认)用于所有设备
screen用于电脑屏幕,平板电脑,智能手机等
print用于打印机和打印预览
speech应用于屏幕阅读器等发声设备
aural已废弃。用于语音和声音合成器
braille已废弃。应用于盲文触摸式反馈设备
embossed已废弃。用于打印的盲人印刷设备
handheld已废弃。用于掌上设备或更小的装置,如 PDA 和小型电话
projection已废弃。用于投影设备
tty已废弃。用于固定的字符网格,如电报、终端设备和对字符有限制的便携设备
tv已废弃。用于电视和网络电视
2)媒体特性

常用媒体特性

  • aspect-ratio:可视窗口宽高比。min-* / max-*

  • device-aspect-ratio:设备的宽高比。min-* / max-*

  • orientation:设备的使用方向

    取值:
    landscape (水平方向)
    portrait(垂直方向 )

  • width:可视窗口的宽度。还有 max-width / min-width(包含等于)

  • height:可视窗口的高度。还有 max-height/ min-height(包含等于)

  • device-width:设备的宽度。还有 max-device-width / min-device-width(包含等于)

  • resolution(安卓):屏幕设备像素比 / 像素密度,单位 dpi、dpcm 或 dppx。min-* / max-*

  • -webkit-device-pixel-radio(ios):屏幕设备像素比率。-webkit-(min/max)-device-pixel-radio

所有媒体特性列表

描述
aspect-ratio定义输出设备中的页面可见区域宽度与高度的比率
color定义输出设备每一组彩色原件的个数。如果不是彩色设备,则值等于0
color-index定义在输出设备的彩色查询表中的条目数。如果没有使用彩色查询表,则值等于0
device-aspect-ratio定义输出设备的屏幕可见宽度与高度的比率。
device-height定义输出设备的屏幕可见高度。
device-width定义输出设备的屏幕可见宽度。
grid用来查询输出设备是否使用栅格或点阵。
height定义输出设备中的页面可见区域高度。
max-aspect-ratio定义输出设备的屏幕可见宽度与高度的最大比率。
max-color定义输出设备每一组彩色原件的最大个数。
max-color-index定义在输出设备的彩色查询表中的最大条目数。
max-device-aspect-ratio定义输出设备的屏幕可见宽度与高度的最大比率。
max-device-height定义输出设备的屏幕可见的最大高度。
max-device-width定义输出设备的屏幕最大可见宽度。
max-height定义输出设备中的页面最大可见区域高度。
max-monochrome定义在一个单色框架缓冲区中每像素包含的最大单色原件个数。
max-resolution定义设备的最大分辨率。
max-width定义输出设备中的页面最大可见区域宽度。
min-aspect-ratio定义输出设备中的页面可见区域宽度与高度的最小比率。
min-color定义输出设备每一组彩色原件的最小个数。
min-color-index定义在输出设备的彩色查询表中的最小条目数。
min-device-aspect-ratio定义输出设备的屏幕可见宽度与高度的最小比率。
min-device-width定义输出设备的屏幕最小可见宽度。
min-device-height定义输出设备的屏幕的最小可见高度。
min-height定义输出设备中的页面最小可见区域高度。
min-monochrome定义在一个单色框架缓冲区中每像素包含的最小单色原件个数
min-resolution定义设备的最小分辨率。
min-width定义输出设备中的页面最小可见区域宽度。
monochrome定义在一个单色框架缓冲区中每像素包含的单色原件个数。如果不是单色设备,则值等于0
orientation定义输出设备中的页面可见区域高度是否大于或等于宽度。
resolution定义设备的分辨率。如:96dpi, 300dpi, 118dpcm
scan定义电视类设备的扫描工序。
width定义输出设备中的页面可见区域宽度。
3)媒体查询运算符
  • and 并且

  • , 或者

  • not 否定。一定要指定媒体类型,因为媒体类型默认 all

    "not" 运算符作用于整个媒体查询,而不是查询中的某个具体条件。举个例子:@media not (color) and (min-width: 700px) { ... },这个查询的意思是:应用样式于不支持【彩色且宽度至少为 700px 的设备】。错误理解:非彩色或宽度至少为 700px 的设备。

    css
    /* 示例1:错误理解 */
    @media not (color) and (min-width: 700px)
    /* 以为匹配:黑白屏 且 宽度≥700px */
    
    /* 示例2:实际匹配 */
    @media not (color) and (min-width: 700px)
    /* 真正匹配:黑白屏 或 宽度<700px */
    
    /* --------------------------------------------------------------- */
    /* 想要:不支持彩色 且 宽度≥700px */
    /* 方法一 */
    @media not all and (color), all and (min-width: 700px) {
      /* 这样写比较复杂,通常分开写更清晰 */
    }
    
    /* 方法二:分步 */
    @media (min-width: 700px) {
      /* 先匹配宽度 */
    }
    @media not all and (color) {
      /* 再单独处理不支持彩色的情况 */
    }
  • only only + 媒体类型

    使用 "only" 可以确保旧版浏览器完全忽略这个媒体查询,因为旧版浏览器不认识 only 关键字,所以会忽略这个媒体查询。

2. 用法

1)用法一
html
<link rel="stylesheet" media="mediatype and (media feature)" href="mystylesheet.css">
<link rel="stylesheet" media="mediatype" href="mystylesheet.css">
<link rel="stylesheet" media="(media feature)" href="mystylesheet.css">
2)用法二
css
@import url(css文件) mediatype and (media feature)
@import url(css文件) mediaType
@import url(css文件) (media feature)
3)用法三
css
@media [not|only] mediatype and (media feature) {
  CSS-Code;
}

@media (media feature) {
  CSS-Code;
}

3. 实战

移动端优先

css
@media screen and (min-width: 320px) and (max-width: 375px) {
  body { background-color: #f00; }
}

@media screen and (min-width: 375px) and (max-width: 414px) {
  body { background-color: #0f0; }
}

@media screen and (min-width: 414px) and (max-width: 600px) {
  body { background-color: #00f; }
}

@media screen and (min-width: 600px) and (max-width: 750px) {
  body { background-color: #f80; }
}

等价于

css
@media screen and (min-width: 320px) {
  body { background-color: #f00; }
}

@media screen and (min-width: 375px) {
  body { background-color: #0f0; }
}

@media screen and (min-width: 414px) {
  body { background-color: #00f; }
}

@media screen and (min-width: 600px) {
  body { background-color: #f80; }
}

@media screen and (min-width: 750px) {
  body { background-color: #fff; }
}

三、图片响应式

1. aspect-ratio

一个 div 元素设置了背景图片,且设置了宽高,还设置了边框。现在的问题是边框不能完美的包裹住图片,如何让边框随着图片的大小改变而改变呢?

就可以使用 aspect-ratio: 16/9; 来设置宽高比,如果不知道宽高比,也可以设置为图片实际的【宽/高】。这样 div 元素只需设置宽度就行,高度会自动计算。

附加

一、FC

块级盒子(Block-level boxes)参与块格式化上下文(block formatting context)。内联级盒子(Inline-level boxes)参与内联格式化上下文(inline formatting context)。

1. BFC

1)是什么

BFC 的意思是 Block Formatting Context,即块级格式上下文。当元素满足了某些条件,我们认为该元素创建了 BFC。创建了 BFC 的元素我们可以把他看做是一个独立的容器,容器内的元素不论如何布局都不会影响到外面。

了解 BFC 可以帮助你更好地理解 CSS 的布局,并解决一些常见的布局问题,例如清除浮动,防止元素塌陷等。

2)创建 BFC 的方式
  • 根元素。
  • 浮动元素。
  • 绝对定位或固定定位的元素。
  • 行内块元素。
  • 表格单元格(th、td)、表格行(tr)、表格标题(caption)、table、thead、tbody、tfoot。
  • 设置元素的 display 属性为 inline-blocktable-cell (表格单元格)table-caption (表格标题)
  • 匿名表格单元格元素。更具体点是元素的 display 为 table、table-row、table-row-group、table-header-group、table-footer-group(分别是 HTML table、tr、tbody、thead、tfoot 的默认属性)或 inline-table。
  • overflow 的值不为 visible 的块元素。
  • 伸缩项目。也被称为 FFC。
  • 网格元素(display 为 grid 或 inline-grid 元素的直接子元素)。也被称为 GFC。
  • 多列容器。
  • column-span 为 all 的元素始终会创建一个新的 BFC,即使该元素没有包裹在一个多列容器中。
  • display: flow-root 专门用于创建 BFC,没有任何副作用。
3)BFC 排布方式 / 特征

在 BFC 中,box 会在垂直方向上一个接着一个的排布;

垂直方向的间距由 margin 属性决定;

在同一个 BFC 中,相邻两个 box 之间的 margin 会折叠(collapse);

在 BFC 中,每个元素的左边缘是紧挨着包含块的左边缘的;

BFC 的区域不会与 float 的元素区域重叠。

BFC 是一个独立的容器,内部元素不会影响外部元素。

4)创建 BFC 可以解决的问题
① 清除子元素浮动的影响

在 BFC 中,子元素的浮动不会影响父元素的高度。这可以解决因为子元素浮动导致父元素高度塌陷的问题。

BFC 解决高度塌陷需要满足两个条件:

  • 浮动元素的父元素触发 BFC,形成独立的块级格式化上下文。
  • 浮动元素的父元素的高度是 auto 的。

为什么可以解决浮动高度的塌陷问题,但是不能解决绝对定位元素的高度塌陷问题呢?

块格式化上下文根元素的"Auto"高度计算规则:

  • 如果只有内联级别的元素,高度是最顶部行框的顶部到最底部行框底部的距离。
  • 如果只有块级元素,是由最底层的块上边缘和最底层块盒子的下边缘之间的距离(包含外边距)。
  • 如果有绝对定位元素会被忽略;相对定位的盒子会被考虑,但不计算其偏移量。
  • 如果元素有浮动元素,那么会增加高度以包括这些浮动元素的下边缘。
② 解决外边距塌陷

给父元素创建 BFC。

二、CSS 函数

1. calc 函数

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

css
width: calc(100% - 80px);

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

2. var 函数

var() 函数允许使用自定义属性(也称为 CSS 变量)来存储特定的值,以便在整个样式表中重复使用。

1)语法

css
var(--custom-property-name, fallback-value)
  • --custom-property-name 是你定义的变量名。
  • fallback-value 是可选的,当变量未定义时使用的默认值。

2)使用

定义变量。通常在 :root 选择器中定义全局变量。

css
:root {
  --main-color: #3498db;
  --font-size: 16px;
}

使用变量。

css
.button {
  background-color: var(--main-color);
  font-size: var(--font-size);
}

注意:给某个元素使用 --xxx: xxx 定义了变量,该变量只能在其子元素中使用。所以一般给 html 元素设置。

3. min / max / clamp

css
width: min(50%, 300px, 20rem);    /* 取 50%、300px、20rem 中最小的那个值 */
width: max(50%, 300px, 20rem);    /* 取 50%、300px、20rem 中最大的那个值 */
width: clamp(200px, 50%, 800px);  /* 宽度首选 50% , 只要这个值没有超过 200px-800px */

三、其他 CSS 属性

1. 触摸相关

1)touch-action

touch-action 是一个 CSS 属性,用于控制触摸屏设备(如手机、平板)上的触摸行为如何触发浏览器默认动作(例如滚动、缩放、平移等)。它主要用于优化触摸交互体验,尤其是在开发触摸友好的网页或应用时。

常用值

  • auto:默认值,允许浏览器处理触摸行为(例如滚动、缩放)。
  • none:禁止浏览器处理触摸行为,通常用于完全自定义触摸事件(例如游戏或绘图应用)。
  • pan-x:允许水平方向的滚动(平移)。
  • pan-y:允许垂直方向的滚动(平移)。
  • pinch-zoom:允许缩放操作。
  • manipulation:等同于 pan-x pan-y pinch-zoom,允许滚动和缩放,但可能禁用一些高级手势。
2)user-select

user-select 是一个 CSS 属性,用于控制用户是否可以选择页面中的文本或内容。它主要用于限制或启用文本选择行为。

常用值

  • auto:默认值,允许用户选择文本(视具体元素而定,例如 <input><textarea> 默认可选择)。
  • none:禁止用户选择文本。
  • text:强制允许选择文本内容。
  • all:允许一次性选中整个内容(点击一下即可全选)。

2. 滚动相关

1)overscroll-behavior

当一个嵌套的滚动容器滚动到边界时,默认情况下,滚动事件可能会“泄漏”到外部的父级滚动容器。例如,滚动一个弹窗的内容时,滚到头可能会导致背景页面也滚动。overscroll-behavior 可以防止这种情况。

通常设置给 body 元素。

常用值

  • auto(默认):允许滚动穿透到父级滚动容器。
  • contain:阻止滚动穿透到父级容器。
  • none:完全禁用滚动穿透和滚动回弹效果(如 iOS 的橡皮筋效果)。
2)scroll-behavior

在单页应用中,当点击导航链接或使用 JavaScript 滚动时,通常希望滚动是平滑的,而不是瞬间跳转到目标位置。

通常设置给 html 元素。

常用值

  • auto(默认):立即跳转到目标位置,没有过渡动画。
  • smooth:滚动到目标位置时会有平滑的过渡动画。
3)scroll-snap
[1] 容器属性

scroll-snap-type

定义滚动容器的滚动吸附行为。

常用值

  • none(默认值):不启用滚动吸附。
  • x:仅在水平滚动方向启用吸附。
  • y:仅在垂直滚动方向启用吸附。
css
/* 不写第二个参数,默认是 mandatory */
scroll-snap-type: x [mandatory];
scroll-snap-type: x [proximity];
属性值强制性滚动体验适用场景
mandatory强制吸附到最近的吸附点更严格、更精准的滚动对齐轮播图、分页滚动
proximity接近吸附点时才触发吸附更灵活、更自然的滚动体验自由滚动的内容展示

scroll-padding

为滚动容器的吸附区域添加内边距,确保吸附的内容不会紧贴容器边缘。

[2] 子元素属性

scroll-snap-align

定义子元素在滚动吸附时的对齐方式。

常用值:

  • start:子元素的开头与滚动容器的边缘对齐。
  • center:子元素的中心与滚动容器的边缘对齐。
  • end:子元素的结尾与滚动容器的边缘对齐。

scroll-margin

为子元素的滚动吸附区域添加外边距,确保吸附点不会紧贴容器边缘。

scroll-snap-stop

控制滚动吸附的强度,决定是否允许用户跳过吸附点。

常用值:

  • normal(默认值):允许用户快速滚动跳过吸附点。
  • always:强制每次都吸附到吸附点。

Updated at:

Released under the MIT License.