CSS Review
I KNOW CSS
Layout & Drawing
浮动 Float
最初引入 float 属性:实现文字环绕和首字下沉。MDN
浮动元素会被移出正常文档流,后续元素会显示在其下层。若不想让剩余元素也受到浮动元素的影响,那么需要清除浮动。
-
额外标签法 => 浮动元素后添加设置了属性
clear:both;
的空标签 -
将包裹元素的 overflow 属性设置为除 visible 外的其他值
-
使用 after 伪元素清除浮动
-
双伪元素清除浮动 => 无内容;创建块格式化上下文;指定 clear 属性
.clearfix:after,.clearfix:before{ content: ""; display: flex|table|...; }
.clearfix:after{ clear: both; }
.clearfix{ *zoom: 1; }
/* 样式模块 */
.parent{ width: 400px;border: 1px solid #424242; }
.left{ width: 200px;height: 200px;background: #00B26A;float: left; }
.leftt{ width: 120px;height: 120px;background: #06B4FE;float: right; }
.footer{ width: 900px;height: 100px;background: darkslateblue; }
<!-- 模板模块 -->
<div class="parent">
<div class="left">left</div>
<div class="leftt">leftt</div>
</div>
额外标签法也称为隔墙法,具体是指在浮动元素的末尾添加一个空标签,并设置上属性 clear:both
。不足之处在于引入了无意义的内容。
外层元素通过设置属性 overflow:hidden
产生的 BFC 无法解决需要显示溢出元素的需求。
/* 修改parent样式;此处overflow必须为hidden */
.parent{ width: 400px;border: 1px solid #424242;overflow: hidden; }
属性 overflow:hidden
作用:溢出隐藏、清除浮动、解决外边距塌陷等。
外边距塌陷也称为外边距合并:两个相邻(兄弟或父子关系)的块级元素外边距组合在了一起。只有上下外边距才会有塌陷,左右外边距不会出现这种问题。
.big{ width: 200px;height: 200px;background: #00B26A;overflow: hidden; }
.small{ width: 120px;height: 120px;background: #35393b;margin-top: 30px; }
<div class="big">
<div class="small"></div>
</div>
after 伪元素方式:语义化较好,符合闭合浮动思想,存在兼容问题,需 zoom:1 触发 hasLayout。
/* 伪元素是行内元素 */
.clearfix:after{ display: block; clear:both; visibility: hidden; content: ""; }
.clearfix{ *zoom: 1; }
BFC
There are different types of formatting contexts. Notable among them are Block Formatting Context, Inline Formatting Context, Flex Formatting Context & Grid Formatting Context.
块格式化上下文是一个独立的渲染区域,该区域容器里的子元素不会在布局上影响外部的元素。
block-level boxes 和 blocks containing boxes 的交集在广义上称为 block boxes。
可通过设置部分属性在 box 内部创造一个 formatting context 的环境给后代元素。
布局规则:
- 内部 box 在垂直方向逐个排列
- box 垂直方向的距离由 margin 决定
- 同属一个 BFC 的两个相邻 box 的 margin 会发生重叠,即使存在浮动
- BFC 区域不会与 float box 重叠
- 浮动元素的高度参与 BFC 的高度计算
触发条件:
- 根元素
<html>
- float 值非 none
- overflow 值非 visible
- display 取值 table、grid、flex,inline-...、table-...
- position 取值 absolute、fixed
- ...
作用场景:
- 清除浮动
- 解决因非 BFC 容器却包含了浮动元素所导致的高度塌陷
- 自适应两栏布局:一边定宽 float,一边适应 overflow(产生 BFC)
- 阻止外边距重叠:添加空内容且产生 BFC 的伪元素
/* 同时解决高度塌陷和外边距重叠 */
.clearfix::before, .clearfix::after{
content: "";
display: table;
clear: both;
}
水平垂直居中
水平居中可选策略:
margin: 0 auto
:通过 auto 自动占用可用空间text-align: center
:指定元素中的文本以何种方式开展水平对齐
垂直居中可选策略:
- 当内外元素的宽高已知时,可直接计算 margin
- relative 与 absolute 定位配合
margin: auto
*{ padding: 0;margin: 0; }
.box{ width: 300px; height: 300px; border: 3px solid #4e4e4e; position: relative; }
img{ width: 100px; height: 100px; position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; }
- relative 与 absolute 定位配合
transfrom: translate(-50%,-50%)
*{ padding: 0;margin: 0; }
.box{ width: 300px; height: 300px; border: 3px solid #4e4e4e; position: relative; }
img{ width: 100px; height: 100px; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); }
- 外层元素进行 flex 布局
*{ padding: 0;margin: 0; }
.box{ width: 300px; height: 300px; border: 3px solid #4e4e4e; display: flex; justify-content: center; align-items: center; }
img{ width: 100px; height: 100px; }
.supContainer{ display: flex }
.subContainer{ margin: auto auto auto auto; }
- 内层元素 margin 设置为
calc(50% - 内层元素宽/2) auto
*{ padding: 0;margin: 0; }
.box{ width: 300px; height: 300px; border: 3px solid #4e4e4e;}
.box div { height: 100px; width: 100px; background-color: red; margin: calc(50% - 50px) auto }
Animation
- animation
animation 是一个简写属性形式,由 animation-name,animation-duration,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,animation-fill-mode 和 animation-play-state 组成。
animation-name 指定应用的系列动画,每个名称代表一个由 @keyframes 定义的动画序列。
animation-duration 属性指定元素上的动画从开始到结束耗费时长。
animation-iteration-count 用以指定动画重复的次数,仅仅使用该属性就能使动画重复播放。在该例中,设该属性为 infinite 以使动画无限重复。
animation-timing-function 属性是动画的速度函数。这个属性使用贝塞尔曲线(Cubic Bezier)函数来生成或直接使用 ease、ease-in、ease-out 或 linear。
animation-direction 属性为 alternate 设置来回滑动。
- 通过 animation 实现一个圆弧运动的球体
CSS3 的 transfrom 过渡效果可以实现元素位移、旋转、缩放。结合 animation 属性,就可以实现元素的动画效果。
球体运动可拆分成 X 和 Y 轴两个运动,X 轴将以慢 —> 快这样的速度运动;而 Y 轴的方向是以快 —> 慢这样的速度运动(从斜率方面思考);结合两个轴的运动,实现弧线效果。
.box {
width: 400px;
height: 400px;
border: 5px solid #262626;
}
aside {
width: 20px;
height: 20px;
border: 1px solid #222;
animation: arc1 5s ease-in forwards;
}
/* 这个虚拟元素默认是行内元素 */
aside::after {
content: "";
display: block;
width: 20px;
height: 20px;
-webkit-border-radius: 20px;
-moz-border-radius: 20px;
border-radius: 20px;
background: #424242;
animation: arc2 5s ease-out forwards;
}
@keyframes arc1 {
to {
transform: translateX(380px);
}
}
@keyframes arc2 {
to {
transform: translateY(380px);
}
}
<div class="box">
<aside></aside>
</div>
常见绘制
半圆弧绘制 => 使用复合属性 border-radius:
width: 160px;
height: 80px;
background-color: transparent;
border-bottom-right-radius: 90px;
border-bottom-left-radius: 90px; /*增加了边框,圆角半径也要变化*/
border-left: 10px solid black; /*边框左边线*/
border-right: 10px solid black; /*边框右边线*/
border-bottom: 10px solid black; /*边框底边线*/
三角形绘制 => 宽高为零,三边透明:
width: 0;
height: 0;
border-left:100px solid transparent;
border-top:80px solid transparent;
border-right:40px solid transparent;
border-bottom:70px solid #424242;
圣杯布局(左右宽度固定,中间自适应且优先加载):
* { margin: 0; padding: 0; }
html, body { height: 100%; width: 100%; }
header { width: 100%; background-color: #06b4fe; }
/* 清除浮动塌陷 */
footer { width: 100%; background-color: #ff6c37; clear: both; }
.center, .left, .right { float: left; }
.wrapper { padding: 0 100px; }
.center { width: 100%; height: 100px; background-color: lightblue; }
.left { width: 100px; height: 100px; background-color: lightgreen; margin-left: -100%; position: relative; left: -100px; }
.right { width: 100px; height: 100px; background-color: yellow; margin-left: -100px; position: relative; right: -100px; }
<header>header</header>
<!-- 优先加载 -->
<div class="wrapper">
<div class="center">center</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
<footer>footer</footer>
双飞翼布局(可看作圣杯布局的优化版):
.main { width: 100%; float: left; }
.middle { background-color: lightblue; margin: 0 100px; }
.leftt { width: 100px; background-color: lightgreen; float: left; margin-left: -100%; }
.rightt { width: 100px; background-color: yellow; float: left; margin-left: -100px; }
.footer { clear: both; }
<div class="header">header</div>
<div class="main">
<div class="middle">middle</div>
</div>
<div class="leftt">leftt</div>
<div class="rightt">rightt</div>
<div class="footer">footer</div>
块内显示一行,超出显示省略号 & 块内显示两行或三行,超出显示省路号:
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
0.5px 边框常有单线和全框两种形式:
- border + border-image + linear-gradient
- 伪元素 + background-image
- 定位 + 伪元素 + transform:scale
auto
auto 的效果可区分为两种,自动占用可用空间或直接设置 0 px。
对于前者,通常用于实现水平居中的效果,但若使用不当则会出现与预期存在差异的情况。
/* 水平居中 */
margin: auto;
/* 左或右边距单独设置 auto 会导致该边距占据所有可用空间 => 使元素视觉向反方向偏移 */
margin-right: auto;
auto 在浮动,内联和绝对元素中不起作用,因为这些元素已经确定了布局。对应浮动和绝对定位,由于脱离标准文档流,而 auto 是针对文档流的元素,那么自然会失效;内联会导致元素因无法设置宽高,而 auto 无法自动占用空间而失效。
对于后者的情况,块元素的宽度通常占据其整个容器,那么 margin:auto
将被设置为 0px。此外,auto 在顶部和底部边距中总是计算为 0px,这也是 w3c 规范导致 auto 仅常见于实现水平居中而不用于垂直居中的原因。
当然,也会存在一定程度上受制于垂直页面流。页面大小总在高度方面增加,相对于页面本身而言,元素垂直居中于其容器并不一定会使其显示恒为居中。
Reflow & Repaint
回流必引起重绘,重绘不一定回流。点此。
文档流即是浏览器采用的流式布局 Flow Based Layout。
在 RenderTree 生成前,需先构建文档对象模型 DOM 和 CSS 对象模型 CSSOM。
重排|回流 Reflow
渲染树中元素尺寸、结构、属性的几何信息发生改变,导致浏览器重新渲染部分或全部文档。
触发重排|回流 => 视窗改变与首次渲染;添加删除和更新节点;display
属性的变更;伪类的激活与移除;查询属性和计算方法。
重绘 Repaint
页面中元素样式改变而不影响在文档流中的位置和布局时,浏览器会重新绘制此元素的外观样式。
visibility:hidden;
(仅隐藏内容,并未脱离文档流,继续占据页面的空间)color、background-color:...;
(仅颜色改变)
优化与避免
尽可能的将可能引起回流和重绘的操作放入特定队列,进行批量处理。具体实现可以考虑当任务数量或时间间隔达到指定阈值时,浏览器将队列清空,进行批处理。
样式上应尽量避免页面整体使用老旧的表格布局,以及多层内联的样式设置,和样式计算表达式。
脚本方面要避免频繁的操作样式,应批量重写 style 属性,或者将样式定义为 class 进行整体更改。也可考虑开辟 DocumentFragment 再添加于文档中。
<ul id="list"></ul>
var list = document.querySelector('#list')
var fruits = ['Apple', 'Orange', 'Banana', 'Melon']
var fragment = new DocumentFragment()
fruits.forEach(function (fruit) {
var li = document.createElement('li')
li.innerHTML = fruit
fragment.appendChild(li)
})
list.appendChild(fragment)
// Apple
// Orange
// Banana
// Melon
- 会引起元素或周围的元素位置变化则 reflow,如窗口、字体大小、元素位置改变...;不会引起位置变化,仅存在变色效果则 repaint。
- 回流性能消耗较重绘要高,因回流的影响也会冒泡作用于周边及父元素。
display:none;
因不占据物理空间,因此涉及了dom树的操作,所以会引起重绘和回流;visibility:hiden;
元素虽然不可见但是却占据物理空间,因此不影响dom树的改变,所以只会引起回流。
秋豪之末
使用空格分隔的类选择器是后代选择器,表示选择具有该类的元素及其后代元素;而无空格分隔的类选择器是并列选择器,要求在同一元素上同时具有这两个类才会生效。
7.5pt 即 10px,即 0.625em,通常会将浏览器的根元素 HTML 标签(<html>
)的字体大小(font-size
)设置为 62.5% 或 10px。在 CSS2.1 中,rem
的大小取决根元素的字体大小。如果同时在 <body>
和 <html>
元素上设置了 font-size
,rem
单位将参考 <html>
元素上的值。
结束
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议,转载请注明出处!