HTML和CSS核心知识

716 阅读34分钟

文档声明

<!DOCTYPE>即文档声明,是一种告知浏览器当前HTML文档版本的声明,用于指导浏览器如何正确地解析和显示文档

文档声明必须在HTML文档的第一行,且顶格书写,对大小写不敏感,任何在文档声明之前的内容都可能触发浏览器进行怪异模式

在HTML5中,文档声明使用<!DOCTYPE html>的形式,通过加入该文档声明,浏览器就会以最新的HTML5标准对文档进行解析,这样可以提高文档的可预测性和兼容性,确保页面在不同浏览器和平台下能够保持一致

标准模式和怪异模式

标准模式和怪异模式是浏览器的两种不同的HTML文档解析和渲染方式,它们会影响浏览器如何解释和执行HTML、CSS、JavaScript代码

标准模式又称严格模式,是指浏览器按照W3C的标准来解析和渲染HTML文档,这意味着浏览器会遵循最新的HTML、CSS和JavaScript规范,以提供一致和可预测的页面表现

怪异模式又称混杂模式,是指浏览器以一种向后兼容的方式对文档进行解析和渲染。在这种模式下,浏览器会模式老式浏览器的行为,以确保老旧的页面也能够正常显示

两者的区别:

  • 标准模式下,宽高设置的是元素的内容盒

    而老版本的IE浏览器,在怪异模式下,宽高设置的是元素的边框盒

  • 在标准模式下,给span等行内元素设置width和height都不会生效,而在怪异模式下会生效

  • 使用 margin: 0 auto 在标准模式下可以使元素水平居中,但在怪异模式下会失效

  • 怪异模式下 white-space: pre 会失效

  • 怪异模式下设置图片的 padding 会失效

  • 标准模式下,子元素高度为百分比,但父元素高度自动,则子元素设置高度无效

    怪异模式下,子元素高度为百分比在任何情况下都能被正确应用

语义化

语义化的概念

HTML5的语义化指的是合理使用语义化的标签来创建页面结构,如header,footer,nav,从标签上即可以直观的知道这个标签的作用,而不是滥用div

语义化包含两个层面:

  1. 每一个元素都有具体的含义

  2. 元素展示在页面中的效果,应该由CSS决定,跟选择哪个元素无关

    因此选择使用某个元素时,应该根据内容的含义,而不应该根据内容的样式进行元素选择

语义化的作用

  1. 为了搜索引擎优化(SEO)

    语义化的元素能够让搜索引擎更好地理解页面(搜索引擎理解得越好,网页显示时就可能越靠前)

  2. 方便其他设备解析(如屏幕阅读器)网页

  3. 代码结构清晰,易于阅读,利于维护

常见语义化元素

  • article
  • aside
  • nav
  • main
  • section
  • header
  • footer

image.png

SEO

SEO(Search Engine Optimization),即搜索引擎优化,是一种通过利用搜索引擎内在规则,提升网站在相关搜索引擎中自然排名的方法

实现SEO的手段:

  1. 使用语义化元素

    语义化的元素不仅有利于SEO,还有利于开发者理解页面结构

  2. 为非装饰性图片添加alt属性

    alt属性能够帮助搜索引擎理解图片内容,同时屏幕阅读器也能根据alt属性朗读出图片的描述信息

  3. 服务端渲染

    大部分搜索引擎爬虫只会抓取到网页的静态源代码,而不会执行其中的JS代码

    采用Vue构建的单页面应用,就是采用客户端渲染的方式,页面上的DOM元素是在客户端通过JavaScript动态生成的,这是需要一定时间的,爬虫不会等你渲染好再分析页面,因此能够抓取和分析的内容会大幅减少

  4. 避免使用iframe

    iframe中的内容不会被搜索引擎爬虫抓取

  5. 合理使用TDK

SEO的TDK

SEO的TDK分别是指Title(标题)、Description(描述)、Keywords(关键词)

  • Title

    网页的标题,也是搜索引擎结果页面(SERP)中显示的链接标题

    标题是搜索引擎了解网页主题和内容的重要依据,也是吸引用户点击的第一要素

    标题的长度控制在60个字符以内,以避免在SERP中被截断

  • Description

    网页的描述,通常显示在标题的下方,是对网页内容的简短概述

    描述是用户决定是否点击链接的重要参考因素

    描述长度控制在160个字符以内,确保在SERP中完整显示

  • Keywords

    由于早期网站对关键词的滥用,导致如今大部分的搜索引擎对关键字的参考已经大大降低,但对小部分搜索引擎仍具有一定意义

    关键词的数量一般不超过3个,每个关键词不宜过长,而且词语间要用英文逗号隔开,更重要的关键字尽量靠前放

