Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

流的破坏与保护 #28

Open
xiongshj opened this issue Apr 24, 2021 · 0 comments
Open

流的破坏与保护 #28

xiongshj opened this issue Apr 24, 2021 · 0 comments

Comments

@xiongshj
Copy link
Owner

流的破坏与保护

这是学习《CSS 世界》第 6 章的笔记。

魔鬼属性 float

text-align 和 vertical-align 对块级元素无效。

float 会把元素块状化。

float 的天然克星 clear

clear 属性只有块级元素才有效。

CSS 世界的结界——BFC

BFC 全称为 block formatting context,中文为“块级格式化上下文”。相对应的还有 IFC,也就是 inline formatting context,中文为“内联格式化上下文”。

如果一个元素具有 BFC,内部子元素不会影响到外部的元素。所以,BFC 元素是不可能发生 margin 重叠的,因为 margin 重叠是会影响外面的元素的;BFC 元素也可以用来清除浮动的影响,因为如果不清除,子元素浮动则父元素高度塌陷,必然会影响后面元素布局和定位,这显然有违 BFC 元素的子元素不会影响外部元素的设定。

常见触发 BFC 的情况:

  • 根元素;
  • float 的值不为 none;
  • overflow 的值为 auto、scroll 或 hidden;
  • display 的值为 table-cell、table-caption 和 inline-block 中的任何一个;
  • position 的值不为 relative 和 static。

换言之,只要元素符合上面任意一个条件,就无须使用 clear: both 属性去清除浮动的影响了。

BFC 的表现原则,具有 BFC 特性的元素的子元素不会受外部元素的影响,也不会影响外部元素。

BFC 声明家族能担任自适应布局重任的:

  • overflow: auto/hidden,适用于 IE7 及以上版本浏览器;
  • display: inline-block,适用于 IE6 和 IE7;
  • display: table-cell,适用于 IE8 及以上版本浏览器。

最后,我们可以提炼出两套 IE7 及以上版本浏览器适配的自适应解决方案。

  • 借助 overflow 属性,如下:
.lbf-content {
  overflow: hidden;
}
  • 融合 display: table-cell 和 display: inline-block,如下:
.lbf-content {
  display: tabel-cell;
  width: 9999px;
  /* 如果不需要兼容 IE7,下面样式可以省略 */
  display: inline-block;
  width: auto;
}

最佳结界 overflow

要想彻底清除浮动的影响,最适合的属性不是 clear 而是 overflow。一般使用 overflow: hidden,利用 BFC 的“结界”特性彻底解决浮动对外部或兄弟元素的影响。

overflow 支持的属性值:

  • visible:默认值。
  • hidden:剪裁。
  • scroll:滚动条区域一直在。
  • auto:不足以滚动时没有滚动条,可以滚动时滚动条出现。

如果 overflow-x 和 overflow-y 属性中的一个值设置为 visible 而另外一个设置为 scroll、auto 或 hidden,则 visible 的样式表现会如同 auto。但是,scroll、auto 和 hidden 这 3 个属性值是可以共存的。

在 PC 端,无论是什么浏览器,默认滚动条均来自 <html>,而不是 <body> 标签。所以,如果我们想要去除页面默认滚动条,只需要 html { overflow: hidden; }。这个规则只对 PC 端有效,对于移动端并不一定适用。例如,在 PC 端,对 <html> 标签设置 overflow: hidden 可以隐藏滚动条禁止滚动,但是在移动端基本上无效。在 PC 端,窗体滚动高度可以使用 document.documentElement.scrollTop 获取,但是在移动端,可能就要使用 document.body.scrollTop 获取。

滚动条会占用容器的可用宽度或高度。

单行文字溢出点点点效果:

.ell {
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}

对 -webkit- 私有前缀支持良好的浏览器还可以实现多行文字打点效果,但是却无须依赖 overflow: hidden。比如,最多显示 2 行内容,再多就打点的核心 CSS 代码如下:

.ell-rows-2 {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

实现返回顶部效果:

<a href="#">返回顶部</a>

overflow: hidden 元素依然可以滚动。

float 的兄弟 position: absolute

<span> 元素默认是 inline 水平,但是一旦设置 position: absolute,其 display 计算值就变成了 block

“包含块” 计算规则,具体如下(不常用的未列出):

  1. 根元素(很多场景下可以看成是<html>)被称为“初始包含块”,其尺寸等同于浏览器可视窗口大小。
  2. 对于其他元素,如果该元素的 positionrelative 或者 static,则“包含块”由其最近的块容器祖先盒的 content box 边界形成。
  3. 如果元素 positin: fixed,则“包含块”是“初始包含块”。
  4. 如果元素 position: absolute,则“包含块”由最近的 position 不为 static 的祖先元素建立,具体方式如下:如果该祖先元素是纯 inline 元素,则规则略复杂:
  • 假设给内联元素的前后各生成一个宽度为 0 的内联盒子(inline box),则这两个内联盒子的 padding box 外面的包围盒就是内联元素的“包含块”;
  • 如果该内联元素被跨行分割了,那么“包含块”是未定义的,也就是 CSS2.1 规范并没有明确定义,浏览器自行发挥。

否则,“包含块”由该祖先的 padding box 边界形成。

如果没有符合条件的祖先元素,则 “包含块”是“初始包含块”。

可以看到,和常规元素相比,absolute 绝对定位元素的“包含块”有以下 3 个明显差异:

  1. 内联元素也可以作为“包含块”所在的元素;
  2. “包含块”所在的元素不是父级元素,而是最近的 position 不为 static 的祖先元素或根元素;
  3. 边界是 padding box 而不是 content box。

具有相对特性的无依赖 absolute 绝对定位

即使写了很多年 CSS 代码的人也可能会错误地回答下面这个问题:一个绝对定位元素,没有任何 left/top/right/bottom 属性设置,并且其祖先元素全部都是非定位元素,其位置在哪里?

很多人都认为是在浏览器窗口左上方。实际上,还是当前位置,不是在浏览器左上方。

这是关于 absolute 绝对定位最典型的错误认知。正是这种错误认知导致凡是使用 absolute 绝对定位的地方,一定父容器 position: relative,同时 left/top 等属性定位,甚至必同时使用 z-index 属性设置层级。

这是非常严重的认知和使用错误!

请牢记下面这句话:absolute 是非常独立的 CSS 属性值,其样式和行为表现不依赖其他任何 CSS 属性就可以完成。

实现在文字右上方增加小图标:

.icon-hot {
  position: absolute;
  margin: -6px 0 0 2px;
  width: 28px;
  height: 11px;
  background: url(hot.gif);
}

一个简简单单的 position: absolute,然后通过 margin 属性进行定位,效果即达成,包括 IE6 在内的浏览器都是兼容良好的。

同样是 position: absolute,通过简单的 margin 偏移实现。此方法兼容性很好,与 inline-block 对齐相比的好处在于,inline-block 对齐最终行框高度并不是 20px,因为中文下沉,图标居中,要想视觉上水平,图标 vertical-align 对齐要比实际低一点儿,这就会导致最终整个行框的高度并不是预期的 20px,而是 21px 或者更大。但是,如果使用“无依赖绝对定位”实现,则完全不必要担心这一问题,因为绝对定位元素不会改变正常流的尺寸空间,就算我们的图标有 30px 大小,行框高度依然是纯文本所在的 20px 高度。

absolute 的流体特性

<div> 之类的普通块级元素拥有流体特性。实际上,绝对定位元素也具有类似的流体特性,当然,不是默认就有的,而是在一定条件下才具有,这个条件就是“对立方向同时发生定位的时候”。

left/top/right/bottom 是具有定位特性元素专用的 CSS 属性,其中 left 和 right 属于水平对立定位方向,而 top 和 bottom 属于垂直对立定位方向。

当一个绝对定位元素,其对立定位方向属性同时有具体定位数值的时候,流体特性就发生了。例如:

.box {
  position: absolute;
  left: 0;
  right: 0;
}

如果只有 left 属性或者只有 right 属性,则由于包裹性,此时 .box 宽度是 0。但是在本例中,由于 left 和 right 同时存在,所以宽度就不是 0,而是表现为“格式化宽度”,宽度大小自适应于 .box 包含块的 padding box,也就是说,如果包含块 padding box 宽度发生变化,.box 的宽度也会跟着一起变。

position: relative

relative 的定位有两大特性:一是相对自身;二是无侵入。

“无侵入”的意思是,当 relative 进行偏移定位的时候,一般情况下不会影响周围元素的布局。

relative 的定位还有另外两点值得一提:相对定位元素的 left/top/right/bottom 的百分比值是相对于包含块计算的,而不是自身。注意,虽然定位位移是相对自身,但是百分比值的计算不是。

当相对定位元素同时应用对立方向定位值得时候,也就是 top/bottom 和 left/right 同时使用的时候,只有一个方向的定位属性会起作用(哪个方向生效与文档流的顺序有关,默认的是 top 和 left 生效)。

position: fixed 固定定位

position: fixed 固定定位元素的“包含块”是根元素,我们可以将其近似看成 <html> 元素。

蒙层弹窗是网页中常见的交互,其中黑色半透明全屏覆盖的蒙层基本上都是使用 position: fixed 定位实现的。

小结

昨天是世界读书日,买了一本书,叫《牧羊少年奇幻之旅》,上面有句话“当你想要某种东西时,整个宇宙会合力助你实现愿望”。

所以,加油吧。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant