Published on

CSS-渲染逻辑

前言

我们在没有写任何 CSS 的情况下,不同的浏览器会有不同的默认样式,因此展示的效果会有差异。而这些样式叫做用户代理样式表(User Agent Stylesheet)。

所以在我们编写 CSS 前,需要清除一下用户代理样式表。

继承 Inheritance

加载 CodePen...

我们注意到 <p> 标签包裹了 <em> 标签,我们只给 <p> 设置了 color: red,但 <em> 也会被渲染成红色。答案就是 CSS 的 继承(inherit)。color 属性会继承到所有的子孙元素。

强制继承

有时候,我们希望一些属性可以继承父元素,我们就需要使用 inherit 关键字。例如以下的例子:

加载 CodePen...

按理说 <a> 标签的 color 属性应该继承父元素的 color 属性,但是结果呈现的不是我们想要看到的效果。为什么呢🧐?因为浏览器的用户代理样式表,把这个本该继承的属性覆盖了,现在的 <a> 标签的 color 属性的值是 -webkit-link

那我们想让 <a> 标签的 color 属性继承父元素的 color 属性,我们只需要在 CSS 中显式地设置 color: inherit 即可。

方向

许多 CSS 的机制和术语都继承自印刷排版领域。 对于横向阅读的语言,有两种放方向:

  • 块方向(Block Direction):从上到下,类似搭积木,是堆叠起来的。
  • 行方向(Inline Direction):从左到右,类似排队,是并排的。

盒子模型

组成盒子模型的是这四个属性:

  • 内容区域(Content):
  • 内边距(Padding):
  • 边框(Border):
  • 外边距(Margin):

可以通过 box-sizing 来控制盒子模型的计算方式。

  • content-box:宽度和高度只包括内容区域。
  • border-box:宽度和高度包括内容区域、内边距和边框。

Border vs. Outline

核心区别在于 outline 不影响布局。outline 有点更像 box-shadow;它是一种覆盖在元素上的装饰性效果,不会移动元素或改变其大小。

还有一点是,outline是堆叠在border之外的。

有关outline还有两点:

  • outline 会遵循 border-radius
  • 有一个特殊的 outline-offset 属性。它允许你在元素及其 outline 之间添加一点间隙。

对于以下 CSS 会导致键盘用户,无法知道当前是哪个按钮,如果使用,最好是设置:focus样式后再使用

button {
  outline: none;
}

外边距(Margin):

margin 可以想象成它可以控制人与人之间的距离。除此之外,它还可以有其他的一些有趣的用法: 水平居中,将元素移到父元素之外等等

它还要有一个塌陷的问题: 不过仅仅是在流式布局的算法中,且只有垂直方向上才会。

外边距旨在增加同级元素之间的距离。它不是为了增加子元素与其父元素边界框之间的间隙;那是内边距(padding)的作用。

外边距总是会尝试增加同级元素之间的距离,**即使这意味着将外边距“转移”到父元素上!**在这种情况下,效果就如同我们将外边距应用到父级一样。外边距必须是相互接触的,它们才会发生折叠。

负值

对于 borderpadding,他们是没有负值的,但是 margin 可以有负值。

负的margin值可以实现将元素移到父元素之外。要注意,改变margin值,不是针对改变所选元素的位置,实际上他是改变了元素之间的距离。 所以负的margin值,可能会将两个元素重叠。

同时,改变margin值,会影响所有同级元素的位置。

这里有一个小技巧:子元素的width设置为auto。同时设置负的margin值。可以实现即使父元素有padding值,子元素也可以达到父元素的边缘。

加载 CodePen...

需要明确一下:当widthauto时, 它的默认行为是尽可能的占据包含块的可用宽度。

auto

auto 值,它会尽可能的填充可用空间。他的工作方式和 width 的工作方式类似。当我们设置左右的外边距为 auto 时,他们会势均力敌,将可用空间平均分配,最终将元素水平居中。

有两个需要注意的点:

  • auto 值,只对水平方向有效
  • auto 值,只对块级元素有效,如果想要居中效果,元素的宽度必须明确。如果不明确块元素会自然的扩展到父元素的宽度。

Width

width属性,有两种类型的值,一种是有单位的,一种是关键字。

关键字

  • auto:尽可能的占据包含块的可用宽度,是动态可伸缩的(margin负值)。
  • max-content:以最大内容的宽度为准。
  • min-content:以最小内容的宽度为准。
  • fit-content:上述两种中间,超出宽度换行,没有超出不会占据全部宽度。

height

对于全屏,还是使用从 html元素-body元素 继承来的高度要舒服。因为 vh 单位对移动端不友好。

overflow

如果成为滚动元素(scroll,auto(只有超出时才会),hidden),子元素是一定不会超出父元素的。