<title>标题</title>								<!-- T -->
<meta name="description" content="描述">			<!-- D -->
<meta name="keywords" content="关键词">			<!-- K -->

meta元素

<meta>标签主要用于提供有关 HTML 文档的元数据(metadata)

元数据是关于数据的数据,它不会显示在网页的内容区域,但会被浏览器和搜索引擎解析和处理,以了解网页信息

meta元素的作用包含以下几点:

  1. 定义文档的字符集:通过 <meta charset="UTF-8"> 这样的标签,可以指定网页内容使用的字符编码
  2. 设置网页描述:<meta name="description" content="这里是网页的描述内容">,这个描述通常会显示在搜索引擎结果页面中,有助于吸引用户点击
  3. 定义关键词:虽然现代搜索引擎对 <meta name="keywords" content="关键词1, 关键词2"> 的重视程度已大大降低,但在过去,它用于帮助搜索引擎理解网页的主要内容
  4. 指定网页的视口(viewport):对于移动设备,<meta name="viewport" content="width=device-width, initial-scale=1.0"> 非常重要,它告诉浏览器如何控制页面的尺寸和比例

iframe元素

iframe是HTML中的一个元素,用于在当前页面中嵌入另一个独立的HTML文档

优点:

  • 独立性:iframe可以在页面上独立显示一个页面或内容,而不会与页面中的其他元素产生冲突
  • 代码复用:通过使用iframe,可以将一些常用的网页元素(如导航栏、页脚等)封装成一个独立的页面,然后在其他页面中引用,这样可以减少代码的重复编写,提高开发效率

缺点:

  • 加载时间延长:每个iframe都需要加载自己的HTML、CSS和JavaScript文件,增加了请求服务器的次数,也增加整个页面的加载时间(使主页面的onload事件延后触发)
  • SEO受影响:爬虫无法解析iframe中的内容,导致这部分内容无法被搜索引擎收录和展示,这会影响搜索排名和可见性
  • 难以调整大小和样式:iframe的大小和样式通常由嵌入的网页决定,如果需要调整iframe的大小和样式,就需要修改嵌入网页的代码和样式表,增加了维护的复杂度
  • 安全性:iframe可以嵌入来自其他网站的内容,这可能导致安全性问题。比如恶意网站可以通过iframe嵌入攻击代码,实施点击劫持等攻击手段

页面可见性API

页面可见性API可以用于判断用户当前是否正在浏览本网页

页面可见性API为document添加了一个事件和一个属性

  • visibilitychange事件

    当页面可见性发生变化时会触发该事件

    如用户切换标签页时、浏览器窗口被覆盖时、最小化浏览器窗口时、设备待机时

  • visibilityState属性,只读属性,取值包含以下几种

    visible:页面内容对用户可见(包括部分可见)

    hidden:页面内容对用户不可见(完全不可见)

利用页面可见性API,可以实现:

  • 网站有图片轮播效果,只有在用户观看轮播的时候,才会自动展示下一张幻灯片
  • 当设备进入待机模式时,关闭网页中的视频和音频的播放

a元素的功能

  1. 跳转页面:设置href属性为其他页面的url,即可在点击a元素时跳转到目标页面
  2. 锚点导航:通过设置href属性为#加上页面内某个元素的id,来实现页面内的锚点导航
  3. 拨打电话:在支持的设备上,通过设置href属性为tel:加上电话号码,a元素就可以创建一个拨打电话的链接。用户点击链接时,会尝试使用设备的电话功能拨打指定的号码
  4. 发送邮件:通过设置href属性为mailto:加上电子邮件地址,a元素就可以创建一个发送电子邮件的链接。用户点击链接时,会启动默认的邮件客户端,并填写好收件人地址
  5. 文件下载:通过设置a元素的download属性,可以使其指向的文件在点击时被下载,而不是在浏览器中打开
  6. JS交互:通过设置href属性为javascript:加上js代码的形式,在点击a元素时即可执行一段简单的js代码

CSS的四种引入方式

  1. 行内样式

    行内样式即直接书写在元素的style属性中的样式

  2. 内联样式

    内部样式是书写在html文档中style标签中的样式

  3. link元素导入外部样式

  4. @import导入外部样式

    @import需要书写在样式代码之中,只有主样式代码文件加载完成并开始解析后,@import所导入的样式文件才会被加载

常规流

