本文主要讨论7大CSS知识点,个个都是金刚附体,干货满满:
1、移动端样式适配
2、回流和重绘
3、flex布局
4、BFC
5、CSS垂直居中方法
6、CSS两栏、三栏自适应布局
7、CSS单行、多行文本溢出省略号格式
一、如何做到移动端样式适配
1、媒体查询Media Queries–响应式设计
@media screen and (max-width: 600px) {
/*在小屏幕上的样式*/
}
@media screen and (min-width: 601px) and (max-width: 1024px) {
/*在中等屏幕上的样式*/
}
@media screen and (min-width: 1025px) {
/*在大屏幕上的样式*/
}
2、弹性布局flex
使用弹性布局和网格布局可以更好的灵活布局,使页面元素可以根据屏幕大小自动调整位置
.container {
display: flex;
flex-wrap: wrap
}
.item {
flex: 1;
}
3、移动端优先
先定义移动端样式,再使用媒体查询逐渐添加大屏上的样式,确保基本功能在小屏幕上也能正常工作。
/*移动端样式*/
body {
font-size:14px;
}
/*大屏幕样式*/
@media screen and (max-width: 768px) {
body {
font-size: 16px;
}
}
4、图片多媒体适配
- 使用max-width: 100%确保图片和多媒体在小屏幕上不会溢出容器
- 使用picture元素或srcset属性提供不同尺寸的图片
img {
max-width : 100%;
height: auto;
}
5、交互友好
使用合适的尺寸和间距,确保链接、按钮等可点击元素在触摸屏幕上易于点击。
a, button {
padding: 10px;
}
二、回流和重绘
1、定义
回流一定会引起重绘,而重绘不一定会引起回流。频繁的回流和重绘会导致页面性能下降,影响用户体验。
- 回流:布局引擎根据各种样式计算每个盒子在页面上的大小和位置
- 重绘:当计算好盒模型位置、大小和其他属性后,浏览器会根据每个盒子特性进行绘制
- 解析Html生成Dom树,解析CSS,生成CSSDOM树
- 将Dom树和CSSDOM树结合,生成渲染树(Render Tree)
- Layout(回流):根据渲染树进行回流,得到节点几何位置
- Painting(重绘):根据渲染树以及回流得到的几何位置,得到节点的绝对像素
- Display:将像素发给GPU, 展示在页面上
2、触发时机
2.1 回流触发时机
- 添加删除DOM元素
- 元素位置改变
- 元素尺寸改变
- 页面一开始渲染时不可避免的回流
- 浏览器窗口尺寸改变
2.2 重绘触发时机
- 颜色修改
- 文本方向改变
- 阴影修改
3、浏览器优化机制
由于每次重排都会造成额外的计算消耗,因此浏览器通过队列化修改并批量执行来优化重排过程。
浏览器会将修改操作放入队列中,直到达到一定阈值,才清空队列。
4、如何减少回流重绘
- 如果想设定元素样式,通过改变元素的class类名
比如下面的多次样式修改,每次样式修改都会触发回流重绘
const container = document.getElementById('container');
container.style.width = '100px';
container.style.height = '100px';
container.style.color = 'red';
我们修改的方法就是将多次的样式修改放到class内,一次性添加
<style>
.basic {
width: 100px;
height: 100px;
color: red;
}
</style>
<stript>
const container = document.getElementById('container');
container.classList.add('basic')
</stript>
- 复杂的动画,使用position设置为fixed或者absolute,尽可能使元素脱离文档流,从而减少对其他元素的影响
- 避免使用table布局,table中每个元素大小以及内容改动,都会导致整个table重新计算
- 避免使用css的js表达式
- 使用css3硬件加速,可以使transform、opacity、filters这些动画不会引起回流重绘
三、flex布局
flex弹性布局
- 采用flex布局的元素,称为flex容易container
- 所有子元素成为容器成员,称为container的item
1、使用场景
- 等高的多列布局
- 水平和垂直居中
- 自适应布局
- 等间距分布:使用flexbox的justify-content和align-items属性,在容器中创建等间距布局
- 响应式布局
2、属性
- flex-direction
- flex-wrap
- flex-flow
- justify-content
- align-items
- align-content
2.1 flex-direction
定义主轴上排列方向
- row: 从左到右 默认属性
- column: 从上到下
- row-reserve:从右到左
- column-reserve: 从下到上
2.2 flex-wrap
容器内是否换行
- wrap: 换行
- no-wrap: 不换行 默认属性
- wrap-reserve: 换行且第一行在下面
默认情况下就是no-wrap: 不换行,但是不会让元素超出容器,元素会弹性伸缩:
如果每个元素设置了min-height和min-width, 默认和nowrap就会超过容器:
3、flex-flow
这个属性是flex-direction
和flex-wrap
的属性简写形式,默认是row nowrap
.box {
flex-flow: <flex-direction> || <flex-wrap>
}
4、justify-content
定义主轴上对齐方式
- flex-start:左对齐 默认属性
- flex-end:右对齐
- center:居中
- space-between:两端对齐,item之间间隔相等
- space-around:两个项目两侧间隔相等
5、aligh-items
定义交叉轴上(y轴)对齐方式
- stretch:如果没设置高度或设为auto,将占满整个容器 默认属性
- flex-start:y轴开始位置对齐
- flex-end:y轴终点对齐
- center:y轴中间对齐
- baseline:项目第一行文字的基线对齐
3、item属性
以下6个属性设置在项目上。
- order
- flex-grow
- flex-shrink
- flex-basis
- flex
- align-self
3.1 order
order属性定义项目的排列顺序
数值越小,排列越靠前,默认为0。
.item {
order: <integer>;
}
3.2 flex-grow属性
flex-grow等比分配剩余空间
flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
.item {
flex-grow: <number>; /* default 0 */
}
如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
3.3 flex-shrink属性
flex-shrink等比缩小
flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
.item {
flex-shrink: <number>; /* default 1 */
}
如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。
负值对该属性无效。
3.4 flex-basis属性
flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
.item {
flex-basis: <length> | auto; /* default auto */
}
它可以设为跟width
或height
属性一样的值(比如350px),则项目将占据固定
空间。
如果flex-basis
设置值为0%
,表示项目的初始大小为 0
,然后根据flex-grow
和flex-shrink
来确定最终大小。
3.5 flex属性
flex属性是flex-grow
, flex-shrink
和 flex-basis的简写,默认值为0 1 auto
。后两个属性可选。
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。
建议优先使用
这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。
flex:1代表什么?
- flex: 1 = flex: 1 1 0%
- flex: 2 = flex: 2 1 0%
- flex: auto = flex: 1 1 auto
- flex: none = flex: 0 0 auto
在 CSS 中,flex: 1
是一个用于弹性布局(Flexbox)的属性值组合。它由三个部分组成:flex-grow
、flex-shrink
和flex-basis
。
-
flex-grow
:- 定义了弹性项目的增长因子。当弹性容器有剩余空间时,具有
flex-grow
值大于 0 的项目会按比例扩展以填充剩余空间。 flex: 1
中的flex-grow
值为 1,表示当有剩余空间时,该项目会与其他设置了flex-grow
为正整数的项目一起,按比例增长来占据剩余空间。
- 定义了弹性项目的增长因子。当弹性容器有剩余空间时,具有
-
flex-shrink
:- 定义了弹性项目的收缩因子。当弹性容器空间不足时,项目会根据
flex-shrink
的值按比例收缩。 flex: 1
中的flex-shrink
默认值为 1,表示当空间不足时,该项目会与其他项目一起按比例收缩以适应容器。
- 定义了弹性项目的收缩因子。当弹性容器空间不足时,项目会根据
-
flex-basis
:- 定义了弹性项目在分配空间之前的初始大小。
flex: 1
中的flex-basis
默认值为0%
,表示项目的初始大小为 0,然后根据flex-grow
和flex-shrink
来确定最终大小。
例如,假设有一个弹性容器包含三个项目,其中两个项目设置了flex: 1
,另一个项目宽度固定为 100px。当容器宽度足够大时,两个设置了flex: 1
的项目会平分剩余空间;当容器宽度变小时,它们会根据比例收缩以适应容器。
以下是一个代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.container {
display: flex;
}
.item1,
.item2 {
flex: 1;
background-color: lightblue;
height: 50px;
}
.item3 {
width: 100px;
background-color: lightgreen;
height: 50px;
}
</style>
</head>
<body>
<div class="container">
<div class="item1"></div>
<div class="item2"></div>
<div class="item3"></div>
</div>
</body>
</html>
在这个例子中,.container
是一个弹性容器,.item1
和.item2
设置了flex: 1
,它们会根据容器的大小自动调整宽度,而.item3
有固定的宽度 100px。
flex:1 与 flex:auto 的区别?
这俩的区别就在于flex-basis=0%和flex-basis=auto的区别
- flex-basis = 0% 代表flex-grow和grow-shrink收缩时不用考虑元素尺寸
- flex-basis = auto 收缩时需要将元素本身尺寸考虑进去
3.6 align-self属性
align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性
。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
该属性可能取6个值,除了auto,其他都与align-items属性完全一致。
四、BFC
1、什么是BFC
BFC是Block Formatting Context, 即块级作用域上下文,有自己的渲染规则:
- 内部盒子在垂直方向一个接一个放置
- 两个相邻盒子的垂直外边距相遇时,会发生外边距合并(margin collapsing)现象,但在 BFC 中,这种合并只会发生在同一个 BFC 内部的盒子之间
- BFC 的区域不会与浮动元素重叠
- 计算 BFC 的高度时,浮动元素也会参与计算
- 每个元素的外边距与包含块的左边界接触(从左到右),即使浮动元素也是如此
2、触发条件
- 根元素,即html元素
- 浮动元素,float为left、right
- overflow值不为visible,为auto、scroll、hidden
- display值为inline-block, table-cell, table-caption, table, inline-table, flex, inline-flex, grid, inline-grid
- position值为absolute或fixed
3、应用场景
BFC(Block Formatting Context,块级格式化上下文)有以下一些应用场景及代码实例:
3.1 防止 margin 重叠
-
问题描述:
- 在默认情况下,垂直方向上相邻的块级元素的外边距(margin)会发生重叠。这可能导致布局不符合预期,尤其是当你希望两个元素之间的间距是两个元素的外边距之和时。
-
解决方案:
- 将其中一个元素包裹在一个创建了 BFC 的容器中,这样可以防止外边距重叠。
-
代码实例:
<style> .box1 { height: 50px; width: 100px; background-color: lightblue; margin-bottom: 20px; } .box2 { height: 50px; width: 100px; background-color: lightgreen; margin-top: 30px; } .bfc-container { overflow: hidden; /* 创建 BFC */ } </style> <div class="box1"></div> <div class="bfc-container"> <div class="box2"></div> </div>
在这个例子中,.box1
和.box2
原本会发生外边距重叠,导致它们之间的间距只有 30px(取两个外边距中的较大值)。但是,将.box2
包裹在一个创建了 BFC 的.bfc-container
中后,它们之间的间距就变成了两个外边距之和,即 50px。
3.2 清除浮动
-
问题描述:
- 当一个父元素内部的子元素设置了浮动(float)属性时,父元素的高度可能会塌陷,即父元素的高度不会自动包含浮动的子元素。
-
解决方案:
- 可以通过在父元素上创建 BFC 来解决这个问题,让父元素的高度能够自动包含浮动的子元素。
-
代码实例:
<style> .parent { border: 1px solid black; } .float-child { float: left; width: 50px; height: 50px; background-color: lightblue; } .bfc-parent { overflow: hidden; /* 创建 BFC */ border: 1px solid red; } </style> <div class="parent"> <div class="float-child"></div> <div class="float-child"></div> </div> <div class="bfc-parent"> <div class="float-child"></div> <div class="float-child"></div> </div>
在这个例子中,第一个.parent
元素没有创建 BFC,所以它的高度为 0,边框不会显示出高度。而第二个.bfc-parent
元素通过设置overflow: hidden
创建了一个 BFC,它的高度会自动包含内部的浮动子元素的高度,边框会显示出正确的高度。
3.3 避免元素被浮动元素覆盖
-
问题描述:
- 当一个元素设置了浮动后,它可能会覆盖后面的非浮动元素。
-
解决方案:
- 可以将非浮动元素包裹在一个创建了 BFC 的容器中,这样可以避免被浮动元素覆盖。
-
代码实例:
<style> .float-img { float: left; width: 100px; height: 100px; background-color: lightgray; } .bfc-container { overflow: hidden; /* 创建 BFC */ } .text { background-color: lightyellow; } </style> <div> <div class="float-img"></div> <div class="bfc-container"> <p class="text"> This is some text that won't overlap with the floated element because it's in a BFC. </p> </div> </div>
在这个例子中,.float-img
是一个浮动的元素。.bfc-container
创建了一个 BFC,内部的文本内容.text
不会与浮动的图片重叠,而是在 BFC 的区域内正常显示。
五、CSS 垂直居中方法
1、使用 flex 布局
- 对于单个元素在父容器中垂直居中
通过设置父元素为 flex 容器,并使用<style> .parent { display: flex; align-items: center; height: 200px; } .child { width: 100px; height: 50px; background-color: lightblue; } </style> <div class="parent"> <div class="child"></div> </div>
align-items: center
属性来实现子元素在垂直方向上的居中。 - 对于多个元素在父容器中垂直居中
设置父元素为 flex 容器,<style> .parent { display: flex; flex-direction: column; justify-content: center; height: 200px; } .child1, .child2 { width: 100px; height: 50px; background-color: lightblue; margin: 10px; } </style> <div class="parent"> <div class="child1"></div> <div class="child2"></div> </div>
flex-direction: column
使子元素垂直排列,再使用justify-content: center
实现子元素整体在垂直方向上的居中。
2、使用 grid 布局
- 单个元素垂直居中
类似 flex 布局,设置父元素为 grid 容器,通过<style> .parent { display: grid; align-items: center; height: 200px; } .child { width: 100px; height: 50px; background-color: lightblue; } </style> <div class="parent"> <div class="child"></div> </div>
align-items: center
实现子元素垂直居中。
3、使用绝对定位和负边距
- 已知子元素高度时
首先将子元素设置为绝对定位,通过<style> .parent { position: relative; height: 200px; } .child { position: absolute; top: 50%; height: 50px; margin-top: -25px; background-color: lightblue; } </style> <div class="parent"> <div class="child"></div> </div>
top: 50%
将子元素的顶部移动到父元素的垂直中间位置,然后再使用负的margin-top
值,其值为子元素高度的一半,将子元素向上移动自身高度的一半,从而实现垂直居中。
4、使用 line-height 和 vertical-align
- 对于单行文本
设置父元素的<style> .parent { height: 200px; line-height: 200px; text-align: center; } .child { display: inline-block; vertical-align: middle; background-color: lightblue; } </style> <div class="parent"> <div class="child">单行文本垂直居中</div> </div>
line-height
与父元素的高度相等,使文本在垂直方向上占据整个父元素的高度。然后将子元素设置为inline-block
并使用vertical-align: middle
使其在父元素中垂直居中。 - 对于多行文本(需配合伪元素)
将父元素设置为<style> .parent { height: 200px; display: table-cell; vertical-align: middle; text-align: center; } .child { display: inline-block; background-color: lightblue; } </style> <div class="parent"> <div class="child"> 多行文本垂直居中<br>多行文本垂直居中 </div> </div>
table-cell
,并使用vertical-align: middle
实现垂直居中。子元素设置为inline-block
以便在父元素中水平居中显示。
5、使用 transform 属性
- 已知子元素高度时
同样先将子元素设置为绝对定位并通过<style> .parent { position: relative; height: 200px; } .child { position: absolute; top: 50%; transform: translateY(-50%); background-color: lightblue; } </style> <div class="parent"> <div class="child"></div> </div>
top: 50%
移动到父元素垂直中间位置,然后使用transform: translateY(-50%)
将子元素向上移动自身高度的一半,实现垂直居中。
六、CSS 实现两栏布局(右侧自适应)和三栏布局(中间自适应)
1. 两栏布局(右侧自适应)
1.1 使用浮动(Float)
<style>
.left-column {
width: 200px;
float: left;
background-color: lightblue;
}
.right-column {
background-color: lightgreen;
overflow: hidden;
}
</style>
<div class="left-column">Left column with fixed width.</div>
<div class="right-column">Right column adapts to remaining space.</div>
- 左侧栏设置固定宽度并向左浮动。
- 右侧栏通过设置
overflow: hidden
来清除左侧栏的浮动影响,从而实现右侧栏自适应剩余空间。
1.2 使用 Flex 布局
<style>
.container {
display: flex;
}
.left-column {
width: 200px;
background-color: lightblue;
}
.right-column {
flex: 1;
background-color: lightgreen;
}
</style>
<div class="container">
<div class="left-column">Left column with fixed width.</div>
<div class="right-column">Right column adapts to remaining space.</div>
</div>
- 将容器设置为 flex 布局。
- 左侧栏设置固定宽度。
- 右侧栏设置
flex: 1
,使其自动填充剩余空间,实现自适应。
2. 三栏布局(中间自适应)
2.1 使用浮动(Float)
<style>
.left-column {
width: 200px;
float: left;
background-color: lightblue;
}
.right-column {
width: 150px;
float: right;
background-color: lightpink;
}
.middle-column {
background-color: lightgreen;
overflow: hidden;
}
</style>
<div class="left-column">Left column.</div>
<div class="middle-column">Middle column adapts to remaining space.</div>
<div class="right-column">Right column.</div>
- 左侧栏和右侧栏分别设置固定宽度并向左和向右浮动。
- 中间栏通过设置
overflow: hidden
来清除左右两侧栏的浮动影响,实现中间栏自适应剩余空间。
2.2 使用 Flex 布局
<style>
.container {
display: flex;
}
.left-column {
width: 200px;
background-color: lightblue;
}
.right-column {
width: 150px;
background-color: lightpink;
}
.middle-column {
flex: 1;
background-color: lightgreen;
}
</style>
<div class="container">
<div class="left-column">Left column.</div>
<div class="middle-column">Middle column adapts to remaining space.</div>
<div class="right-column">Right column.</div>
</div>
- 将容器设置为 flex 布局。
- 左侧栏和右侧栏分别设置固定宽度。
- 中间栏设置
flex: 1
,使其自动填充剩余空间,实现自适应。
2.3 使用 Grid 布局
<style>
.container {
display: grid;
grid-template-columns: 200px auto 150px;
background-color: lightgray;
}
.left-column {
background-color: lightblue;
}
.middle-column {
background-color: lightgreen;
}
.right-column {
background-color: lightpink;
}
</style>
<div class="container">
<div class="left-column">Left column.</div>
<div class="middle-column">Middle column adapts to remaining space.</div>
<div class="right-column">Right column.</div>
</div>
- 将容器设置为 grid 布局,并使用
grid-template-columns
定义三栏的宽度,中间栏设置为auto
实现自适应。
七、CSS 实现单行、多行文本溢出省略样式
1. 单行文本溢出省略
1.1 使用 CSS 属性实现
<style>
.single-line-text {
width: 200px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
<div class="single-line-text">This is a single line text that may overflow and should be ellipsized.</div>
- 设置元素宽度为固定值(如 200px)。
white-space: nowrap
确保文本不换行。overflow: hidden
隐藏超出部分。text-overflow: ellipsis
在文本溢出时显示省略号。
2. 多行文本溢出省略
2.1 使用伪元素实现
<style>
.multiline-text {
position: relative;
line-height: 20px;
height: 40px;
overflow: hidden;
}
.multiline-text::after {
content: "...";
position: absolute;
bottom: 0;
right: 0;
padding-left: 5px;
background: linear-gradient(to right, transparent, white);
}
</style>
<div class="multiline-text">This is a multiline text that may overflow and should be ellipsized after two lines.</div>
- 设置元素宽度为固定值(如 200px)。
display: -webkit-box
和-webkit-box-orient: vertical
将元素设置为弹性盒子并垂直排列。-webkit-line-clamp: 2
限制文本显示为两行。overflow: hidden
隐藏超出部分。- 使用伪元素
::after
在文本末尾添加省略号,并通过background: linear-gradient(to right, transparent, white)
创建渐变背景,使省略号看起来更自然。
注意:多行文本溢出省略的实现方式在不同浏览器中的兼容性可能有所不同,上述代码中的-webkit-
前缀是针对 WebKit 内核浏览器的,其他浏览器可能需要不同的前缀或不支持此特性。