容易忽略的七个CSS知识点

若是你在平常工做中使用CSS,那么你的主要目标极可能集中在使事情看起来是正确的。最终获得的正确结果远好比何实现更重要。这意味着相比正确的语法和视觉效果咱们更少关注CSS的实现原理。css

你可能尚未意识到,但CSS的视觉效果一般是操纵隐藏属性的间接结果。一些CSS属性(如 background-color)和你看到的视觉效果就有显然的直接关系。而其余的(好比display)对咱们许多人来讲仍然含糊不清,由于结果彷佛高度依赖于上下文。web

我怀疑不少开发者都不能简单的描述当设置了display: block以后实际上作了什么。最多你可能只是直观地了解这个属性是如何工做的。不要紧,你能够在不了解基本原理的状况下,对CSS有很好的使用。虽然,你知道解决问题的方案,可是你却不必定真的了解问题。浏览器

对于许多人来讲,诸如盒子模型、级联和特殊性等概念是咱们所熟知的。虽然他们常常被曲解,可是知道这些工做原理有助于咱们编写更好的CSS。布局

正由于如此,我想试着揭示CSS的这些隐藏黑科技部分,只介绍涉及你须要知道的部分,并但愿以逻辑顺序解释该过程,以便你更好的理解CSS真正的工做原理。性能

渲染过程概述

当你加载一个HTML文档的时候,页面的渲染过程当中会按照顺序发生了不少事情。字体

第一步就是解析HTML文档。从这一步开始浏览器会生成一个“文档树”。树的结构是一种用HTML表明具备明显层次结构信息的方式。树中的元素能够用相似于家谱的方式描述,好比:后代节点、父节点、子孙节点和兄弟节点。flex

你可能据说过“DOM”这个术语。它表明“文档对象模型(Document Object Model)”。它是文档树结构的扩展,它被用来存储web文档内容和操做信息。网站

随着HTML被解析,样式文件和其余资源文件会被下载。样式声明经过一个称为级联的过程来解释和决定。spa

在此过程当中,将解析CSS属性的最终值。通过计算,这些值可能与咱们样式表中所写的值不一样。例如:像auto 这样的相对单位的关键字被赋予了真正的值,并会应用继承的值。这些计算好的值会像存储在DOM树中的元素同样被存储在一个树中,毫无疑问会被称为CSS对象模型(CSS Object Model )或CSSOM。代理

如今就能够开始渲染页面的过程了。这个过程当中的第一步是计算 盒模型。这一步对于计算出元素的大小和间距是很重要的,尽管可能并非最终的位置。

和 盒模型相比并非那么被熟知的过程叫作 视觉格式模型。此过程会肯定页面上元素的布局和位置。它包含您可能已经熟悉的一些概念,例如:定位方案(positioning schemes), 格式化上下文(formatting contexts), 显示模式(display modes), 和 堆叠上下文(stacking contexts)。

最终页面被渲染出来。

以上段落中可能有几个术语,您还不熟悉。若是是这样的话,最重要的是理解 级联, 盒模型, 和 视觉格式模型,理解这些术语是解释、处理和渲染HTML和CSS相当重要的一步。在描述上面每一个渲染过程的细节时,我跳过了不少的细节,因此接下来咱们更加仔细地看这三个步骤。

级联

级联多是CSS中最容易被弄错的属性之一。它指的是合并不一样样式表并解决CSS选择器之间冲突的过程。

级联查看声明的优先级、来源、特性和顺序,以肯定使用哪一种样式规则。

你须要知道什么:

大多数网站都有多种样式表。一般的样式是在页面中添加了一个引用css文件的link 标签,或者在HTML主体中使用 style 标签。即便最基本的页面也有由浏览器提供的默认样式。此默认样式表有时称为用户代理样式表(user-agent stylesheet)。

在级联过程当中样式表按如下顺序解释:

!important 声明

开发者编写的样式表

浏览器默认的样式表

注意事项: 我跳过了用户样式表,由于它已不是常见的了。

合并这些来源的样式以后,若是不少规则被用在了同一个元素上,则用权重肯定应用的规则。

特殊性

特殊性是指选择器的权重。仅仅把它看做一个单独的数字是一个常见的错误。实际上它是4个独立的数字或4种类别的权重。

计算特殊性,把下面的权重相加:

  1. ID,
  2. class, 属性 和 伪类,
  3. 元素 和 伪元素

例如: #nav .selected:hover > a::before 的权重分别是 1, 2, 2。

不管多少个class的权重,都没有ID的权重高。当比较选择器时,首先应该比较ID的权重大小。仅当ID的权重同样的时候,再比较class、属性和伪类的权重,最后,若是权重依然同样的话就比较元素和伪元素的权重。

若是每一个类别的权重都相等的话,则采用就近优先的原则(即应用来源中最后声明的规则)。

是的!我知道我说了4类的权重大小。可是行内样式的权重比ID的更高。尽管它们是技术上权重计算中的第一类,可是一般是没法和行内样式竞争的,因此,很容易记住行内样式老是高于其余类别的权重。

重要注意事项: !important 声明没有考虑权重计算,可是它们比级联中的正常声明具备更高的优先级。

继承

继承不是级联中的一部分,可是这里我把它包含进来主要是由于它常常和级联一块儿被讨论。

继承是应用于元素的值能够由其子元素传递(或继承)的过程。

您可能很熟悉字体属性(当应用于body或另外一个容器元素时)也由该容器内的每一个元素继承的事实。这就是继承。

并不是全部属性都默认继承。 了解继承是编写更加优雅和简洁CSS的关键。 使用inherit关键字强制继承是很是有用的。

注意事项: 某些属性如border-color 具备默认值currentcolor。 这意味着他们将使用color属性上设置的值。 这个默认值与继承不同。 虽然颜色属性自己一般是继承的。

盒模型

了解盒子模型对于限制使用布局和定位时的问题是必不可少的。 它是CSS中最基本的概念之一。

盒模型用于计算元素的宽和高。这是一个计算步骤,并不彻底被依赖于肯定元素的最终布局和定位。

你须要知道什么:

HTML的每个元素都是一个矩形的盒子。每一个盒子都有4个区域,用于定义元素的边距(margin)、边框(border)、填充(padding)和内容区域。

默认状况下,你给一个元素设置的宽度,只是设置了内容区域的宽度。当你给元素添加padding、border和margin时,这是增长了除了宽度以外的部分。实际上,这意味着宽度为50%的两个元素若是添加了padding,margin或border,则会超过100%的宽度,进而致使不能并排排版了。
图片描述

就是这样!这是至关简单的对吧?为何这经常是困惑的来源呢?好吧,你可能遇到过一些状况,事情彷佛有些不一样的表现…

填充区域

当你给一个元素设置背景的时候,填充的不只仅是内容区域,并且还包括内部padding区域和边框区域。
图片描述

从概念上来讲,咱们认为HTML元素是单一的东西。所以很容易认为元素的视觉边界等于其宽度,但状况并不是如此。尽管元素的视觉边界包括填充(padding)和边框(border)区域,width 属性明确地应用于内容区域上。

注意事项: 改变 box-sizing 属性能够改变这种表现行为。

动态宽度

另外一个潜在的困惑的来源是width: auto 是怎样工做的。一个自动的宽度对于大部分的HTML元素都是一个默认值,好比:div和p标签,auto 的宽度计算以便于margin、border、padding和内容区域合并以后可以适应可用的空间。

实际上,是从新计算宽度以确保一切都适合。 经过比较,设置宽度为“100%”时,无论边距、填充和边框的大小是多少,内容区域都将填充可用空间。
图片描述

Box-sizing

box-sizing属性可以改变盒模型的工做方式。当 box-sizing设置为border-box 时,padding和border将减小内容区域的内部宽度,而不是增长元素的总体宽度。这意味着一个元素的宽度如今与它的可视宽度相同。
图片描述
不少人喜欢这个属性,若是你正在创建一个网格系统,或任何其余须要水平对齐类型的布局项目,这能够更直观的工做方式。

边距重叠

当边距意外重叠的时候,真的使人很困惑,由于你不知道发生了什么。当两个或多个相邻的垂直边距接触时,边距有时会发生重叠,而且不会用填充或边框分隔。若是子元素的边缘扩展到父元素的边缘,而且不会被填充分隔开,那么就会出现边距重叠的现象。

若是元素采用的是绝对定位、浮动定位或者有一个不同的 格式化上下文时,边距不会发生重叠现象。

若是你感到困惑,不要紧。边距不会发生重叠的规则是复杂的。 您须要知道的主要事情是当元素没有填充或边框时,垂直边距可能会重叠。

视觉格式化模型

当盒模型计算元素的尺寸时,它是负责肯定这些盒布局的视觉格式模型。 视觉格式模型考虑了盒的类型、定位方案、元素之间的关系和由内容强加的约束,以肯定页面上每一个元素的最终位置和呈现。

你须要知道什么:

视觉格式模型遍历文档树,并按CSS盒模型生成一个或多个渲染元素所需的盒子。CSSdisplay 属性在决定元素如何参与当前的格式化上下文和定位方案中起着关键的做用。这些部分将决定元素的最终布局和位置。

这是一个复杂的步骤,是迄今为止最难尝试和总结的。若是你还不了解全部的关于这个部分的话,不要紧。理解咱们如何经过CSS属性操做 定位方案和格式化上下文是一个很好的开始。若是你能掌握这一模式的不一样部分之间的相互做用,你就会比大多数人作得更好。至少你应该知道它们是存在的。

显示类型