视觉格式化模型

视觉格式化模型规定了页面中多个盒子的排列规则

视觉格式化模型,大体上将页面中盒子的排列方式分为三种:

  1. 常规流
  2. 浮动
  3. 定位

常规流布局

常规流,也称为文档流,标准流

所有元素,默认情况下,都属于常规流

总体规则:常规流块盒独占一行,常规流行盒水平依次排列

包含块

包含块(containing block):每个盒子都有它的包含块,包含块决定了盒子的排列区域(活动范围)

绝大部分情况下,盒子的包含块,为其父元素的内容盒

常规流块盒
  1. 块盒的总宽度(margin+border+padding+content)必须等于包含块的宽度

    width: auto表示将包含块的剩余水平空间吸收,width的默认值就是auto

    左右margin: auto表示将包含块的剩余水平空间吸收,margin的默认值为0

    当width和margin都为auto,则剩余水平空间会归width所有,因为width的空间吸收能力强于margin

    若常块盒width为auto,左右margin为负值,则会导致块盒的content-box宽度增加

    要设置块盒在包含块中水平居中,可以将块盒定宽,并将左右margin设置为auto

  2. 垂直方向上的auto

    height: auto表示适应内容高度

    垂直margin: auto等于0

  3. 百分比取值

    width、padding、margin可以取值为百分比,这些百分比都是相对于包含块的宽度

    height百分比:

    • 如果子元素的高度设置为百分比,但其包含块的高度取决于子元素,则高度百分比无效
    • 如果包含块高度固定,不取决于子元素,则子元素设置的高度百分比相对于包含块高度

    注意:border的尺寸不能设置为百分比

  4. 外边距合并

    两个常规流块盒,若上下外边距无缝相邻时,会发生合并

    所谓的上下外边距可以是一上一下,也可以是都为上,后者通常出现父子元素之间

  5. 忽略脱离常规流的元素

    常规流元素会无视浮动和定位元素的原因

  6. 计算自动高度时,会忽略其内部的脱离了常规流的元素

    高度坍塌的原因

可替换元素与非可替换元素

大部分元素,其显示在页面中的内容,取决于元素内部的内容,称为非可替换元素

常见的可替换元素有:divspanph1 ~ h6

少部分元素,在显示在页面中的内容,取决于元素的属性,称为可替换元素

常见的可替换元素有:imgvideoaudiocanvasiframe

可替换元素的特点:

  1. 通常为行盒
  2. 设置所有尺寸都有效
  3. CSS不能完全控制其样式

行盒盒模型

常见的行盒:spanstrongemiimgvideoaudio

特点

  1. 盒子宽度随内容进行延伸

    行盒高度不计算内部的行块盒以及可替换元素

  2. 设置宽高无效

    可以通过调整字体大小、字体类型等间接调整宽高

    也可以通过左右padding间接调整

  3. 内边距在水平方向有效,垂直方向上仅会导致背景覆盖区域变化,不会实际占据空间

  4. 边框在水平方向有效,垂直方向上仅会导致边框覆盖区域变化,不会实际占据空间

  5. 外边距在水平方向上设置有效,垂直方向无效

行块盒

display属性为inline-block的盒子,其有以下特点:

  1. 不独占一行
  2. 所有尺寸都有效

浮动

左浮动:设置元素属性float: left,左浮动的元素在包含块中(先)靠上(再)靠左排列

右浮动:设置元素属性float: right,右浮动的元素在包含块中(先)靠上(再)靠右排列

常规流中的元素,默认floatnone,即不浮动

特点

  1. 浮动后的元素,一定为块盒

  2. 浮动元素是脱离常规流的

  3. 浮动盒子的尺寸

    宽度为auto时,为适应内容的宽度

    高度为auto时,为适应内容的高度

    marginauto时,均为0

盒子排列

  1. 左浮动的盒子靠上靠左排列

  2. 右浮动的盒子靠上靠右排列

  3. 浮动盒子在包含块中排列时,会避开先前的兄弟常规流块盒

  4. 常规流块盒在排列时,无视先前的兄弟浮动盒子

  5. 行盒在排列时,会避开浮动盒子

    利用这个特点可以实现文字环绕

    如果文字没有直接在行盒中,浏览器会自动生成一个行盒包裹文字,该行盒叫做匿名行盒

高度坍塌

指常规流盒子的自动高度,在计算时不考虑浮动盒子

解决方法:清除浮动,清除浮动涉及css属性clear

  • none:默认值,不清除浮动
  • left:清除左浮动
  • right:清除右浮动
  • both:清除左右浮动
