为了账号安全,请及时绑定邮箱和手机立即绑定

CSS 对象模型与规则匹配

CSS 对象模型

DOM 树建立之后,CSS 编译器开始工作。整个过程与 HTML 编译过程基本一致:将 CSS 字符串经过词法、语法分析后,变成一组样式规则集合,也就是 CSSOM,称为 CSS 对象模型。

每一个内部样式表( style 标签内,包括 @import 引用 )、外部样式表( link 引用 )和 HTML 元素的内联 style 属性值都会单独生成一个 CSSOM。

CSSOM 是在 DOM 接口的基础上进行的扩展,因此 JavaScript 访问 CSSOM 需要通过 DOM 提供的接口去实现。例如,访问内部和外部样式规则,需要通过 document 上的 styleSheets 属性;访问内联 style 样式规则,需要通过 HTML 元素的 style 属性。

例子:

//省略了部分代码
<head>
    <style>
        div {
            background: #ccc;
        }
        
        p {
            color: #ff0000;
        }
    </style>
</head>

<body>
    <div>
        <p style="font-size:20px">hello</p>
    </div>
</body>

CSSOM 示意图( 图片仅供参考,并不完全准确 )

图片描述

CSSOM 在谷歌浏览器中的存在形式

图片描述

我们可以在谷歌浏览器的控制台上,直接操作 CSSOM:

//输入以下代码
document.styleSheets[0].rules[1].style.color="#fff";
document.getElementsByTagName("div")[0].style.backgroundColor="#ff0000";

图片描述

CSS 样式匹配

CSSOM 建立完成之后,渲染引擎将一直保存这个规则结果。然后,引擎开始为可视 DOM 节点(1)匹配合适的样式信息。匹配的过程可以大致分为以下 5 步:

*(1)可视 DOM 节点:DOM 节点中,例如 div、span、img 等节点,是用来展示页面内容的,因此称之为“ 可视节点 ”。与之相反的,head、meta 等节点,或者设置了 display:none 的节点,不会进入最终的布局与绘图环节,页面的最终显示结果,也不会有所体现,因此称这类节点为" 非可视节点 "。

  1. 首先,为节点创建 RenderStyle 对象,以保存所有匹配到的样式;
  2. 紧接着,开始匹配浏览器默认样式规则,依次按照 ID、className、标签名等选择器信息逐步匹配,如果匹配上该节点,则添加进 RenderStyle 对象;
  3. 然后,开始匹配内部和外部样式规则,依次按照 ID、className、标签名等选择器信息逐步匹配,如果匹配上该节点,则添加进 RenderStyle 对象;
  4. 再然后,将内联 style 样式规则添加进 RenderStyle 对象;
  5. 最后,渲染引擎对 RenderStyle 对象中的样式规则进行排序,并返回该对象。

例子:

//省略了部分代码
<head>
    <style>
        div {
            background: #ccc;
        }
        
        p {
            color: #ff0000;
        }
    </style>
</head>

<body>
    <div>
        <p style="font-size:20px">hello</p>
    </div>
</body>

上例中,我们打开谷歌浏览器,在开发者工具中,点击 P 元素,左边显示的就是该元素最终的匹配结果。

图片描述

选择器的权重

大多数情况下,同一个节点都会同时匹配到多个样式规则。那么,该节点应该使用哪些样式呢?
通常,渲染引擎会根据选择器的权重来判断,选择器描述的越具体,权重越高,下面介绍一些常用选择器的权重:

*下列选择器的权重依次递增

  1. 通配符
    该类选择器的权重为0。

  2. 标签选择器和伪元素
    该类选择器的权重为1。

  3. 类选择器、属性选择器和伪类
    该类选择器的权重为10。

  4. ID选择器
    该类选择器的权重为100。

  5. 内联样式
    可以覆盖任何由选择器匹配到的样式规则。

  6. !important 声明
    带有 !important 声明的样式将覆盖任何其他样式规则。

计算选择器的权重

1、每一种选择器类型的数值相加,应用选择器权重高的样式。

例子:

<style>
    /* 标签选择器 + 属性选择器 = 11 */
    p[class=text] {
        color: brown;
    }
    
    /* 类选择器 = 10 */
    .text {
        color: blue;
    }
</style>

<!-- p 元素应用 p[class=text] 中的样式 -->
<p class="text">hello</p>

2、选择器权重相等时,应用最后的那个选择器中的样式。

例子:

<style>
    /* 属性选择器 = 10 */
    [class=text] {
        color: brown;
    }

    /* 类选择器 = 10 */
    .text {
        color: blue;
    }
</style>

<!-- p 元素应用 .text 中的样式 -->
<p class="text">hello</p>

3、直接作用于元素的样式规则会覆盖继承而来的规则。

例子:

<style>
    #box {
        color: brown;
    }
    
    p {
        color: blue;
    }
</style>

<div id="box">
    <!-- p 元素应用 p 中的样式 -->
    <p>hello</p>
</div>

4、DOM 树中元素的距离对权重没有影响。

例子:

<style>
    #box p {
        color: brown;
    }
    
    #main p {
        color: blue;
    }
</style>

<div id="main">
    <div id="box">
        <!-- p 元素应用 #main p 中的样式 -->
        <p>hello</p>
    </div>
</div>

CSSOM View

除了我们上面讲的 CSS 对象模型,其实还有另外一种 CSS 模型,即 CSS 视图模型( CSSOM View )。它的基本含义是为 DOM 节点增加了一些可以访问视图方面的样式信息。扩展的这些属性有些还是很常用的,下面列举几个,具体使用方法和兼容性问题,可以自行查询。

Window 扩展

innerWidth 和 innerHeight
获取浏览器窗口视口的宽/高,包括滚动条。只读。

outerWidth 和 outerHeight
获取整个浏览器窗口的宽/高。只读。

pageXOffset 和 pageYOffset
获取整个页面水平/垂直滚动的像素值。只读。

screenX 和 screenY
获取浏览器窗口在显示器中水平/垂直位置。只读。

HTMLElement 扩展

clientLeft 和 clientTop
获取元素左/上边框的宽度。只读。

clientWidth 和 clientHeight
获取元素的内部宽/高,包括内边距,但不包括边框。只读。

offsetLeft 和 offsetTop
获取距离最近的拥有定位的父元素的左侧/上侧偏移量。只读。

offsetParent
获取距离最近的拥有定位的父元素。只读。

offsetWidth 和 offsetHeight
获取元素的宽/高,包括内边距和边框。只读。

scrollLeft 和 scrollTop
获取或设置元素距离左侧/上侧滚动的像素值。可读可写。

scrollWidth 和 scrollHeight
获取元素内部宽/高,包括由于溢出不可见的区域( 出现滚动条 )。只读。

MouseEvent 扩展

clientX 和 clientY
获取鼠标相对于浏览器窗口( window )的 X / Y 坐标。只读。

pageX 和 pageY
获取鼠标相对于文档( document )的 X / Y 坐标。只读。

screenX 和 screenY
获取鼠标相对于显示器的 X / Y 坐标。只读。


如有错误,欢迎指正,本人不胜感激。

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消