003-CSS选择器优先级

CSS 选择器优先级计算规则(详细解析)

CSS 选择器的优先级决定了当多条规则作用于同一个元素时,哪条规则会被应用。以下是完整的优先级计算机制:

一、优先级计算原理

优先级是通过 选择器权重值 来计算的,权重由 4 个级别组成(从左到右比较):

[内联样式, ID选择器, 类/属性/伪类选择器, 元素(标签)/伪元素选择器]

权重计算规则:

  1. 从高到低逐级比较,先比较内联样式,再比较ID,然后类,最后元素
  2. 高权重比较胜出后即停止,不再比较低级别
  3. 相同权重 时,后定义的样式覆盖先定义的

二、权重值详细分类

1. 内联样式(权重值:1,0,0,0)

1
<div style="color: red;"></div> <!-- 优先级最高 -->

2. ID 选择器(权重值:0,1,0,0)

1
#header { color: blue; }

3. 类/属性/伪类选择器(权重值:0,0,1,0)

  • 类选择器:.nav
  • 属性选择器:[type="text"]
  • 伪类选择器::hover, :nth-child()

4. 元素/伪元素选择器(权重值:0,0,0,1)

  • 元素选择器:div, p
  • 伪元素选择器:::before, ::after

5. 通配符/继承样式(权重值:0,0,0,0)

  • 通配符:*
  • 继承的样式(如从父元素继承的字体颜色)

三、计算示例

示例1:

1
2
3
4
5
6
7
8
9
#nav .list li a:hover { ... } /* 0,1,2,2 */
/* 分解:
#nav → 0,1,0,0
.list → 0,0,1,0
li → 0,0,0,1
a → 0,0,0,1
:hover → 0,0,1,0
合计:0,1,2,2
*/

示例2:

1
2
3
4
5
6
7
8
9
10
body .menu > ul li.active { ... } /* 0,0,2,3 */
/* 分解:
body → 0,0,0,1
.menu → 0,0,1,0
> → 不计算
ul → 0,0,0,1
li → 0,0,0,1
.active → 0,0,1,0
合计:0,0,2,3
*/

四、特殊规则

1. !important(最高优先级)

1
p { color: red !important; } /* 超越所有优先级 */
  • 会覆盖其他所有声明(包括内联样式)
  • 应该尽量避免使用,会导致样式难以维护

2. 相同权重时的顺序

1
2
.btn { color: blue; }  /* 规则1 */
.btn { color: green; } /* 规则2 - 最终生效 */

3. 组合选择器的计算

1
2
3
4
5
/* 权重:0,0,1,0 + 0,0,0,1 = 0,0,1,1 */
.nav li { ... }

/* 权重:0,0,1,0 + 0,0,1,0 = 0,0,2,0 */
.nav.active { ... }

4. :where() 和 :is() 的特殊性