<!DOCTYPE html>
<style>
    .clearfix::after{
        content: "";
        display: block;
        clear: both;
    }

    li{
        float: left;
    }
</style>

<ul class="clearfix">
    <li></li>
    <li></li>
    <li></li>
</ul>

浮动的细节规则

  • 左浮动的盒子向上向左排列
  • 右浮动的盒子向上向右排列
  • 浮动盒子的顶边不得高于上一个盒子的顶边
  • 若剩余空间无法放下浮动盒子,则该盒子向下移动,直到具备足够的空间容纳盒子,然后再向左或向右移动

image.png

定位

定位用来手动控制元素在包含块中的精确位置

position属性:

  • static:静态定位(不定位)
  • relative:相对定位,不会导致元素脱离常规流
  • absolute:绝对定位,会导致元素脱离常规流
  • fixed:固定定位,会导致元素脱离常规流
  • sticky:粘性定位

position不为static的元素就是定位元素

脱离常规流的元素的特点

  1. 常规流中的元素在摆放时,会忽略脱离了常规流的元素

    常规流元素会忽略浮动和定位元素的原因

  2. 常规流中的元素计算自动高度时,会忽略其内部的脱离了常规流的元素

    高度坍塌的原因

    浮动导致的高度坍塌可以处理,但定位导致的高度坍塌无法处理

相对定位

相对定位不会导致元素脱离文档流,只是允许元素在原来位置进行偏移

相对定位元素的偏移相对的是元素原来的位置

相对定位元素的偏移不会对其他盒子造成任何影响

绝对定位

特点
  1. 绝对定位元素,它的宽高为auto时,表示适应内容的宽高

    注意第3种的特殊情况

  2. 绝对定位元素,它的包含块:

    若祖先元素中存在定位元素,则从下往上找,找祖先元素中第一个定位的祖先元素的填充盒为其包含块

    若祖先元素中均没有定位元素,则包含块为网页最左上端的视口区域

    试滑动横向及纵向滚动条,并关注div所在的位置:

    <!DOCTYPE html>
    <style>
        html {
            width: 200vw;
            height: 200vh;
        }
    
        div {
            width: 100px;
            height: 100px;
            background-color: lightblue;
            position: absolute;
            right: 0;
            bottom: 0;
        }
    </style>
    
    <div></div>
    
  3. 绝对定位元素,不给其定宽,并且为其leftright同时设置为0,则定位元素宽度会撑满包含块

    绝对定位元素,不给其定高,并且为其topbottom同时设置为0,则定位元素高度会撑满包含块

  4. 绝对定位、固定定位元素的left、right百分比取值,相对于包含块的宽度;top、bottom百分比取值,相对于包含块的高度

固定定位

除包含块外,其它情况与绝对定位相同

固定定位的包含块始终为视口

定位下的居中

以下的居中只能使用在绝对定位和固定定位的元素上,相对定位元素无效

居中是指在定位元素在包含块中居中

水平居中:将定位元素定宽,并将leftright同时设置为相同的绝对值,并将左右margin设置为auto

垂直居中:将定位元素定高,并将topbottom同时设置为相同的绝对值,并将上下margin设置为auto

补充

  1. 只有定位元素,设置z-index才有效

  2. 绝对定位、固定定位的盒子一定是块盒

  3. 除相对定位外,绝对定位与固定定位都会导致元素脱离常规流

  4. 绝对定位、固定定位元素一定不会是浮动元素

  5. 绝对定位、固定定位元素没有外边距合并

  6. 定位元素设置left: 0top: 0是指其margin区域的左上角距离包含块左上角的距离为分别为0,0

    right: 100%bottom: 100%是指其margin区域的左上角距离包含块右下角的距离分别为0,0

  7. 定位元素的width、padding、margin百分比和常规流块盒一样,相对于包含块的宽度,height百分比相对于包含块的高度

    只是包含块发生了变化

块级格式化上下文

块级格式化上下文(BFC,Block Formatting Context),它是一块独立的渲染区域,它规定了在该区域中,常规流块盒的布局规则

常规流块盒的布局规则:

  1. 常规流块盒在水平方向上,必须撑满包含块
  2. 常规流块盒在包含块的垂直方向上依次摆放
  3. 常规流块盒若上下外边距无缝相邻,则进行外边距合并
  4. 常规流块盒的自动高度和摆放位置,无视脱离常规流的元素

BFC是一块渲染区域,由某个元素创建