咱们知道在CSS中设置display 属性能够决定一个元素怎样被渲染,可是目前还不清楚它的工做原理是什么样的。事实上,有时甚至是不可预测的。

这是由于display 属性决定了元素的“盒类型”。该隐藏属性由内部显示类型和外部显示类型组成,这些类型一块儿帮助肯定元素的呈现方式。

外部显示类型一般解析为“block”或“inline”,而且几乎与CSS中的“display”属性的指望一致。 从技术上讲,外部显示类型决定了元素如何参与其父元素的格式化上下文。

内部显示类型肯定该元素将生成什么样的格式化上下文。 这将影响其子元素的布局。

想象一下Flexbox容器的工做原理。 它的外部类型是block,其内部类型是flex。 它的子元素外部类型也能够是block,但它们的布局受到Flexbox容器的格式上下文的影响。

格式化上下文

格式化上下文是关于布局的。 它们是管理容器内元素布局的规则,以及它们如何相互交互。

一些格式化上下文能够直接在容器上创建,例如经过使用display 的值为:flex、grid或table。 其余类型(如块和内联格式化上下文)按照浏览器的要求建立。

注意事项: 一度,由于它和浮动元素的交互方式,理解如何让浏览器创建一个新的块格式化上下文很是重要。一个块格式化上下文的元素会包含浮动的元素。

定位方案

一个盒元素能够根据3种定位方案中的一种来布局。这三种方案分别是:正常文档流布局, 浮动布局 和 绝对定位布局。您可能熟悉浮动和绝对定位布局的方式,由于咱们在编写CSS时常常与这些方案进行交互。 当一个元素未浮动或绝对定位布局时,就是正常文档流布局。

正常文档流布局
正常文档流描述了默认的定位方案,“in-flow”描述符合此要求的元素。 在文档流中您能够认为是根据其源的顺序和格式化上下文布局的元素的天然位置。

浮动布局
Float(浮动)是一个CSS属性,它使一个元素从正常流中跳出来,并尽量地向左或向右偏移,直到它接触到其上一级的盒元素或另外一个浮动元素的边缘。 当这种状况发生时,文本和内联元素将包围浮动元素。

一般若是不设置,元素的高度将适应其全部后代元素。 当元素浮动时,它们从正常文档流跳出来,这意味着容器不会调整其高度以将其清除。

正是这种行为容许多种文本、标题和其余元素对浮动内容进行流式包裹。但有时这是有问题的。清除浮动和创建一个新的块格式化上下文将使容器清除其浮动的子元素。这种技术容许使用浮动来进行布局,好久以前这就已经成为web开发技术之一了。这种技术仍然很重要,但它也正逐渐被新的布局技术所取代,好比Flexbox和Grid。

绝对定位布局
绝对定位的元素彻底从文档流中去除,不一样于浮动元素,它们对周围的内容没有影响。

具备相对定位的容器容许您使用绝对定位来控制后代元素的偏移量。

相对定位的元素也能够被给定一个偏移量,可是这个偏移量是与元素的正常位置相对的,而不是另外一个相对的容器。

CSS的top, bottom, left 和 right 属性用来计算“盒容器的偏移量”。这些属性不是二维偏移,而是每一个边缘相对于其容器的内容盒子进行定位。

具备重叠偏移的定位元素能够致使元素占用相同空间而发生重叠问题。堆叠上下文能够解决这个问题。

层叠上下文

堆叠上下文决定事物呈现到页面的顺序。 你能够想象一个堆叠上下文,如图层。 堆叠底部的图层首先绘制,堆叠上方的元素出如今顶部(相对于底部来讲是在上层)。

在一个绝对或相对定位的元素上设置z-index 是创建新的堆叠上下文的最多见方式。 可是还有其余一些方法能够造成堆叠上下文,包括设置不透明度(opacity),转换(transforms),过滤(filters)或使用will-change属性。

其中的一些缘由并不直观,与开发人员的预期相比,更多的是与渲染的性能有关。这有助于理解这些层能够由浏览器单独渲染。所以,出于性能考虑,故意建立一个新的堆栈上下文有时会颇有用。

除非创建了堆叠上下文,否则设置z-index没有效果。 z-index的值设置的越高,层叠放置的堆叠越高(越靠近被最终显示的上层)。

关于堆叠最使人困惑的部分之一是能够在现有堆叠环境中创建新的堆叠上下文。 这意味着您能够拥有多层图层。

在这种状况下,并不老是拥有最高的z-index值显示在堆叠越高的位置。

总结

简短地介绍一些CSS的重要的不为人熟知的工做原理部分。若是你只是读了其中的一部分也不要紧。但愿这篇文章澄清了一些事情,或者对所涉及的过程有了一个大体的说明。在不牺牲精确性的状况下,用简单的术语解释这些东西是一个真正的挑战。
图片描述

相关文章
相关标签/搜索