CSS 基础
1、 BFC 简介
BFC 是 Block Formatting Context 的缩写,中文翻译为 块格式化上下文。它是 Web 页面 CSS 渲染的一部分,是块级盒子布局中产生的区域。你可以将 BFC 可以理解为一个容器,里面的元素不会影响到容器外的布局。
BFC 的特点:
- 内部元素不会影响外部元素: BFC 内部的元素不会溢出到 BFC 外部,也不会影响外部元素的布局。
- 相邻元素的 margin 会重叠: BFC 内部的相邻块级元素,它们的 margin 会在垂直方向上进行重叠。
- 包含浮动元素: BFC 可以包含浮动元素,并计算浮动元素的高度。
哪些元素是 BFC?:
- 根元素 (
<html>) - 设置了
overflow为hidden、scroll或auto的元素 - 绝对定位的元素 (
position: absolute) - 浮动元素 (
float: left、float: right或float: none) - Flexbox 布局容器 (
display: flex) - 网格布局容器 (
display: grid)
BFC 的应用:
- 清除浮动: BFC 最常见的用法就是清除元素内部的浮动。只要把父元素设为 BFC,就可以清理子元素的浮动了。最常见的做法就是在父元素上设置
overflow: hidden样式。 - 垂直对齐元素: BFC 可以用来垂直对齐元素。例如,可以使用 BFC 来垂直对齐两侧的图片。
- 制作响应式布局: BFC 可以用来制作响应式布局。例如,可以使用 BFC 来创建左右两栏布局,并使两栏在不同屏幕尺寸下保持宽度不变。
2、 居中为什么要使用 transform
transform 属于合成属性(composite property),对合成属性进行 transition/animation 动画将会创建一个合成层(composite layer),这使得被动画元素在一个独立的层中进行动画。通常情况下,浏览器会将一个层的内容先绘制进一个位图中,然后再作为纹理(texture)上传到 GPU,只要该层的内容不发生改变,就没必要进行重绘(repaint),浏览器会通过重新复合(recomposite)来形成一个新的帧。
top/left属于布局属性,该属性的变化会导致重排(reflow/relayout),所谓重排即指对这些节点以及受这些节点影响的其它节点,进行CSS计算->布局->重绘过程,浏览器需要为整个层进行重绘并重新上传到 GPU,造成了极大的性能开销。
3、 flex 布局
Flex布局的原理是将容器划分为两个轴:主轴和侧轴。主轴是子元素排列的方向,可以是水平方向或垂直方向。侧轴是垂直于主轴的方向。
4、 粘性布局
position 中的 sticky 值是 CSS3 新增的,设置了 sticky 值后,在屏幕范围(viewport)时该元素的位置并不受到定位影响(设置是top、left等属性无效),当该元素的位置将要移出偏移范围时,定位又会变成fixed,根据设置的left、top等属性成固定位置的效果。
sticky 属性值有以下几个特点:
- 该元素并不脱离文档流,仍然保留元素原本在文档流中的位置。
- 当元素在容器中被滚动超过指定的偏移值时,元素在容器内固定在指定位置。亦即如果你设置了top: 50px,那么在sticky元素到达距离相对定位的元素顶部50px的位置时固定,不再向上移动。
- 元素固定的相对偏移是相对于离它最近的具有滚动框的祖先元素,如果祖先元素都不可以滚动,那么是相对于viewport来计算元素的偏移量
5、 space-between 和 space-around
6、 transition 和 animation 的属性
CSS3 中的 transition 和 animation 都是用于创建动画效果的属性,但它们在使用方式和功能上存在一些差异。
6.1、 transition 属性
transition 属性用于指定元素在状态变化时如何平滑过渡。它可以控制以下四个方面:
- transition-property: 指定要添加过渡效果的 CSS 属性。默认值为 all,表示所有可以动画演示的属性都可以触发动画效果。
- transition-duration: 定义过渡效果花费的时间。默认值为 0。
- transition-timing-function: 指定动画的速度曲线。默认值为 ease。
- transition-delay: 指定动画开始之前的延迟时间。默认值为 0。
例如,以下代码将使元素在 0.5 秒内从蓝色过渡到红色:
.element {
transition: background-color 0.5s ease;
background-color: blue;
}
.element:hover {
background-color: red;
}
6.2、 animation 属性
animation 属性用于指定元素应该如何动画化。它包含以下子属性:
- animation-name: 指定要应用的动画的名称。
- animation-duration: 指定动画持续的时间。
- animation-timing-function: 指定动画的速度曲线。
- animation-delay: 指定动画开始之前的延迟时间。
- animation-iteration-count: 指定动画播放的次数。默认值为 1,表示播放一次。
- animation-direction: 指定动画的播放方向。默认值为 normal,表示正向播放。
- animation-fill-mode: 指定动画在播放前后如何保持状态。默认值为 none,表示保持初始状态或最终状态。
例如,以下代码将使元素在 1 秒内旋转 360 度:
.element {
animation-name: spin;
animation-duration: 1s;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
6.3、 区别
以下是 transition 和 animation 的主要区别:
- 应用场景:
transition通常用于元素状态变化时的隐式动画,例如鼠标悬停或元素获得焦点时。animation则用于更复杂的动画效果,例如旋转、缩放或移动元素。 - 控制力:
transition对动画效果的控制力较弱,只能控制过渡的持续时间、速度曲线和延迟时间。animation则可以更精细地控制动画的各个方面,例如关键帧、播放次数、播放方向和填充模式。 - 性能:
transition的性能通常优于animation,因为它只需要在元素状态变化时触发动画。animation则需要在动画播放期间不断更新元素的样式,因此可能会对性能造成影响。
在实际应用中,应根据具体需求选择合适的动画属性。如果只需要简单的过渡效果,可以使用 transition 属性。如果需要更复杂的动画效果,则可以使用 animation 属性。
7、 png8、png16、png32的区别
PNG图片主要有三个类型,分别为 PNG 8/ PNG 24 / PNG 32。
- PNG 8:PNG 8中的8,其实指的是8bits,相当于用2^8(2的8次方)大小来存储一张图片的颜色种类,2^8等于256,也就是说PNG 8能存储256种颜色,一张图片如果颜色种类很少,将它设置成PNG 8得图片类型是非常适合的。
- PNG 24:PNG 24中的24,相当于3乘以8 等于 24,就是用三个8bits分别去表示 R(红)、G(绿)、B(蓝)。R(0-255),G(0-255),B(0-255),可以表达256乘以256乘以256=16777216种颜色的图片,这样PNG 24就能比PNG 8表示色彩更丰富的图片。但是所占用的空间相对就更大了。
- PNG 32:PNG 32中的32,相当于PNG 24 加上 8bits的透明颜色通道,就相当于R(红)、G(绿)、B(蓝)、A(透明)。R(0255),G(0255),B(0255),A(0255)。比PNG 24多了一个A(透明),也就是说PNG 32能表示跟PNG 24一样多的色彩,并且还支持256种透明的颜色,能表示更加丰富的图片颜色类型。
PNG图片的压缩,分两个阶段:
预解析(Prediction):这个阶段就是对png图片进行一个预处理,处理后让它更方便后续的压缩。 压缩(Compression):执行Deflate压缩,该算法结合了 LZ77 算法和 Huffman 算法对图片进行编码。
8、 如何优化图片
- 对于很多装饰类图片,尽量不用图片,因为这类修饰图片完全可以用 CSS 去代替。
- 对于移动端来说,屏幕宽度就那么点,完全没有必要去加载原图浪费带宽。一般图片都用 CDN 加载,可以计算出适配屏幕的宽度,然后去请求相应裁剪好的图片。
- 小图使用 base64 格式
- 将多个图标文件整合到一张图片中(雪碧图)
- 选择正确的图片格式:
- 对于能够显示 WebP 格式的浏览器尽量使用 WebP 格式。因为 WebP 格式具有更好的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量,缺点就是兼容性并不好 小图使用 PNG,其实对于大部分图标这类图片,完全可以使用 SVG 代替
- 照片使用 JPEG
9、 中伪类和伪元素的区别
伪类示例:
:hover:鼠标悬停在元素上面时:link:未访问的链接:visited:已访问的链接:focus:元素获得焦点时:active:元素被激活时:first-child:元素是其父元素的第一个子元素:last-child:元素是其父元素的最后一个子元素:nth-child(n):元素是其父元素的第 n 个子元素
伪元素示例:
:before:在元素之前插入一个虚拟元素:after:在元素之后插入一个虚拟元素:first-line:元素的首行文本:first-letter:元素的第一个字母::selection:选中的文本::placeholder:输入框的占位符文本
10、 选择器
CSS 选择器用于指定要应用样式的HTML元素。根据选择器的类型和复杂程度,CSS 选择器具有不同的优先级。优先级决定了在多个选择器同时应用时哪个选择器生效。
10.1、 优先级
选择器类型的优先级是递增的:
- 类型选择器(例如,h1)和伪元素(例如,::before)
- 类选择器(例如,.example),属性选择器(例如,[type="radio"])和伪类(例如,:hover)
- ID 选择器(例如,#example)。
10.2、 选择器的类型
- 类型选择器:根据元素的类型选择元素,例如
h1、p、div等。 - ID 选择器:根据元素的 ID 选择元素,例如
#header、#footer等。 - 类选择器:根据元素的类选择元素,例如
.main、.nav等。 - 属性选择器:根据元素的属性选择元素,例如
a[href]、img[alt]等。 - 伪类选择器:根据元素的状态选择元素,例如
:hover、:link等。 - 伪元素选择器:选择元素的特定部分,例如
::before、::after等。 - 后代选择器:选择元素的所有后代元素,例如
div p、ul li等。 - 子代选择器:选择元素的直接子代元素,例如
div > p、ul > li等。 - 相邻兄弟选择器:选择元素的相邻兄弟元素,例如
p + span、li ~ ul等。 - 通用选择器:选择所有元素,例如
*。
10.3、 优先级计算
优先级 = a * 1000 + b * 100 + c * 10 + d
其中:
- a 是选择器中 ID 的数量。
- b 是选择器中类、属性和伪类的数量。
- c 是选择器中类型选择器和伪元素选择器的数量。
- d 是选择器在样式表中的位置。
例如,选择器 #header.main 的优先级计算如下:
优先级 = 1 * 1000 + 1 * 100 + 0 * 10 + 0 = 1100
选择器 div.content:hover 的优先级计算如下:
优先级 = 0 * 1000 + 1 * 100 + 1 * 10 + 1 = 111
特殊情况:
- !important 关键字可以强制提高选择器的优先级。
- 行内样式的优先级高于所有外部样式表的样式。
11、 属性继承
可继承的属性
- 文字相关属性: font-family、font-size、font-weight、font-style 等。
- 颜色属性: color、background-color。
- 文本相关属性: line-height、text-align、text-transform 等。
- 链接相关属性: text-decoration、link、visited、hover、active 等。
- 列表属性: list-style-type、list-style-image 等。
- 表格属性: border-collapse、border-spacing 等。
- 元素显示属性: display、visibility。
- 百分比属性: 某些属性(如 padding、margin)中的百分比值可以继承。
12、 grid 布局
网格布局(Grid)是最强大的 CSS 布局方案。
Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局。Grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局。Grid 布局远比 Flex 布局强大。
12.1、 示例
<style>
.box {
display: grid;
/* 指定了一个三行三列的网格,列宽和行高都是50px */
grid-template-columns: 50px 50px 50px;
grid-template-rows: 50px 50px 50px;
}
.item {
font-size: 2em;
text-align: center;
border: 1px solid #e5e4e9;
}
.item-1 {
background-color: #ef342a;
}
.item-2 {
background-color: #f68f26;
}
.item-3 {
background-color: #4ba946;
}
.item-4 {
background-color: #0376c2;
}
.item-5 {
background-color: #c077af;
}
.item-6 {
background-color: #f8d29d;
}
.item-7 {
background-color: #b5a87f;
}
.item-8 {
background-color: #d0e4a9;
}
.item-9 {
background-color: #4dc7ec;
}
</style>
<div class="box">
<div class="item item-1">1</div>
<div class="item item-2">2</div>
<div class="item item-3">3</div>
<div class="item item-4">4</div>
<div class="item item-5">5</div>
<div class="item item-6">6</div>
<div class="item item-7">7</div>
<div class="item item-8">8</div>
<div class="item item-9">9</div>
</div>
12.2、 repeat函数
.box {
display: grid;
grid-template-columns: repeat(3,1fr);
grid-template-rows: repeat(3, 50px);
}
使用repeat可以免去重复写3个50px
12.3、 固定一列宽度
.box {
display: grid;
grid-template-columns: 100px 1fr 1fr;
grid-template-rows: repeat(3, 50px);
}
12.4、 区间范围函数:minmax
.box {
display: grid;
grid-template-columns: minmax(300px, 1fr) 1fr 1fr;
grid-template-rows: repeat(3, 50px);
}
12.5、 独立设置单元格的范围
设置起始边界范围
.item-1 {
background-color: #ef342a;
grid-column-start: 1;
grid-column-end: 4;
}
也可以使用如下缩写
.item-1 {
background-color: #ef342a;
grid-column: 1 / 4;
}
12.6、 grid-area控制单元格范围
使用 grid-area 实现博客的经典布局
.box {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 1fr 3fr 1fr;
height: 100%;
grid-template-areas:
"h h h h h h h h h h h h"
"s s c c c c c c c c c c"
"f f f f f f f f f f f f";
}
.item {
font-size: 2em;
text-align: center;
border: 1px solid #333;
}
.item-1 {
background-color: #ef342a;
grid-area: h;
}
.item-2 {
background-color: #f68f26;
grid-area: s;
}
.item-3 {
background-color: #4ba946;
grid-area: c;
}
.item-4 {
background-color: #0376c2;
grid-area: f;
}
13、 Flex 弹性布局
- flex-shrink: 收缩因子。用法介绍