以下元素会在内部创建BFC:

  • html元素

  • 行块盒

  • 浮动元素

  • 绝对定位和固定定位元素

  • overflow不为visible的块盒

    该块盒还是常规流块盒

<!DOCTYPE html>
<html>
<body>
  <div class="A" style="float: left;">
      <div class="B"></div>
  </div>

  <div class="C" style="position: absolute;">
      <div class="D"></div>
  </div>

  <div class="E">
      <div class="F"></div>
  </div>

  <div class="G" style="overflow: hidden;">
      <div class="H"></div>
  </div>
</body>
</html>

在上面的这些元素中

  • 元素A、C、E、F、G处在根元素创建的BFC中

    注意:虽然浮动元素和绝对定位元素不是常规流块盒,但不影响它们处在某个BFC中

  • 元素B处在元素A创建的BFC中

  • 元素D处在元素C创建的BFC中

  • 元素G处在元素H创建的BFC中

“独立的渲染区域”意味着不同的BFC,它们进行渲染时互不干扰

因此创建BFC的元素,隔绝了它内部(不包括元素自己)与外部的联系,内部的渲染不会影响到外部

BFC的具体规则

基于“BFC渲染的独立性”,使得创建BFC的元素具有以下几个特点:

  1. 创建BFC的元素,它的自动高度需要计算内部的浮动元素

    可以理解为:为了隔绝内部与外部的联系,创建BFC的元素的自动高度就需要计算浮动元素以保证浮动元素不会超出其覆盖范围,从而防止浮动元素影响到其他BFC中的元素

    会计算浮动元素,但绝对定位和固定定位元素仍不会计算

  2. 创建BFC的元素,它的边框盒不会与兄弟浮动元素的margin-box重叠

    当浮动元素书写靠前时,两者会在水平方向上依次排列而没有重叠区域

    利用这个特点可以实现多栏布局

  3. 创建BFC的元素,不会和它的子元素进行外边距合并

    只有处在同一个BFC中的两个常规流块盒才可能发生外边距合并

属性值的计算过程

页面上的所有元素,是一个元素一个元素依次渲染的,渲染顺序按照文档的树形目录结构进行

元素进行渲染的前提条件:该元素的所有CSS属性都必须有唯一的值

一个元素,从所有属性都没有值,到所有属性都有值,这个过程叫做属性值的计算过程

步骤:

  1. 确定声明值

  2. 层叠冲突

    1. 比较重要性
    2. 比较特殊性
    3. 比较源次序
  3. 使用继承

  4. 使用默认值

确定声明值

参考样式表(作者样式表和浏览器默认样式表)中没有冲突的声明,作为CSS属性的值

层叠冲突

对于样式表中有冲突的声明,使用层叠规则确定CSS属性的值

比较重要性

重要性从高到低:

  1. 作者样式表中的!important样式
  2. 作者样式表中的普通样式(无!important的样式)
  3. 浏览器默认样式表(user agent stylesheet)中的样式

若样式表中的两个样式,它们的重要性相同,则进入下一步

比较特殊性

总体规则:选择器选中的范围越窄,越特殊

具体规则:通过选择器,计算出一个4位数(_ _ _ _):

  • 千位:行内样式,记1,否则记0
  • 百位:选择器中所有id选择器的数量
  • 十位:选择器中所有类选择器、属性选择器、伪类选择器的数量
  • 个位:选择器中所有元素选择器、伪元素选择器的数量

每一位并非是逢十进一,据说是逢256进一

对于通配符选择器,它的“权重”为0

若样式表中的两个样式,它们的特殊性相同,则进入下一步

比较源次序

代码书写靠后的胜出

使用继承

对仍然没有值的属性,若可以继承,则继承父元素的值

通常跟文字内容相关的属性都能被继承,如:font-sizefont-styletext-align等属性·

使用默认值

对仍然没有值的属性,使用默认值

每一个CSS属性都天生带有一个默认值,它不是浏览器默认样式表中属性的值

堆叠上下文

堆叠上下文(Stack Context),它是一块区域,由某个元素创建,它规定了该区域中的内容在Z轴上排列的先后顺序

会创建堆叠上下文的元素:

  1. html元素(根元素)
  2. 设置z-index为数值(非auto值)的定位元素(包括相对定位)
  3. 设置transform为非none的元素
  4. 设置opacity小于1的元素

创建堆叠上下文的元素,其元素本身是并非处在它所创建的堆叠上下文中

处于堆叠上下文F中的元素,在Z轴上的排列顺序(从后向前)为:

  1. 创建堆叠上下文F的元素的背景和边框

  2. z-index为负值的定位元素所创建的子堆叠上下文S

  3. 常规流块盒

  4. 非定位浮动盒子

  5. 行盒

  6. z-index为auto的定位元素(不会创建堆叠上下文),以及z-index为0的定位元素创建的子堆叠上下文S

  7. z-index为正值的定位元素创建的子堆叠上下文S

    若同处于该级别的两个元素,z-index越大,越靠前

若处于同一堆叠上下文的两个元素,它们同属于上面的某一种情况,则位于文档后面的元素覆盖位于文档前面的元素

每个堆叠上下文,独立于其他堆叠上下文,它们之间不可相互穿插

image.png

CSS渲染性能优化

  1. 选择器的合理使用

    使用id选择器:id选择器是唯一的,这能够快速帮助浏览器找到元素并应用样式

    避免使用通配符选择器:通配符选择器的作用范围过大,会导致样式应用的速度变慢

    避免使用嵌套过长的选择器:过长的选择器会增加匹配元素的时间开销

  2. 合并CSS文件

    将多个CSS文件合并为一个文件可以减少HTTP请求的数量,从而加快页面加载速度

    利用构建工具(如Webpack)可以自动完成这一功能

    合并CSS文件不利于渐进式渲染

  3. 压缩

    对CSS中的空格、换行等进行移除,减小文件体积

    也可以对样式文件进行压缩

  4. 使用CSS预处理器

    Sass、Less等CSS预处理器可以提供变量、嵌套规则、混合等高级功能,使CSS代码更加简洁、易于维护,并且它们也支持压缩和自动合并CSS文件

  5. 避免使用@import指令

    使用@import引用的CSS文件只有在引用它的那个CSS文件被下载、解析之后,浏览器才会知道还有另外一个CSS文件需要下载,这时才去下载并开始解析,这就导致浏览器无法并行下载所需的样式文件

  6. 小图片处理

    雪碧图:对于多个小图片,可以合并成为一张雪碧图,减少请求图片的数量

    使用字体图标:对于小图片,可以替换为字体图标,一个字体图标就是一个文字,可以使用color属性进行换色,并且字体图标放大缩小不会出现失真

    使用base64格式的图片数据:base64数据可以直接书写在img元素的src属性位置,不需要额外发出请求

  7. 使用transform

    transform导致的元素变化不会导致页面重排重绘,因为transform的变换效果是由独立的合成线程负责处理的

  8. 预加载CSS文件

    通过使用设置了preload或prefetch的link元素来预加载CSS文件,当需要时可以直接使用下载完成的结果

  9. 内联关键CSS

    将页面首屏所需的关键CSS内联到HTML中,其余样式异步加载。这可以减少首次渲染时的CSS请求,提高渲染速度

CSS选择器的匹配过程

CSS选择器的匹配是从右向左进行的

例如,对于选择器div.container p span,浏览器会先查找所有span元素,然后向上查找其父元素是否为p,再向上查找是否为.container类名的div元素

从右到左的匹配方式可以有效减少需要遍历的元素数量,提高匹配效率

设想如果从左到右匹配,浏览器需要先找到所有的div元素,然后筛选出带有.container类的div,再查找其后代元素中所有的p,最后再查找p的后代元素中的span,这需要遍历大量的元素,效率低下,而从右到左匹配则可以避免这种大量的无效遍历

媒体查询

MDN 媒体查询

媒体查询(Media Query)能够根据不同的媒体类型和条件来应用不同的CSS样式

媒体类型

设备类型
all所有设备
braille盲人用点字法触觉回馈设备
embossed盲文打印机
handheld便携设备
print打印用纸或打印预览视图
projection各种投影设备
screen电脑显示器
speech语音或音频合成器
tv电视机类型设备
tty使用固定密度字母栅格的媒介,比如电传打字机和终端

使用方式

  1. link元素

    <link rel="stylesheet" href="index.css" media="screen" />
    

    当媒体为电脑显示器时,才会加载index.css

    <link rel="stylesheet" href="inex.css" media="screen and (max-width:600px)" />
    

    当媒体为电脑显示器,且屏幕宽度小于等于600px时才会加载index.css

    <link rel="stylesheet" href="inex.css" media="screen and (min-width:480px) and (max-width:600px)" />
    

    当媒体为电脑显示器,且屏幕宽度大于等于480px且小于等于600px时才会加载index.css

    <link rel="stylesheet" href="inex.css" media="screen (max-width:600px)" />
    

    当媒体的屏幕宽度小于等于600px时才会加载index.css

    <link rel="stylesheet" href="index.css" media="screen and (orientation: portrait)" />
    

    当设备处于横屏时才会加载index.css

  2. @import

    @import url("./index.css") screen and (max-width:600px);
    
  3. @media

    @media screen and (max-width:600px) {
        div {
            ...
        }
    }
    