1
2
:where(.nav) li { ... } /* 权重:0,0,0,1(:where()内的选择器不计权重) */
:is(.nav, #main) li { ... } /* 权重取参数中最高的(此处为0,1,0,1) */

五、优先级比较示例

选择器示例 权重值 说明
style="..." 1,0,0,0 内联样式
#header .logo 0,1,1,0 ID+类
ul#menu li.active 0,1,1,2 ID+类+2元素
.btn:hover 0,0,2,0 类+伪类
div p 0,0,0,2 2个元素
* 0,0,0,0 通配符

六、最佳实践建议

  1. 避免过度使用ID选择器 - 会导致优先级过高,难以覆盖
  2. 尽量使用类选择器 - 保持适度的优先级
  3. 避免!important - 除非必要(如覆盖第三方库样式)
  4. 使用CSS方法论(如BEM)来管理选择器复杂度
  5. 利用层叠特性 - 合理组织CSS顺序比提高优先级更好

004-SVG和Canvas对比详解

SVG 和 Canvas 是两种主流的 Web 图形技术,各有优缺点和适用场景。以下是详细对比:


1. 基础概念

特性 SVG (Scalable Vector Graphics) Canvas
类型 矢量图形(基于 XML 描述图形) 位图(通过 JavaScript 动态绘制像素)
渲染方式 由浏览器解析 XML 并渲染(DOM 的一部分) 通过 JavaScript API 直接操作像素
分辨率 无限缩放,不失真(矢量特性) 依赖画布尺寸,放大后可能模糊
交互支持 原生支持事件绑定(如 clickmouseover 需手动计算坐标实现交互
适用场景 图标、地图、可交互图表、动态 UI 元素 游戏、数据可视化、图像处理、动画

2. 技术细节对比

2.1 语法与结构

  • SVG

    1
    2
    3
    <svg width="200" height="200">
    <circle cx="100" cy="100" r="50" fill="red" onclick="alert('clicked!')" />
    </svg>
    • 通过 XML 标签定义图形,支持 CSS 和 JavaScript 操作。
  • Canvas

    1
    <canvas id="myCanvas" width="200" height="200"></canvas>
    1
    2
    3
    4
    5
    const ctx = document.getElementById('myCanvas').getContext('2d');
    ctx.fillStyle = 'red';
    ctx.beginPath();
    ctx.arc(100, 100, 50, 0, Math.PI * 2);
    ctx.fill();
    • 完全依赖 JavaScript API 绘制,无内置图形对象。

2.2 性能

场景 SVG Canvas
静态图形 较高(浏览器优化渲染) 极高(直接操作像素)
动态更新 较差(频繁 DOM 操作成本高) 极佳(适合高频重绘,如游戏)
图形复杂度 适合简单或中等复杂度图形 适合高复杂度或大量图形(如粒子效果)

2.3 功能对比

功能 SVG Canvas
文本渲染 完美支持(可选中、SEO 友好) 需手动绘制,不支持文本选择
动画 通过 CSS/JS 或 SMIL 实现 需手动控制每一帧(如 requestAnimationFrame
图像处理 仅支持基础滤镜(如模糊、阴影) 支持像素级操作(如 getImageData
响应式适配 自动缩放(矢量特性) 需监听窗口事件并重绘

3. 选择建议

优先使用 SVG 的场景

  • 需要 矢量缩放(如图标、Logo)。
  • 需要 交互事件(如可点击的地图区域)。
  • 图形复杂度较低且需与 DOM 协同(如动态图表)。

优先使用 Canvas 的场景

  • 高频更新(如游戏、实时数据可视化)。
  • 大量图形渲染(如粒子系统、复杂动画)。
  • 需要像素级操作(如图像编辑器、滤镜效果)。

4. 代码示例对比

示例1:绘制一个可交互的圆形

  • SVG(直接绑定事件):

    1
    2
    3
    4
    <svg width="200" height="200">
    <circle cx="100" cy="100" r="50" fill="blue"
    onclick="this.setAttribute('fill', 'red')" />
    </svg>
  • Canvas(需手动计算点击区域):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    const canvas = document.getElementById('myCanvas');
    canvas.addEventListener('click', (e) => {
    const rect = canvas.getBoundingClientRect();
    const x = e.clientX - rect.left, y = e.clientY - rect.top;
    const ctx = canvas.getContext('2d');
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = 'blue';
    ctx.beginPath();
    ctx.arc(100, 100, 50, 0, Math.PI * 2);
    if (ctx.isPointInPath(x, y)) {
    ctx.fillStyle = 'red';
    }
    ctx.fill();
    });

5. 结合使用

实际项目中可混合使用两者:

  • Canvas 为主:处理高性能渲染(如游戏背景)。
  • SVG 覆盖:添加可交互的 UI 元素(如按钮、提示框)。

总结

维度 SVG Canvas
图形类型 矢量 位图
交互性 原生支持 需手动实现
性能 适合静态或低频更新 适合高频动态渲染
复杂度 适合中小规模图形 适合大规模或像素级操作
学习曲线 简单(类似 HTML) 较高(需掌握绘图 API)

根据需求选择技术,或结合两者优势实现复杂应用!