CSS 的那些坑
前言:
本篇目录 1.层叠上下文 2.合并外边距 3.CSS 渲染原理 4.清除浮动 5.关于定位的一些认知
预计阅读时间 20 分钟。以下代码示例可自行复制到 vscode 中尝试。
关于定位的一些认知
- 相对定位是相对于自身位置位移,但是所占据的空间还是原来的那个.
- 默认每一个 z-index 计算的值是 auto,auto 的值为 0,但是写 0 和 auto 是不一样的.
- absolute 相对于祖先元素最近的一个,即 position 不是 static. absolute 最好要配合两个位置 top/left 来写,否则某些浏览器可能会发生位置错乱的情况,
- position 是相对视口进行定位,fixed 和 transform(父级元素) 配合使用,会造成 fixed 使用,css 不正交.(手机上最好不用 fixed,因为有很多的 bug) 下面是代码实例,fixed 失效了.
<div class="container">
<div class="fixed">123</div>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
<p>12</p>
</div>
.fixed {
border: 1px solid black;
position: fixed;
left: 10px;
bottom: 10px;
background: green;
}
.container {
transform: scale(0.9);
}
层叠上下文
我认为层叠上下文是写 css 的时候经常遇到得问题,非常得重要.所以在此详细得记录下来.首要会介绍一下 div 的立体分层结构 层叠上下文也叫堆叠上下文,在 html 元素内部会开启一个默认的层叠上下文,html 是最底的元素(被遮盖),相当于房子的地基.本文中每一个层叠上下文比喻成一个新的小世界,mdn 介绍层叠上下文的网址developer.mozilla.org/zh-CN/docs/…
- 会创建层叠上下文的因素有:z-index 不为 auto 值为 absolute(绝对定位)或 relative(相对定位),flex,opacity/transform
- 如果你的元素定位了,那么图层会在上面。负的 z-index 在 background 下面 如图所示。
- 负的 z-index 逃不出层叠上下文小世界。
- 结论 :层叠上下文就是一个小世界,只有处在同一个小世界的 z-index 才可以互相比较
.container {
border: 1px solid black;
height: 200px;
background: white;
position: relative;
}
.a {
/* a和b标签是同级的,他们都是container的直接子元素,并且处于html标签的层叠上下文中 */
/* 因为这里开启一个小世界(层叠上下文)z-index为1 */
position: relative;
z-index: 1;
border: 1px solid red;
}
.a2 {
/* 那么这里的z-index 就是 1里面的10 他是比同级的b2 z-index5小的, 1.10<5 */
position: relative;
z-index: 10;
height: 50px;
width: 50px;
background: red;
}
.b2 {
position: relative;
z-index: 5;
height: 50px;
width: 50px;
/* 为了让a2和b2重叠看到谁在上面 */
top: -20px;
background: green;
}
<div class="container">
<div class="a">
<div class="a2">10</div>
</div>
<div class="b">
<div class="b2">5</div>
</div>
</div>
- 负的 z-index 逃不出层叠上下文里。
<div class="container">
<div class="demo"></div>
</div>
.container {
border: 1px solid black;
height: 200px;
background: rgba(255, 0, 255, 0.9);
/* 相对定位, z-index不是auto 创建了一个层叠上下文 */
position: relative;
z-index: 0;
}
.demo {
width: 100px;
height: 100px;
border: 1px solid red;
position: absolute;
/* 默认情况应该是在紫色背景下面,但是因为container创建了一个层叠上下文,所以红色背景跑上面了! */
z-index: -1;
background: red;
}
transition 和 anmation
transition 详细的 transition 请自行去 mdn 上搜索。 过渡动画注意事项:
- 过渡动画需要有起始
- 并不是所有属性都可以用过渡动画 display none=>block 无法过渡。一般改写成 visibility:hidden=>visible
2.1 visibility 和 display 区别 简单提一句,请注意 visibility: hidden 与 display: none 是不一样的。前者隐藏元素,但元素仍占据着布局空间(即将其渲染成一个空框),而后者 (display: none) 将元素从渲染树中完全移除,元素既不可见,也不是布局的组成部分。 anmation 详细的请自行 mdn 搜索 transition 和 anmation 的区别如下: transition 关注的是 CSS property 的变化,property 值和时间的关系是一个三次贝塞尔曲线。 animation 作用于元素本身而不是样式属性,可以使用关键帧的概念,应该说可以实现更自由的动画效果。 简单的情况选用 transition,自由一点或者复杂的可以用 animation。
CSS 渲染原理
下面简要概述了浏览器完成的步骤:
- 处理 HTML 标记并构建 DOM 树。
- 处理 CSS 标记并构建 CSSOM 树。
- 将 DOM 与 CSSOM 合并成一个渲染树(render tree)。
- 根据渲染树来布局 Layout,以计算每个节点的几何信息。 将各个节点绘制到屏幕上。
- paint 绘制(边框颜色,阴影等画出来)
- compose 合成(根据层叠关系展示画面)
二. 如何知道 css 哪个属性触发什么过程呢? csstriggers.com/
清除浮动 一定要在父级元素加上 clearfix,否则父级元素会没有高度. 下面是推荐写法
.clearfix::after {
content: "";
display: block;
clear: both;
}
.box-left {
/* width: 100px; */
border: 1px solid red;
float: left;
}
.box-right {
/* width: 100px; */
border: 1px solid red;
float: right;
}
.content {
border: 1px solid red;
}
<div class="clearfix content">
<div class="box-left">123</div>
<div class="box-right">123</div>
</div>
合并外边距
- 同级的 margin-top 和 margin-bottom 会合并。 如果不想合并,可以将 dispaly 设置为 inline-block,width:100%.
- 直接子元素的第一个元素和最后一个元素的 margin-top/bottom 会合并。父元素会重叠,谁长显示谁,只有上下会重叠,左右不重叠。