补充:

  • 媒体查询可以嵌套使用
  • 媒体查询除了可以限制屏幕尺寸和方向,还可以用于限制其他特征,如分辨率、颜色深度等

单位总结

css中的单位可以分为两大类:绝对单位和相对单位

绝对单位:

  • px:像素
  • cm:厘米
  • mm:毫米
  • in:英寸

注意:一个像素的大小并非是固定的,不同设备的一个像素的尺寸会有所差异,因此像素被认为是绝对单位里的相对单位

相对单位:

  • %:百分比
  • em:对于font-size属性,相对于父元素的字体大小;对于其它属性,相对于元素本身的字体大小
  • rem:相对于html元素的字体大小
  • vw:视口宽度,1vw等于视口宽度的1%
  • vh:视口高度,1vh等于视口高度的1%

居中总结

本小节所描述的居中为盒子在其包含块中居中

水平居中

  • 行盒 & 行块盒

    设置的父元素text-align:center

    行盒 & 行块盒一定是常规流盒子,浮动与定位盒子一定是块盒

  • 常规流块盒

    给元素定宽,设置左右marginauto

  • 定位元素

    ① 给元素定宽,设置left、right为相同的绝对值,再设置左右marginauto

    ② 给元素定宽,设置left为50%,再设置margin-left为负的元素宽度的一半

    ③ 无需给元素定宽,设置left为50%,再设置transform的translateX属性为-50%

  • 使用flex布局,设置弹性容器justify-content: centent

垂直居中

  • 单行文本

    设置文本所在元素的line-height为包含块的高度

  • 行块盒 & 块盒内的多行文本

    设置盒子的上下padding为相同的绝对值

  • 定位元素

    ① 给元素定高,设置top、bottom为相同的绝对值,再设置上下marginauto

    ② 给元素定高,设置top为50%,再设置margin-top为负的元素高度的一半

    ③ 无需给元素定高,设置top为50%,再设置transform的translateY属性为-50%

  • 使用flex布局,设置弹性容器align-items: center

隐藏元素

  • display: none

    元素不会被渲染,且不会占据空间

    无法触发事件

    动态改变此属性时会引起重排

    不可继承属性

    不会触发过渡效果

  • visibility: hidden

    元素不会渲染,但会占据空间

    无法触发事件

    动态改变此属性时会引起重绘

    可继承属性,后代元素可以通过设置自身的visibility: visible来取消隐藏

    奇怪的过渡效果(延迟变化,而不是逐渐改变)

  • opacity: 0

    元素会渲染,且会占据空间

    正常触发事件

    提升为合成层,不会触发重排重绘

    不可继承属性

    能够触发过渡效果

calc函数

在任何样式属性值为数值的位置,都可以直接使用calc函数

calc能够对内部的数值进行计算,其支持加减乘除四种计算方式

width: calc(100px - 20px);

在计算加减时,需要在运算符±的左右空出一格,以免造成歧义

width: calc(100px -20px);		/* ❌ */

calc支持不同单位的数值进行运算,例如:

/* 利用calc实现元素居中 */
width: 200px;
height: 100px;
position: absolute;
left: calc(50% - 100px);
top: calc(50% - 50px);

粘性定位

  • 最近可滚动祖先

    粘性定位元素的最近可滚动祖先是指其祖先元素中最近的overflow不为visible的元素

    如果这样的祖先元素不存在,则视口会成为元素的最近可滚动祖先

  • 包含块

    粘性定位元素的包含块为父元素的内容盒

粘性定位元素需要根据偏移量属性(即top、left等)来判断是否需要进行“粘连”

假设为粘性定位元素设置top: 0,当通过滑动最近可滚动祖先的滚动条使得粘性定位元素的顶边触碰到最近可滚动祖先时,粘性定位元素就会黏在该最近可滚动祖先元素上

粘性定位元素黏在最近可滚动祖先上时,其原来的位置还是占据着的,其后面的元素不会因为粘性定位黏在别的地方就往上移

如果粘性定位元素的包含块已经不足以容纳完整的粘性定位元素,或者粘性定位元素的原本位置完整地处在最近可滚动祖先元素之中,则粘性定位元素就会跟着包含块一起滚动,而不会与最近可滚动祖先进行“粘连”

<style>
    ul{
        padding: 0;
        list-style: none;
    }
    .container{
        margin-top: 100px;
        height: 400px;
        overflow-y: auto;
        border: 1px solid #000;
        padding: 20px
    }

    li{
        margin: 0 auto;
        text-align: center;
        border: 2px solid #f40;
        width: 200px;
        padding: 20px 0;
    }

    li div {
        height: 30px;
        line-height: 30px;
    }

    .title {
        position: sticky;
        top: 0;
        background-color: lightblue;
    }
</style>

<div class="container">				<!-- 最近可滚动祖先 -->
    <ul>
        <li>						<!-- 其内容盒为包含块 -->
            <div class="title">ONE</div>			<!-- 粘性定位元素 -->
            (div.item>lorem1)*20					<!-- 生成元素,撑开父元素高度 -->
        </li>
        <li>
            <div class="title">TWO</div>
            (div.item>lorem1)*20
        </li>
        <li>
            <div class="title">THREE</div>
            (div.item>lorem1)*20
        </li>
    </ul>
</div>

CSS全局关键字属性值

  1. inherit

    主动继承父元素中对应属性的值

    继承始终来自文档树中的父元素,即使父元素不是包含块

  2. initial

    将属性的初始(或默认)值应用于元素

    注意:初始值并不是浏览器默认样式表中的默认值

  3. revert

    还原为浏览器默认样式表中的样式值

  4. unset

    如果属性是可继承的,则使用继承的值

    如果属性是不可继承的,则使用初始值

all属性

CSS中有一个特殊的属性 —— all,它代表着除了unicode-bidi与direction之外的所有css属性,其属性值可以取上面的四种关键字值

all: inherit;

word-break与word-wrap

word-break和word-wrap都是用于控制浏览器的文字截断规则

浏览器默认的文字显示规则:

  • 连续的空白字符折叠为一个空格
  • 对连续汉字,在容纳不下时在字与字之间进行截断,让剩余部分换行显示
  • 对英文单词,在能够划分单词的边界(如空格,短横线)位置进行截断,让剩余部分换行显示
  • 对于下一个无法进行截断的词语,如果剩余空间不足以将其容纳,就让其换行显示
  • 对于独占一行但又无法进行截断的词语,则溢出显示

word-break:

  • normal:使用浏览器默认的文字截断规则

  • break-all:在汉字或英文字母之间进行截断,无论截断的位置是否是单词的边界(强制截断)

    在这种截断方式下,不再会发生【换行显示下一个过长词语】的规则

  • keep-all:所有文字(包括汉字和英文单词)都在单词的边界处进行截断

    在这种情况下,浏览器会将连续的,中间无标点符号的,无空白字符的中文文字视为一个单词

word-wrap:

  • normal:使用浏览器默认的文字截断规则

  • break-word:在汉字或英文字母之间进行截断,无论截断的位置是否是单词的边界(强制截断)

    与word-break的break-all不同的是,word-wrap: break-word会将下一个过长词语进行换行显示,尝试看其能否在独占一行的情况下完全显示,如果仍发生溢出,就使用强制截断的方式让溢出部分换行显示

word-break其实本就包含属性值break-word,其功能与word-wrap: break-word完全相同,但W3C官方已经决定弃用word-break使用该属性值,而选择利用word-wrap属性使用break-wrap的功能,因为word-break能够与word-wrap相互配合实现更多样的文字效果

word-break与word-wrap的区别参考1

word-break与word-wrap的区别参考2

reflow与repaint

reflow(重排),是指计算元素的尺寸和位置的过程

导致reflow的原因:

  • 页面初次渲染时
  • 改变了元素的大小
  • 移动了元素的位置
  • 增加删除某个元素
  • 读取设置元素的尺寸和位置

重新计算布局信息是非常耗时的,因此需要尽量避免reflow的发生

repaint(重绘),是指重新绘制元素的过程

导致repaint的原因:

  • reflow的发生
  • 修改元素的背景颜色
  • 修改元素的字体颜色
  • 设置圆角边框等
  • 设置盒子阴影
  • 改变outline

由于reflow过后需要将元素重新渲染出来,因此reflow一定会导致repaint

重新绘制元素的过程是非常快速的,相比于reflow,仅只有repaint所造成的性能开销就好得多

减少reflow和repaint的方法:

  • 通过修改class批量修改样式
  • 使用transform
  • 使用文档碎片
  • 缓存布局信息
  • 使用服务端渲染SSR