CSS3基础
- CSS3简介
- 新增长度单位
- 新增盒模型相关属性
- 新增背景相关属性
- 新增边框相关属性
- 新增文字相关属性
- 渐变
- web字体
- 字体图标
- 2D变换
- 3D变换
- 过渡
- 动画
- 多列布局
- 伸缩盒模型
- 响应式布局
- BFC
CSS3简介
概述
CSS3是CSS2的升级版本
在未来会按照模块化进行发展,比如按照处理对象不同划分一个模块,后期完善该模块的样式规范。
官网CSS3模块化地址: https://www.w3.org/Style/CSS/current-work
新特性如下:
1.新增了实用选择器
例如: 动态伪类,目标伪类,伪元素选择器等
2.更好的视觉效果
例如: 圆角、阴影、渐变、动画、过渡等
3.丰富的背景效果
例如: 支持多个背景图片,同时新增了个多背景相关的属性
4.新增全新的布局方案
弹性盒子Flexbox: Flexible Box Layout Module
5.新增了web字体
可以显示用户电脑上没有安装的字体
6.增强了颜色
例如: HSL,HSLA,RGBA颜色模式,新增opacity属性控制透明度
7.新增了2D和3D转换
例如: 2D转换,3D转换,3D旋转,3D缩放,3D平移,3D透视等
8.增加动画过渡效果
例如: 过渡,动画,动画时间,动画延迟,动画次数,动画播放方向,动画播放状态等
CSS3的私有前缀
私有前缀: -webkit-
、-moz-
、-ms-
、-o-
等
-webkit-border-radius: 5px;
私有前缀的作用:
W3C在提出的CSS特性,在被浏览器正式支持之前,浏览器厂商会根据浏览器内核(例如谷歌浏览器-webkit-
),使用私有前缀来测试这些CSS特性,在浏览器正式支持后,浏览器厂商会删除私有前缀,以兼容W3C的CSS特性,保障了W3C新特性可用性。测试不通过的CSS特性,浏览器将不再支持。
因此各个浏览器兼容CSS3比较乱。
查询CSS3兼容性: https://caniuse.com/
查询浏览器厂商是否支持某个特性:
常见浏览器私有前缀:
1.Chrome: -webkit-
2.Edge: -webkit-
3.Safari: -webkit-
4.Firefox: -moz-
5.Opera: -o-
(开发者几乎不再处理该浏览器兼容性)
6.IE: -ms-
(开发者几乎不再处理该浏览器兼容性)
注意:
开发者在编码时,不需要记忆浏览器前缀,因为常用CSS3新特性主流浏览器都是支持,即便是为了兼容老浏览器的兼容性,我们也可以借助打包工具等去帮助我们添加浏览器前缀。
新增长度单位
rem
根元素字体大小倍数,与字体大小有关
例如:
font-size: 16px;
那么withd: 2rem;
其实就是withd: 32px;
用于字体缩进等场景
vw和vh
vw: viewpoint with 视口宽度的百分比
vh: viewpoint height 视口高度的百分比
作用:
可以动态调整盒子在整个视口的宽高,在移动端比较常用
<style>
.box1 {
width: 50px;
height: 40px;
background-color: skyblue;
}
.box2 {
width: 50vw;
height: 20vw;
background-color: skyblue;
}
.box3 {
width: 50vh;
height: 20vh;
background-color: skyblue;
}
</style>
<div class="box1"></div>
<hr>
<div class="box2">vw: viewpoint with</div>
<hr>
<div class="box3">vh: viewpoint height</div>
根据视口宽度设置百分比:
根据视口高度设置百分比:
当不清楚具体元素高度时,可使用calc
函数计算高度
例如设计一个页面,已知顶部顶部导航栏高度为70px,设置内容区的高度,要求内容区和导航栏高度等于视口高度,那么内容区的高度就可以设置为
height: calc(100vh - 70px)
内容区有高度后,就方便使内容区的布局居中
在使用函数时,运算符前后有空格,否则浏览器不识别
vmax和vmin
vmax: viewpoint max 视口宽度和高度中较大为准,然后的百分比
vmin: viewpoint min 视口宽度和高度中较小为准,然后的百分比
新增盒模型相关属性
开发工具显示盒子模型部分区域大小和代码设置的大小不一致的问题
如下: 设置border: 5px,但是在开发工具中显示4.8px
原因有两个:
1.电脑设置了缩放百分比,window电脑一般推荐125%
2.浏览器自动识别电脑设备屏幕缩放比例,会加以矫正,例如,电脑增加了缩放,浏览器自身会自动减小缩放比例,并重新计算大小以便显示正常,这个过程导致开发者工具显示边框小于5px,浏览器的自动减少缩放不是设置中的缩放。
解决方式:
方式一: 设置电脑放缩100%
方式二: 电脑增加缩放,浏览器减小缩放,例如,电脑125%,设置缩放浏览器80%
box-sizing怪异盒模型
属性值:
content-box
: width和height设置的是盒子内容区大小,盒子总大小 =[conent(设定的宽高) + 两边border + 两边padding]
,内容区大小不会改变,因此往往盒子总大小大于设置定的宽高。(标准盒模型)
border-box
: width和height设置的是盒子总大小,盒子总大小(设置定宽高) = [conent(会被压缩) + 两边border + 两边padding]
(怪异盒模型)
<style>
.box1 {
width: 200px;
height: 200px;
background-color: skyblue;
padding: 5px;
border: 5px solid red;
}
.box2 {
width: 200px;
height: 200px;
background-color: skyblue;
padding: 5px;
border: 5px solid red;
box-sizing: border-box;
}
</style>
<div class="box1"></div>
<hr>
<div class="box2"></div>
怪异盒模型宽高确定后,会压缩内容区
resize调整盒子大小
控制是否允许用户控制盒子大小
属性值:
none
: 不允许
both
: 用户可以调节宽高
horizontal
: 用户可以调节宽度
vertical
: 用户可以调节高度
使用条件:
调节元素需添加overflow
属性
<style>
.box1 {
width: 200px;
height: 200px;
background-color: skyblue;
padding: 5px;
margin-left: 10px;
border: 5px solid red;
resize: horizontal;
overflow: hidden;
}
.box11 {
width: 300px;
height: 200px;
background-color: aqua;
padding: 5px;
margin-left: 10px;
border: 5px solid red;
resize: horizontal;
overflow: hidden;
}
.box2 {
width: 200px;
height: 200px;
background-color: skyblue;
padding: 5px;
margin-left: 10px;
border: 5px solid red;
resize: both;
overflow: hidden;
}
</style>
<div class="box1">resize: horizontal
<div class="box11">子盒子</div>
</div>
<hr>
<div class="box2">resize: both</div>
box-shadow阴影复合属性
盒子的阴影盒子作为盒子的阴影效果
<style>
.box1 {
width: 200px;
height: 200px;
background-color: skyblue;
margin: 0 auto;
margin-top: 100px;
/* 相对于盒子本身 两个值: x坐标 y坐标 */
box-shadow: 10px 10px;
/* 三个值: x坐标 y坐标 阴影盒子颜色*/
/* box-shadow: 10px 10px gray; */
/* 三个值: x坐标 y坐标 阴影盒子模糊程度*/
/* box-shadow: 10px 10px 10px; */
/* 四个值: x坐标 y坐标 阴影盒子模糊程度 阴影盒子颜色*/
/* box-shadow: 10px 10px 10px blue; */
/* 五个值: x坐标 y坐标 阴影盒子模糊程度 阴影外延程度 阴影盒子颜色*/
/* box-shadow: 0px 0px 0px 0px blue; */
/* 六个值: x坐标 y坐标 阴影盒子模糊程度 阴影外延程度 阴影盒子颜色 内阴影*/
/* box-shadow: 10px 20px 10px 5px blue inset; */
}
</style>
<div class="box1">
盒子阴影
</div>
语法:
box-shadow: h-shadow y-shadow blur spread color inset;
属性值:
h-shadow
: 水平阴影的偏移量,可以为负数
y-shadow
: 垂直阴影的偏移量,可以为负数
blur
: 阴影的模糊程度
spread
: 阴影的外延程度
color
: 阴影的颜色
inset
: 设置阴影是否内阴影
默认值:
box-shadow: none;
应用场景,如小米手机官网阴影 + 浮动 + 渐变实现效果:
opacity不透明度
作用:
为整个元素包括元素中的内容设置透明效果,透明值范围0-1,0为完全透明,1为完全不透明,值越小越透明
完全透明后仍占据文档流
opacity: 0;
opacity练习
<style>
img {
width: 500px;
}
.sea-post {
position: relative;
}
h1 {
background-color: aquamarine;
text-align: center;
width: 500px;
position: absolute;
top: 0;
left: 0;
opacity: 0.5;
box-shadow: 5px 5px 10px;
}
</style>
<div class="sea-post">
<h1>水至清则无鱼</h1>
<img src="../resources/sea.png" alt="">
</div>
opacity
和rbg
的区别
opacity
是一个属性,设置整个元素以及元素内容的不透明度,不能设置颜色
rbg()
是设置颜色的一个函数,用于设置颜色,它的透明度仅仅调整颜色的透明度,内容文字颜色不会发生变化
新增背景相关属性
background-origin背景原点
回顾background-image
属性: 背景覆盖区域border、padding、content。
<style>
.box1 {
width: 500px;
height: 500px;
margin: 0 auto;
border: 50px dashed red;
background-color: skyblue;
padding: 20px;
background-repeat: no-repeat;
background-image: url("../resources/city-150*150.png");
}
</style>
<div class="box1">内容区</div>
背景图参考原点是padding区域的左上角,重复时,图片的截取部分覆盖了border区域。
background-origin
作用:
设置背景图的参考原点位置
属性值
padding-box
: 背景图参考原点是padding区域的左上角(默认值)
border-box
: 背景图参考原点是border区域的左上角
content-box
: 背景图参考原点是content区域的左上角
background-clip背景修剪方式
background-clip
作用:
设置背景图剪切区域的位置
<style>
.box1 {
width: 500px;
height: 500px;
margin: 0 auto;
border: 50px dashed red;
background-color: skyblue;
padding: 20px;
background-repeat: no-repeat;
background-image: url('../resources/city-1600*1600.png');
/* 默认值 裁剪掉边框以外的图片 */
background-clip: border-box;
}
</style>
<div class="box1">内容区</div>
背景图片的大小为1600px * 1600px,超过了盒子大小500px,这张背景图超过边框以外的图片会被裁剪掉。
属性值
border-box
: 裁剪掉border
以外的背景(默认值)
padding-box
: 裁剪掉padding
以外的背景
裁剪掉border
以及盒子以外的背景,background-color
仍然作用于padding
和content
content-box
: 裁剪掉content
以外的背景
裁剪掉padding
、border
以及盒子以外的背景,background-color
仍然作用于content
注意:
backgroud-clip
裁剪掉的部分为无色,未裁剪的部分background-color
仍有效,如下图,背景图换成了透明的png,未裁剪部分padding
和content
区域仍然是浅蓝色
text
: 文字以外的背景剪切掉,文字依然可见
使用前提,需要把文字调整为透明
<style>
.box1 {
width: 500px;
height: 500px;
margin: 0 auto;
border: 50px dashed red;
background-color: skyblue;
padding: 20px;
background-repeat: no-repeat;
background-image: url('../resources/city-1600*1600.png');
font-weight: bold;
font-size: 120px;
color: transparent;
background-clip: text;
}
</style>
<div class="box1">透明字体上有背景图片</div>
background-size背景图片大小
<style>
.box1 {
width: 400px;
padding: 0 200px;
height: 400px;
border: 1px solid black;
background-color: skyblue;
background-repeat: no-repeat;
background-image: url('../resources/人物-1920*1080.png');
/* 由于改变了图片比例,因此背景图会被压缩,使图片变形 */
background-size: 400px 400px;
/* 百分比: 相对于盒子的宽度的百分比 相对于盒子高度的百分比 同样也改变了图片比例*/
/* background-size: 100% 100%; */
}
</style>
<div class="box1">内容区</div>
属性值
background-size: 400px 400px;
像素值设置大小
背景图大小为1920px1080px,比例为16:9,要压缩到500px500px,改变了图片比例,因此背景图会被压缩,使图片变形
background-size: 100% 100%;
百分比设置大小
百分比: 相对于整个盒子宽度的百分比 相对于整个盒子高度的百分比
百分比的基数是整个盒子,并不是content
的宽高
设置宽高160px,90px,宽高比例是16:9,当增加左右padding
时,宽的比例变大,使图片横向拉伸至变形
auto
工作机制:
1.背景图比例不变
2.以盒子宽高像素直接在背景图上截取
3.会舍弃掉部分背景图
contain
工作机制:
1.等比放缩,图片不变形
2.放缩直至盒子完全包含图片最长的那一边
3.包含整个背景图
填充过程: 先原点对齐图片,然后等比放缩,直到盒子完全包含图片最长的那一边
cover
(推荐)
工作机制:
1.等比放缩,图片不变形
2.把整个图片等比放缩,直至盒子完全包含图片的某一条边
3.会舍弃掉部分背景图
填充过程: 先原点对齐图片,然后等比放缩,直至盒子完全包含图片的某一条边,舍弃掉部分背景图
backgroud复合属性
语法:
background: [background-color] [background-image] [background-repeat] [background-position] / [background-size] [background-origin] [background-clip];
<style>
.box1 {
width: 500px;
height: 500px;
padding: 20px;
border: 10px dashed black;
/* `background: [background-color] [background-image] [background-repeat] [background-position] / [background-size] [background-origin] [background-clip];` */
background: skyblue url('../resources/city-400*400.png') no-repeat 10px 10px / 100px 100px content-box content-box;
}
</style>
<div class="box1">内容区</div>
注意:
1.如果background-origin
和background-clip
值一样,可以只写一个值,如果不一样,前面一个是origin
后面一个是clip
2.background-size
的值必须写在background-position
的后面,并且用/
分隔
设置多个背景图
<style>
.box1 {
width: 700px;
height: 700px;
border: 1px solid black;
background: url('../resources/人物-300*300.png') no-repeat,
url('../resources/人物-300*300.png') no-repeat right top,
url('../resources/人物-300*300.png') no-repeat left bottom,
url('../resources/人物-300*300.png') no-repeat right bottom;
}
</style>
<div class="box1">内容区</div>
新增边框相关属性
border-radius(边框圆角)
radius
: 半径
像素值
border-radius: 30px;
百分比
<style>
.box {
width: 90px;
height: 180px;
padding: 100px;
border: 1px solid black;
border-radius: 50%;
}
</style>
<body>
<div class="box"></div>
</body>
如果元素是正方形(宽高相等):
水平半径 = 垂直半径 = 边长的50%
如果元素是长方形(宽高不等):
水平半径 = 宽度的50%
垂直半径 = 高度的50%
border-top-left-radius左上角圆角(几乎不用)
<style>
.box {
width: 180px;
height: 180px;
border: 1px solid black;
/* 水平半径90px 垂直半径90px */
border-top-left-radius: 90px;
/* 水平半径90px 垂直半径30px 椭圆形弧度 */
border-top-left-radius: 90px 30px;
/* 水平半径=盒子总宽度的50% 垂直半径=盒子总高度的10% */
border-top-left-radius: 50% 10%;
}
</style>
border-top-right-radius右上角圆角(几乎不用)
<style>
.box {
width: 180px;
height: 180px;
border: 1px solid black;
/* 水平半径90px 垂直半径90px */
border-top-right-radius: 90px;
/* 水平半径90px 垂直半径30px 椭圆形弧度 */
border-top-right-radius: 90px 30px;
/* 水平半径=盒子总宽度的50% 垂直半径=盒子总高度的10% */
border-top-right-radius: 50% 10%;
}
</style>
border-bottom-left-radius左下角圆角(几乎不用)
<style>
.box {
width: 180px;
height: 180px;
border: 1px solid black;
/* 水平半径90px 垂直半径90px */
border-bottom-left-radius: 90px;
/* 水平半径90px 垂直半径30px 椭圆形弧度 */
border-bottom-left-radius: 90px 30px;
/* 水平半径=盒子总宽度的50% 垂直半径=盒子总高度的10% */
border-bottom-left-radius: 50% 10%;
}
</style>
border-bottom-right-radius右下角圆角(几乎不用)
<style>
.box {
width: 180px;
height: 180px;
border: 1px solid black;
/* 水平半径90px 垂直半径90px */
border-bottom-right-radius: 90px;
/* 水平半径90px 垂直半径30px 椭圆形弧度 */
border-bottom-right-radius: 90px 30px;
/* 水平半径=盒子总宽度的50% 垂直半径=盒子总高度的10% */
border-bottom-right-radius: 50% 10%;
}
</style>
border-radius四个圆角的复合属性(几乎不用)
border-radius: 20px 30px 40px 50px / 20px 30px 40px 50px;
格式:
border-raduis: 左上x 右上x 右下x 左下x / 左上y 右上y 右下y 左下y;
盒子外轮廓属性outline属性
<style>
.box {
width: 180px;
height: 180px;
padding: 10px;
background-color: grey;
border: 5px solid black;
margin: 0 auto;
margin-top: 50px;
outline-width: 10px;
outline-color: orange;
outline-style: solid;
outline-offset: 10px;
/* 复合属性 */
/* outline: 10px solid orange; */
}
</style>
<div class="box">内容区</div>
<div>上面盒子外轮廓不占文档流</div>
outline-width
: 外轮廓宽度
outline-style
: 外轮廓样式
值有none
、solid
、dashed
、dotted
(点状)、double
outline-color
: 外轮廓颜色
outline-offset
: 外轮廓偏移量
可以为负值,它是一个独立的属性
outline
: 是一个复合属性,包括outline-width
、outline-style
、outline-color
,但不包括outline-offset
注意:
outline
属性不占用文档流,不计算盒子大小。
新增文字相关属性
文字阴影text-shadow复合属性
<style>
h1 {
text-shadow: 2px 2px 5px red;
}
</style>
<h1>文本阴影</h1>
属性值
text-shadow
: h-shadow
y-shadow
blur
color
none
没有阴影
text-shadow: none;
h-shadow
水平偏移量
必须写
y-shadow
垂直偏移量
必须写
blur
模糊程度
可选
color
颜色
可选
white-space属性:文本换行方式
属性值
normal
: 默认值
white-space: normal;
文本超出边界会自动换行,文本中的换行被浏览器识别为空格
pre
: 原样输出与pre标签效果相同
<style>
div {
width: 200px;
height: 200px;
border: 1px solid black;
white-space: pre;
}
</style>
<body>
<div>
无人扶我青云志
我自踏雪之山巅
我自踏雪之山巅
我自踏雪之山巅
</div>
</body>
pre-wrap
:在pre基础上,超出边界自动换行
<style>
div {
width: 200px;
height: 200px;
border: 1px solid black;
white-space: pre-wrap;
}
</style>
<body>
<div>
无人扶我青云志
我自踏雪之山巅我自踏雪之山巅我自踏雪之山巅
我自踏雪之山巅
我自踏雪之山巅
</div>
</body>
pre-line
在pre
基础上,超出边界自动换行,只识别文本中的换行和文字之间的空格。也就是说一行中前后空格没有效果,一行之间的空格有效果。
<style>
div {
width: 200px;
height: 200px;
border: 1px solid black;
white-space: pre-line;
}
</style>
<body>
<div>
无人扶我青云志
我自踏雪之山巅我自踏雪之山巅 我自踏雪之山巅
</div>
</body>
nowrap
强制不换行
text-overflow属性处理文本溢出
<style>
ul {
width: 200px;
height: 200px;
list-style: none;
padding-left: 0;
border: 1px solid black;
}
li {
overflow: hidden;
white-space: nowrap;
/*
clip: 裁剪 默认值
ellipsis: 省略
*/
text-overflow: ellipsis;
}
</style>
<ul>
<li>华裔教授被查资料全消失</li>
<li>“台积电白给了,武器白买了” 台湾巨额保护费换来美国高关税</li>
<li>美股大跌损失惨重,马斯克也忍不住了!他公开挖苦特朗普“顾问”纳瓦罗:要么是自负,要么是脑子有问题</li>
</ul>
属性值
clip
:裁剪
text-overflow: clip;
: 盒子外面的文本裁剪掉,破坏单个文字完整性,默认值
ellipsis
:省略
text-overflow: ellipsis;
: 当文字超过盒子时,盒子外部的文字替换成...
,不会破坏单个文字完整性,需要配合其他属性设置,才能呈现出...
需要配合overflow:非visible值;
和white-space:nowrap;
使用
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
文本修饰
<style>
div {
margin-top: 50px;
font-size: 30px;
font-weight: bold;
/* 文本划线位置 */
text-decoration-line: overline;
/* 文本划线样式 */
text-decoration-style: wavy;
/* 文本划线颜色 */
text-decoration-color: red;
/* 文本划线宽度 */
text-decoration-thickness: 5px;
/* 复合属性 */
text-decoration: overline wavy red 5px;
}
</style>
<body>
<div>文本修饰复合属性</div>
</body>
属性值
text-decoration-line
: 文本装饰线位置
值:
none
: 无装饰线
underline
: 下划线
overline
: 上划线
line-through
: 删除线
text-decoration-style
: 文本装饰线样式
值:
solid
: 实线
double
: 双线
dotted
: 点状
dashed
: 虚线
wavy
: 波浪线
text-decoration-color
: 文本装饰线颜色
text-decoration-thickness
: 文本装饰线宽度
/* 文本划线宽度 */
text-decoration-thickness: 5px;
text-decoration
: 文本修饰复合属性
格式:
text-decoration
: text-decoration-line
text-decoration-style
text-decoration-color
text-decoration-thickness
text-decoration: overline wavy red 5px;
文本描边
仅支持webkit内核浏览器,需要样式前缀-webkit-
<style>
div {
margin-top: 50px;
font-size: 30px;
font-weight: bold;
-webkit-text-stroke-color: red;
-webkit-text-stroke-width: 1px;
color: transparent;
}
</style>
<div>文本修饰复合属性</div>
使用场景: 设置空心文字
-webkit-text-stroke-width
: 文本描边宽度
-webkit-text-stroke-color
: 文本描边颜色
-webkit-text-stroke
: 文本描边复合属性
格式:
-webkit-text-stroke: [width] [color];
渐变
线性渐变
background-image: linear-gradient函数
linear: 线性 gradient: 渐变
格式:
linear-gradient(方向, 颜色1, 颜色2, ...)
关键词调整渐变方向
to bottom
: 从上到下,默认值,可以不写方向,如:background-image: linear-gradient(red, yellow, green);
to top
: 从下到上
to right
: 从左到右
to left
: 从右到左
to top left
: 从右下到左上
to top right
: 从左下到右上
to bottom left
: 从右上到左下
to bottom right
: 从左上到右下
角度调整渐变方向
background-image: linear-gradient(20deg, red, yellow, green);
顺时针调整渐变方向
渐变颜色区域
background-image: linear-gradient(red 50px, yellow 100px, green 150px);
根据渐变方向,从上倒下50px处为红色,100px处为黄色,150px处为绿色,颜色边界范围内进行渐变
文字颜色渐变
.box5 {
color: transparent;
font-size: 50px;
font-weight: bold;
background-image: linear-gradient(20deg, red 50px, yellow 100px, green 150px);
background-clip: text;
}
径向渐变
background-image: radial-gradient(red, yellow, green);
radial: 径向 gradient: 渐变
径向渐变是从一个点向外发散的渐变,默认情况下盒子中心点为圆心,根据盒子宽高来确定渐变的半径,因此渐变圆x半径和y半径有可能不同,那么渐变圆形状就像椭圆
关键词调整渐变圆的圆心
background-image: radial-gradient(at left top, red, yellow, green);
坐标调整渐变圆的圆心
background-image: radial-gradient(at 50px 100px, red, yellow, green);
调整渐变圆的形状(正圆/椭圆)
默认情况下渐变圆的形状根据盒子宽高来决定,宽高不等的情况下,渐变圆的形状是椭圆
background-image: radial-gradient(100px 100px, red, yellow, green);
调整水平半径和垂直半径
circle关键字调整渐变圆为正圆
background-image: radial-gradient(circle, red, yellow, green);
调整渐变颜色区域
background-image: radial-gradient(red 50px, yellow 100px, green 150px);
渐变范围调整水平半径大小
0~50px红色
50px~100px渐变黄色
100px~150px渐变绿色
综合写法
background-image: radial-gradient(渐变圆形状 渐变圆圆心位置, 颜色 区域, 颜色 区域, ...);
background-image: radial-gradient(circle at 50px 120px, red 50px, yellow 100px, green 150px);
重复渐变
重复渐变: 在没有发生渐变区域内,重新按照渐变顺序进行重复填充
使用repeating-linear-gradient()
和repeating-radial-gradient()
函数,在线性渐变和径向渐变基础上实现重复渐变
<style>
.box {
width: 300px;
height: 200px;
border: 1px solid black;
float: left;
margin-right: 20px;
margin-top: 40px;
}
.box1 {
background-image: linear-gradient(red 50px, yellow 100px, green 150px);
}
.box2 {
background-image: repeating-linear-gradient(red 50px, yellow 100px, green 150px);
}
.box3 {
background-image: radial-gradient(red 50px, yellow 100px, green 150px);
}
.box4 {
background-image: repeating-radial-gradient(red 50px, yellow 100px, green 150px);
}
</style>
<div class="box box1">线性渐变存在没有渐变的区域</div>
<div class="box box2">把没有渐变的区域进行重复渐变</div>
<div class="box box3">径向渐变存在没有渐变的区域</div>
<div class="box box4">把没有渐变的区域进行重复渐变</div>
渐变小案例
实现书信样式
<style>
.box1 {
width: 300px;
height: 500px;
border: 1px solid black;
padding: 10px;
background-image: repeating-linear-gradient(transparent 0px, transparent 17px, grey 18px);
background-clip: content-box;
font-family: "Apple Chancery";
}
</style>
<div class="box1">Dear Kevin:</div>
立体小球
<style>
.boll {
width: 200px;
height: 200px;
background-color: gray;
border-radius: 50%;
background-image: radial-gradient(circle at 70% 50%, #fff, #000);
}
</style>
<div class="boll"></div>
web字体
使用@font-face指定字体的名称和引入字体,浏览器会加载服务器中的字体,不需要用户安装字体,也可呈现字体的方案。
基本用法
简单写法:
<style>
@font-face {
font-family: 'customerFont';
src: url('./font/Apple\ Chancery.ttf');
}
.custom-font {
font-family: 'customerFont';
font-size: 50px;
}
</style>
<div class="custom-font">Hello</div>
用法:
1.@font-face: 定义字体名称和引入字体
2.在需要使用的地方,使用font-family
属性,值为自定义字体的名称
高兼容性写法:
引入多种格式字体,用于兼容不同浏览器
@font-face {
font-family: "阿里妈妈刀隶体 Regular";
font-weight: 400;
src: url("./font2/nKfTIcC2gX9V.woff2") format("woff2"),
url("./font2/nKfTIcC2gX9V.woff") format("woff");
font-display: swap;
}
定制字体
中文字体文件包含了很多字,因此文件很大,使用完整的字体不现实,占用了网络资源加载很慢,定制字体可以针对某些文字使用自定义字体。
可以使用阿里的字体定制工具: https://www.iconfont.cn/fonts/index
字体图标
优势:
1.相比图片更加清晰
2.灵活性高,更加方便改变大小,颜色,风格等
3.兼容性好,IE也能支持
使用阿里云的图标库: https://www.iconfont.cn/
iconfont使用方法
1.选择图标添加购物车
2.打开购物车添加至项目
3.选择项目,点击下载至本地
打开本地demo_index.html
文件,查看使用方式
方式一:内部样式使用@font-face引入字体图标
<style>
@font-face {
font-family: 'iconfont';
src: url('./font3/iconfont.woff2?t=1744078538952') format('woff2'),
url('./font3/iconfont.woff?t=1744078538952') format('woff'),
url('./font3/iconfont.ttf?t=1744078538952') format('truetype');
}
/* 在线资源 */
/* @font-face {
font-family: 'iconfont';
src: url('//at.alicdn.com/t/c/font_4884392_cg350ytieds.woff2?t=1744078279675') format('woff2'),
url('//at.alicdn.com/t/c/font_4884392_cg350ytieds.woff?t=1744078279675') format('woff'),
url('//at.alicdn.com/t/c/font_4884392_cg350ytieds.ttf?t=1744078279675') format('truetype');
} */
.iconfont {
font-family: "iconfont" !important;
font-size: 50px;
font-style: normal;
}
</style>
<span class="iconfont"></span>
<span class="iconfont"></span>
<span class="iconfont"></span>
步骤:
1.将下载好的字体放到项目中
2.使用@font-face
引入字体图标,字体资源可以是本地也可以是网络资源
3.标签使用font-family
属性,值为自定义字体的名称
4.标签内容为字体编码
方式二:外部样式引入(推荐)
<!-- <link rel="stylesheet" href="//at.alicdn.com/t/c/font_4884392_cg350ytieds.css"> -->
<link rel="stylesheet" href="./font3/iconfont.css">
<style>
.iconfont {
font-size: 50px;
}
</style>
<span class="iconfont icon-a-113_baohu"></span>
<span class="iconfont icon-a-113_bangong"></span>
<span class="iconfont icon-a-113_ditu"></span>
步骤:
1.引入iconfont.css
文件,该文件可以放到项目中,也可以引入阿里提供的css网络文件
2.将图标中的类名添加到标签中
方式三:使用svg图标
<!-- <script src="//at.alicdn.com/t/c/font_4884392_cg350ytieds.js"></script> -->
<script src="./font3/iconfont.js"></script>
<style>
.icon {
width: 5em;
height: 5em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-a-113_baohu"></use>
</svg>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-a-113_bangong"></use>
</svg>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-a-113_ditu"></use>
</svg>
步骤:
1.引入iconfont.js
文件,该文件可以放到项目中,也可以引入阿里提供的网络文件
2.svg
和use
标签,use
标签的xlink:href
指向图标中的ID命
第三种方式优缺点:
支持多色图标了,不再受单色限制。
通过一些技巧,支持像字体那样,通过 font-size, color 来调整样式。
兼容性较差,支持 IE9+,及现代浏览器。
浏览器渲染 SVG 的性能一般,还不如 png。
以上三种方式推荐使用外部样式引入的方式
修改每个图标的font class
和Symbol
名称
2D变换
transform
属性允许你对元素进行旋转、缩放、倾斜或平移。这是通过修改 CSS 视觉格式化模型的坐标空间实现的。
2D位移
translateX()函数
: 水平位移
translateY()函数
: 垂直位移
translate()函数
: transform: translate(70px)
一个值代表水平方向,transform: translate(50px, 70px);
两个值代表水平和垂直方向位移
水平位移: transform: translateX(70px);
或transform: translate(70px);
垂直位移: transform: translateY(70px);
水平位移+垂直位移写法一: transform: translate(50px, 70px);
水平位移+垂直位移写法二(链式编写): transform: translateX(50px) translateY(70px);
位移单位:
px: 像素
%: 百分比 相对于自身盒子的宽高的百分比 而相对定位布局时的位移百分比是相对于父元素内容区和内边距有关
特点
1.位移和相对定位很像,都不脱离文档流,不会影响到其他元素
<style>
.out {
width: 200px;
background-color: #ccc;
border: 1px solid #000;
margin: 0 auto;
margin-top: 100px;
}
.inner {
width: 150px;
height: 150px;
background-color: aqua;
transform: translateX(70px);
}
</style>
<div class="out">
<div class="inner"></div>
</div>
父元素.out
没有设置高度时,其高度仍然会被位移子元素.inner
撑开,说明位移子元素不脱离文档流,不会影响到其他元素。
2.位移的百分比参考的是自己盒子的大小,而相对定位的百分比是根据父元素盒子内容区
参考相对定位百分比: 相对定位百分比
移动元素增加自身的宽度,其水平位移也会增加
50% = (content + 两padding + 两边框) * 50% = 盒子大小的50%
3.浏览器针对位移有优化,与定位相比,浏览器处理位移的效率更高
4.可以链式编写
transform: translateX(50px) translateY(70px);
5.位移对于行内元素无效,对于行内块元素和块元素有效
<style>
.out {
width: 200px;
height: 200px;
background-color: #ccc;
border: 1px solid #000;
padding: 50px;
}
.inner {
background-color: aqua;
transform: translate(-50%, -50%);
}
img {
transform: translate(50%, 50%);
}
</style>
<div class="out">
<span class="inner">行内元素</span>
<img src="../resources/city-400*400.png" alt="">
</div>
可以设置行内元素display: block;
才能生效
6.配合定位使用位移居中块元素
<style>
.out {
width: 200px;
height: 200px;
background-color: #ccc;
border: 1px solid #000;
position: relative;
padding: 50px;
}
.inner {
width: 150px;
height: 150px;
background-color: aqua;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
<div class="out">
<div class="inner"></div>
</div>
原理:
使.inner
元素改变为绝对定位元素,其父元素.out
作为包含块,因为绝对定位百分比是依据其包含块content
的百分比(参考:绝对定位百分比),
因此.inner
左上角正好在.out
的中心点,再使用transform
进行平移即可。
7.位移元素没有脱离文档流,因此不会跨过父元素的padding
位移元素默认位置在父元素的content
中
浮动+移动元素可以与定位具有相同效果
<style>
.out {
width: 500px;
background-color: #ccc;
border: 1px solid #000;
margin: 0 auto;
}
.inner {
width: 200px;
height: 200px;
background-color: aqua;
float: left;
transform: translate(70px);
}
.out2 {
width: 500px;
background-color: #ccc;
border: 1px solid #000;
margin: 0 auto;
position: relative;
}
.inner2 {
width: 200px;
height: 200px;
background-color: aqua;
position: absolute;
left: 70px;
}
</style>
<div class="out">
<div class="inner">浮动+位移实现定位效果</div>
<img src="../resources/人物-300*300.png" alt="">
</div>
<hr>
<div class="out2">
<div class="inner2">定位元素效果</div>
<img src="../resources/人物-300*300.png" alt="">
</div>
蓝色盒子用(浮动+移动)与绝对定位实现相同的布局
区别:
1.绝对定位完全脱离文档流,可以覆盖块元素、行内元素或行内块元素
2.而浮动后的元素,可以覆盖后面的块元素,但是不能覆盖行内元素或行内块元素,因为浮动脱离了文档流
,但不脱离文本流
3.而位移元素不会因为位移,占据的文档流
和文本流
位置发生改变,只是元素位置改变,占据的文档流
和文本流
位置不变
即使元素浮动后再移动,仍然占据的是最开始的文本流
,不会因为蓝色盒子位移,使图片位置发生改变
缩放
scaleX()函数
: 水平缩放倍数
scaleY()函数
: 垂直缩放倍数
水平放缩: transform: scaleX(0.5);
垂直放缩: transform: scaleY(0.5);
水平放缩+垂直放缩(方式一): transform: scale(0.5, 0.5);
水平放缩+垂直放缩(方式二链式写法): transform: scaleX(0.5) scaleY(0.5);
<style>
.out {
width: 200px;
background-color: #ccc;
border: 1px solid #000;
margin: 0 auto;
margin-top: 100px;
}
.inner {
width: 200px;
height: 200px;
background-color: aqua;
transform: scaleX(0.5) scaleY(0.5);
}
</style>
<div class="out">
<div class="inner">盒子缩放</div>
</div>
缩放倍数
缩放倍数指的是基于当前盒子content的大小而言
.inner
元素缩小为0.5,其内容区200px * 0.5 = 100px,边框仍然是5px
缩放对行内元素无效,对行内块和块元素有效
可以设置行内元素display: block;
才能生效
注意
1.缩放可以写负数但是几乎不用,容易误导别人
2.可以突破浏览器设置字体大小的限制,让文字呈现出更大或更小效果
3.盒子缩放不脱离文档流,不会影响到其他元素布局,如下图黑色盒子不会因为上面的盒子缩放导致布局发生变化
4.放缩可以为负值,其内容文字会反向显示
2D旋转
空间坐标可以分为,x,y,z,我们可以把元素在z轴上进行旋转,z轴是垂直于屏幕的轴,绕着z轴旋转就是平面上的旋转。绕着x轴旋转和y轴旋转就是空间上的旋转。
因此2D旋转是沿着z轴进行旋转,让元素在二维平面内,顺时针或逆时针旋转,
rotateZ()函数
: 绕着z轴旋转,顺时针或逆时针旋转,也就是2D旋转,角度单位为deg
平面旋转: transform: rotateZ(20deg)
或transform: rotate(20deg)
<style>
.out {
width: 200px;
height: 200px;
background-color: #ccc;
border: 1px solid #000;
margin: 0 auto;
margin-top: 100px;
}
.inner {
width: 200px;
height: 200px;
background-color: aqua;
transform: rotateZ(-20deg);
}
</style>
<div class="out">
<div class="inner">盒子缩放</div>
</div>
以盒子中心点为旋转中心点
正数: 顺时针旋转
负数: 逆时针旋转
transform: rotateZ(-20deg);
扭曲(了解即可)
扭曲: 让元素在平面内被拉扯,进而走形。实际开发中几不用
skewX()
函数: 横向扭曲,skewY()
函数: 纵向扭曲
水平方向扭曲: transform: skewX(-20deg);
或transform: skew(-20deg);
skewX正值: 左上角向左拉扯,右下角向右拉扯
skewX负值: 右上角向右拉扯,左下角向左拉扯
skewY正值: 左上角向上拉扯,右下角向下拉扯
skewY负值: 左下角向下拉扯,右上角向上拉扯
垂直方向扭曲: transform: skewY(-20deg);
水平+垂直方向扭曲: transform: skewX(-20deg) skewY(-20deg);
<style>
.out {
width: 200px;
height: 200px;
background-color: #ccc;
border: 1px solid #000;
margin: 0 auto;
margin-top: 100px;
}
.inner {
width: 200px;
height: 200px;
background-color: aqua;
transform: skewX(-20deg);
}
</style>
<div class="out">
<div class="inner">盒子扭曲</div>
</div>
注意:
扭曲元素内容也会变形,但不会反转
多重变换
<style>
.out {
width: 200px;
height: 200px;
background-color: #ccc;
border: 1px solid #000;
margin: 0 auto;
margin-top: 100px;
}
.inner {
width: 200px;
height: 200px;
background-color: aqua;
transform: translate(100px, 100px) scale(0.5);
/* transform: scale(0.5) translate(100px, 100px); */
}
</style>
<div class="out">
<div class="inner">盒子多重变换</div>
</div>
先位移再缩放
transform: translate(100px, 100px) scale(0.5)
: 先位移再缩放的过程
.inner
以左上角为原点,先位移到(100px, 100px)位置,再以自身的中心点为原点进行放缩0.5倍
先缩放再位移的过程
transform: scale(0.5) translate(200px, 200px)
先缩放0.5 ,再移动200px,实际移动了100px
transform: scale(0.5) translate(100px, 100px)
先缩放0.5 ,再移动100px,实际移动了50px
transform: scale(1.5) translate(100px, 100px)
先缩放1.5 ,再移动100px,实际移动了150px
因此先放缩再位移: 是以自身中心点放缩,再以放缩后的盒子的左上角为原点进行位移
水平位移真实距离 = x * 缩放
垂直位移真实距离 = y * 缩放
先位移再旋转
transform: translate(100px, 100px) rotate(20deg)
先旋转再位移
transform: rotate(20deg) translate(100px, 100px)
先顺时针旋转20度,再以盒子左上角为原点,x,y轴的角度也会顺时针旋转20度。也就是说旋转后,坐标轴原点,x,y轴都会改变。
再位移时就根据新的坐标轴进行位移的
如果旋转后、再位移、再进行旋转,其中心点始终是第一次旋转时的中心点
总结
1.缩放会影响元素坐标系原点位置,影响真实位移距离
2.旋转会破坏坐标系,影响位移方向
3.一旦发生了旋转,那么该元素的旋转中心点就确定了,即使位移,中心点也不会改变
4.为元素添加变换属性时往往把旋转放在最后
变换原点transform-origin
属性
<style>
.out {
width: 200px;
height: 200px;
background-color: #ccc;
border: 1px solid #000;
margin: 0 auto;
margin-top: 100px;
}
.inner {
width: 200px;
height: 200px;
background-color: aqua;
transform-origin: left top;
transform: rotate(20deg);
}
</style>
<div class="out">
<div class="inner">变换原点</div>
</div>
关键字属性值
关键字: left
right
center
top
bottom
transform-origin: center center
: 默认值
transform-origin: left top
: 元素左上角为原点
transform-origin: right bottom
: 元素右下角为原点
transform-origin: left
: 只写一个值的时候,默认垂直方向距离值是center
具体像素属性值
transform-origin: 100px 100px;
: 旋转原点在坐标轴,水平向右平移100px,垂直向下平移100px
百分比属性值
transform-origin: 50% 50%;
: 旋转原点在坐标轴,水平向右平移盒子宽度的50%,垂直向下平移盒子高度的50%
关键字、像素、百分比属性值是参考的盒子整个大小,同时包含了边框
原点改动对其他变换的影响
对translate位移坐标原点无影响
对rotate旋转中心点有影响
对scale缩放中心点有影响
默认情况下,缩放中心点是元素的中心点,如果指定了原点,那么以该原点为中心,进行放大或缩小
总结
1.transform-origin
属性值是参考的盒子整个大小,同时包含了边框
2.变换原点对旋转缩放有影响,对位移没有影响
3.属性值有两个时,第一个值是水平方向,第二个值是垂直方向
4.属性值只有一个时,另一个方向值默认是center
或50%
,可以省略
transform-origin: 100px;
就是transform-origin: 100px center;
3D变换
3D空间与景深
对3D元素的父元素开启3D空间
要想让一个元素具有3D属性,必须把其父元素开启3D空间
transform-style: preserve-3d;
: 开启3D空间
transform-style: flat;
: flat意思是扁平,默认值,不开启3D空间
景深概念
景深
: 指定了观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果。z>0 的三维元素比正常大,而 z<0 时则比正常小,大小程度由该属性的值决定。
现实中景深概念
面对电脑屏幕,手拿一张纸,当纸越靠近自己眼睛时,感觉纸张越来越大,直到纸张遮住了电脑屏幕。
而在CSS中,由于父元素(电脑屏幕)没有3D属性,大小就不会改变,只有子元素具有3D属性,才会呈现出3D效果。
未设置父元素景深时,子元素旋转后内容像是被压缩了,宽度不变,高度变矮
对父元素设置景深
perspective
: 中文意思是透视,设置景深值,单位为px
属性值:
none
: 不指定透视(默认值)
数值越小,观察者距离3D元素越近,看起来也就越大
开启景深,呈现出3D效果更明显,如下图,由于子元素旋转,子元素下半部分距离观察者较近,距离越近则越大
子元素空间旋转后,父元素设置背景色,覆盖了子元素部分内容
子元素空间旋转后,父元素设置背景色会覆盖掉父元素后面的子元素内容
3D效果: 子元素一部分跑到了父元素后面,父元素再设置背景色,就会把子元素覆盖掉,只有在父元素前面部分不会覆盖
总结
1.元素开启3D效果,必须对其父元素
开启3D空间
未开启3D空间,3D元素始终在父元素前面,如下图,3D元素旋转时,父元素不会被遮挡住
2.对空间元素设置景深值,3D效果更加明显
一般景深设置值为父元素高度的一半多一点,就会有明显效果
透视点位置(观察者位置)
默认情况下观察者位置是开启3D空间元素的中心点(也就是3D元素的父元素盒子的中心点,包含边框、边距、内容区),也就是x: 父元素盒子宽50%,y: 父元素盒子高50%
父元素盒子对角线交点为默认透视点位置
perspective-origin: 101px 201px;
x水平值: 观察者向右平移
y垂直值: 观察者像下平移,越低,看到的3D元素就像是被压缩
在x轴透视点增加过程:
透视点与3D元素的底部角度越来越小,看起来则更加尖锐
注意
1.通常情况下,不需要调整3D空间元素的透视点位置
2.Y轴增大,3D元素看起来像是压缩了
3D位移
translateZ
函数:使3D元素向眼睛靠近
<style>
.out {
width: 200px;
height: 200px;
border: 1px solid #000;
/* background-color: grey; */
margin: 0 auto;
margin-top: 100px;
transform-style: preserve-3d;
perspective: 500px;
}
.inner {
width: 200px;
height: 200px;
background-color:rgba(255, 0, 0, 0.5);
transform: translateZ(10px);
}
</style>
<div class="out">
<div class="inner">3D空间与景深</div>
</div>
在确定景深时,就像确定了眼睛距离页面的高度一样,然后再调整z轴的高度,在视觉上就像是3D元素向眼睛靠近,因此看起来就像是放大了
当translateZ
值和景深值一样时,就会消失,就像3D元素正好贴在了眼睛上,大于景深值时也同样不显示
translateZ
生效条件
translateZ
生效条件: 开启空间元素的景深要确定(眼睛距离页面的高度,即z轴的高度确定,perspective
值确定)
注意
1.translateZ
为负值时就像3D元素远离了眼睛,元素就会缩小
2.其值只能是像素值,不能百分比,因为translateX
,translateY
的百分比都是参考自身元素盒子大小,而3D元素没有厚度,因此translateZ
的百分比没有意义
浏览器提示设置的百分比值无效
2.为负值时在z轴下方,即在空间元素的后面,因此不管空间有没有设置景深,空间元素添加颜色时,就会完全覆盖3D元素
3D元素在空间内位移
translate3d(x, y, z)
函数: 3D元素在空间内位移,x、y、z分别表示水平、垂直和元素距离眼睛方向的位移,单位为px
可以链式编写: transform: translateX(10px) translateY(20px) translateZ(100px);
注意
1.3D元素空间位移: translate3d
函数x,y,x值都不能省略
2.可以链式编写
3.z轴值只能是像素值,不能百分比
3D旋转
3D旋转在2D旋转(rotateZ或rotate)的基础上,可以让元素在X轴(rotateX)和Y轴(rotateY)旋转。
rotateX
函数: 沿着x轴旋转
眼睛在X轴的右侧时进行观看,如果rotateX值为正,则元素会绕着X轴顺时针旋转,如果rotateX值为负,则元素会绕着X轴逆时针旋转
rotateY
函数: 沿着y轴旋转
眼睛在Y轴的下方时进行观看,如果rotateY值为正,则元素会绕着Y轴顺时针旋转,如果rotateY值为负,则元素会绕着Y轴逆时针旋转
rotate3d
函数: 沿着x、y、z轴旋转
语法:
transform: rotate3d(是否沿着x旋转, 是否沿着y旋转, 是否沿着z旋转, deg);
: 表示,先沿着x轴旋转deg,再沿着y旋转deg,再沿着z旋转deg
transform: rotate3d(0,0,0,10deg);
0: 在轴上不旋转 1: 在轴上旋转
3D缩放
2D缩放:
transform: scaleX(0.5);
影响元素宽度
transform: scaleY(0.5);
影响元素高度
transform: scaleZ(0.5);
影响元素厚度(由于3D元素没有厚度,css会把厚度效果转换为景深效果)
只有让元素有一定角度时,我们才能观察到scaleZ()
的效果
由于3D元素没有厚度,css会转化为景深效果
增加景深值是原来的4倍,会让元素变小,那么再放大元素4倍,又会让元素变大,因此css在z轴方向缩放,其实是在调整景深的缩放倍数
scale3d(x, y, z)
函数: 3D缩放,x、y、z分别表示元素在X、Y、Z轴的缩放倍数,要想看到z轴缩放效果,应该为元素添加旋转角度
注意
3D缩放: scale3d
函数x,y,z值都不能省略
多重变换
设置旋转轴的位置
.inner {
width: 200px;
height: 200px;
background-color: rgba(255, 0, 0, 0.5);
transform-origin: left top;
transform: rotateY(20deg);
}
默认情况下,3D元素的原点是盒子的中心点,如果把原点移到y轴上即x=0,无论原点在y轴上什么位置,只要是围绕Y轴旋转,那么效果都是相同的
transform-origin: left top/center/bottom;
和transform-origin: 0px
,只要原点在y轴上,效果都是相同的
位移+旋转
transform: translateZ(30px) rotateY(30deg);
:
注意
多重变换时,应该把旋转放到最后,因为3D旋转也会破坏坐标系,导致效果不同
3D元素背部可见性
当3D元素旋转到背面时,默认情况下是可以看到元素背面的,当设置可见性为hidden时,元素背面则不可见
.inner {
width: 200px;
height: 200px;
background-color: rgba(255, 0, 0, 0.5);
transform: rotateY(20deg);
backface-visibility: hidden;
}
backface-visibility: hidden;
: 设置元素背面不可见,当3D元素旋转到背面时,元素隐藏了
即使隐藏了仍然占据文档流
过渡
过渡: 可以不使用flash
技术和js
来实现元素的平滑过渡效果
<style>
.container {
width: 200px;
height: 200px;
border: 1px solid #000;
background-color: rgb(255, 204, 0);
/* 设置哪个属性需要过渡效果 */
transition-property: height;
/* 设置过渡所需要的时间 */
transition-duration: 1s;
}
.container:hover {
height: 400px;
}
</style>
<div class="container"></div>
没有对元素设置过渡,和设置过渡效果
实现条件
1.使用transition-property
属性为元素指定过渡的属性
属性值:
none
: 默认值,任何属性都不发生过渡
all
: 所有具有过渡属性能力的属性都发生过渡
transition-property: height;
只有height属性发生过渡
transition-property: width,height;
: 多个属性过渡需要要用逗号隔开
2.指定的过渡属性一定发生变化
如果指定了height属性需要过渡,但是触发过渡时height属性值没有改变,则不会发生过渡效果
3.指定过渡的时间
单位: s或ms
多个时间按照顺序对应多个属性值,用逗号分隔多个时间
transition-duration: 1s;
transition-duration: 1s, 2s;
当transition-duration: 0s;就相当于没有过渡效果
可以分开指定属性过渡时间,如:
transition-property: width, height;
transition-duration: 1s, 2s;:
宽度过渡需要1s,高度过渡需要2s,当过渡条件撤销时也会以设置的过渡时间变为原样
哪些属性可以过渡
具有值可以是数值的属性可以过渡,数值包括像素值,百分比值,颜色值(最终转为16进制数值)等。
2D属性和3D属性,阴影等都是数值类型的值,因此这些属性都可以过渡
height: 200px;
width: 200px;
background-color: green;
transform: rotate(10deg);
box-shadow: 0px 4px 20px black;
过渡高级使用
<style>
.container {
width: 1000px;
border: 1px solid #000;
}
.box {
width: 100px;
height: 100px;
transition-property: all;
transition-duration: 1s;
/* 延迟触发过渡 */
transition-delay: 2s;
}
.box1 {
background-color: red;
}
.box2 {
background-color: orange;
}
.box3 {
background-color: yellow;
}
.box4 {
background-color: green;
}
.box5 {
background-color: cyan;
}
.box6 {
background-color: blue;
}
.box7 {
background-color: purple;
}
.container:hover .box {
width: 1000px;
}
</style>
<div class="container">
<div class="box box2"></div>
<div class="box box1"></div>
<div class="box box3"></div>
<div class="box box4"></div>
<div class="box box5"></div>
<div class="box box6"></div>
<div class="box box7"></div>
</div>
transition-delay
属性延迟过渡
transition-delay: 1s;
: 设置过渡延迟时间,单位为s或ms
触发过渡时等待1s开始出现过渡效果
transition-timing-function
属性设置过渡时序效果
通过这个函数会建立一条加速度曲线,因此在整个 transition 变化过程中,变化速度可以不断改变。过渡期间属性值如何随时间变化。这个属性允许开发者创建平滑的动画效果,通过控制动画的加速度曲线来实现
属性值:
ease
: 缓解,默认值,先慢后快再慢,先加速后减速
linear
: 线性,从开始到结束,速度不变
ease-in
: 缓入,先慢后快,开始时慢,结束时快
ease-out
: 缓出,先快后慢,开始时快,结束时慢
ease-in-out
: 缓入缓出,先慢后快再慢,开始时慢,结束时快
step-start
: 不考虑过渡时间,直接到达终点
step-end
: 考虑过渡时间,但没有过渡效果,到了过渡时间时,瞬间到达终点
steps(n)
: 分步过渡,好像每步之间停顿一下
steps(n, start|end)
: 分步过渡,start:触发过渡时立刻走第一步,end:触发过渡时,等一会走第一步
第一步立刻触发
第一步停顿一下触发
cubic-bezier()函数
: 贝塞尔曲线函数,可以实现回弹效果
从https://cubic-bezier.tupulin.com网站取值
效果:
<style>
.container {
width: 1000px;
border: 1px solid #000;
}
.box {
width: 100px;
height: 100px;
transition-property: all;
transition-duration: 3s;
font-size: 13px;
/* 延迟触发过渡 */
/* transition-delay: 2s; */
}
.box1 {
background-color: red;
transition-timing-function: ease;
}
.box2 {
background-color: orange;
transition-timing-function: linear;
}
.box3 {
background-color: yellow;
transition-timing-function: ease-in;
}
.box4 {
background-color: green;
transition-timing-function: ease-out;
}
.box5 {
background-color: cyan;
transition-timing-function: ease-in-out;
}
.box6 {
background-color: blue;
transition-timing-function: step-start;
}
.box7 {
background-color: purple;
transition-timing-function: step-end;
}
.box8 {
background-color: pink;
/* transition-timing-function: steps(20); */
transition-timing-function: steps(5, end);
/* transition-timing-function: steps(5, start); */
}
.box9 {
background-color: black;
/* 贝塞尔曲线 */
transition-timing-function: cubic-bezier(0.89, 0.96, 0.52, 1.31);
}
.container:hover .box {
width: 1000px;
}
</style>
<div class="container">
<div class="box box1">`ease`: 缓解,默认值,先慢后快再慢,先加速后减速 </div>
<div class="box box2">`linear`: 线性,从开始到结束,速度不变 </div>
<div class="box box3">`ease-in`: 缓入,先慢后快,开始时慢,结束时快 </div>
<div class="box box4">`ease-out`: 缓出,先快后慢,开始时快,结束时慢 </div>
<div class="box box5">`ease-in-out`: 缓入缓出,先慢后快再慢,开始时慢,结束时快 </div>
<div class="box box6">`step-start`: 不考虑过渡时间,直接到达终点 </div>
<div class="box box7">`step-end`: 考虑过渡时间,但没有过渡效果,到了过渡时间时,瞬间到达终点 </div>
<div class="box box8">`steps`: 分步过渡 </div>
<div class="box box9">`cubic-bezier函数`: 贝塞尔曲线 </div>
</div>
transition
复合属性
.inner {
width: 100px;
height: 100px;
background-color: green;
transition: 1s all ease;
}
.container:hover .inner {
width: 500px;
background-color: gold;
box-shadow: 0px 4px 20px black;
}
注意
1.transition
中设置时间,一个是过渡时间,一个是延迟时间,如果只设置一个值,该值是默认过渡时间
transition: 1s all ease;
: 过渡时间1s,不延迟
transition: 1s 3s all ease;
: 过渡时间1s,延迟3s
案例(定位+浮动+阴影+旋转+位移+过渡)
<style>
.container {
margin-top: 50px
}
.show-card {
width: 400px;
height: 200px;
position: relative;
overflow: hidden;
margin: 0 auto;
transition: 0.5s all ease;
float: left;
margin-right: 10px;
}
.mask {
width: 400px;
height: 200px;
position: absolute;
top: 0;
left: 0;
text-align: center;
line-height: 200px;
font-size: 60px;
font-weight: bold;
background-color: black;
opacity: 0;
color: white;
transition: 1s all ease;
}
img {
width: 400px;
transition: 1s all ease;
}
.show-card:hover .mask {
opacity: 0.5;
}
.show-card:hover img {
transform: scale(2) rotateZ(20deg);
}
.show-card:hover {
transform: translateY(-5px);
box-shadow: 0px 0px 10px black;
}
</style>
<div class="container">
<div class="show-card">
<img src="../resources/shanghai-1280*853.jpg">
<div class="mask">上海欢迎您</div>
</div>
<div class="show-card">
<img src="../resources/shenzhen-1280*826.jpg">
<div class="mask">深圳欢迎您</div>
</div>
</div>
动画
帧的概念: 一段动画,在一段时间内连续播放n个画面,每一张画面叫做帧。一段时间内播放的帧数越多,画面就越流畅。
人的眼睛生理机制作用,一般1s24帧流畅度,就不会感觉到有卡顿。
关键帧概念: 指的是构成一段动画若干帧中,起到关键作用的2~3帧,为关键帧,如,小球弹起回落的动作,起跳时第一帧,弹起最高点第二帧,落地时第三帧,其他帧都是根据这三帧的关键帧来进行补间动画。css3的动画,就是基于关键帧的动画来补充其他帧的过程。
简单使用方式
<style>
.container {
width: 500px;
height: 50px;
background-color: #ccc;
border: 1px solid #000;
}
.child {
width: 50px;
height: 50px;
background-color: aqua;
/* 指定元素动画使用的关键帧 */
animation-name: move;
/* 动画持续时间 */
animation-duration: 1s;
}
/* 定义动画关键帧 */
@keyframes move {
from {}
to {
transform: translate(450px);
/* background-color: red; */
}
}
</style>
<div class="container">
<div class="child"></div>
</div>
动画步骤:
1.定义关键帧
@keyframes
标识符,定义关键帧
语法:
@keyframes 动画名称 {
/* 动画开始时 */
from {
/* property: value; 属性: 值 */
...
}
/* 动画结束时 */
to {
/* property: value; 属性: 值 */
...
}
}
from: 指定动画开始时,元素的样式,初始样式可以不写
to: 指定动画结束时,元素的样式
2.元素应用关键帧
animation-name: 动画名称;
: 指定元素使用的动画名称
3.指定元素动画持续时间
animation-duration: 1s;
: 指定动画持续时间,单位为s或ms
动画延迟
为动画元素设置动画延迟,延迟1s开始动画
animation-delay: 1s;
可以解决当为元素设置颜色动画时,感觉元素不像是从最初位置动画的
如下图,元素动画过程变为红色时,元素不像是从起始位置移动的
原因: 显卡渲染速度慢,动画效果不够流畅,所以动画效果看起来不像从最初位置动画的
解决办法:
方法一: 换性能更好的显卡
方法二: 设置动画延迟时间,等显卡渲染完后再开始动画(animation-delay: 1s;
)
完整使用方式
<style>
.container {
width: 500px;
height: 50px;
background-color: #ccc;
border: 1px solid #000;
}
.child {
width: 50px;
height: 50px;
background-color: aqua;
/* 指定元素动画使用的关键帧 */
animation-name: move;
/* 动画持续时间 */
animation-duration: 1s;
animation-delay: 1s;
}
/* 定义动画关键帧 */
@keyframes move {
0% {}
50% {
transform: translate(225px);
background-color: blue;
}
100% {
transform: translate(450px) rotate(360deg);
background-color: red;
border-radius: 50%;
}
}
</style>
<div class="container">
<div class="child"></div>
</div>
使用百分比定义关键帧,百分比可以写多个,控制更多动画过程
@keyframes move {
0% {}
10% {}
50% {
transform: translate(225px);
background-color: blue;
}
100% {
transform: translate(450px) rotate(360deg);
background-color: red;
border-radius: 50%;
}
}
同时百分比和关键字可以同时使用定义关键帧(但不推荐)
@keyframes move {
to {}
20%{}
}
其他属性
animation-timing-function调整动画方式
其属性值和过度的transition-timing-function
属性值相同,都是控制动画的加速度曲线
属性值:
ease
: 缓解,默认值,先慢后快再慢,先加速后减速
linear
: 线性,从开始到结束,速度不变
ease-in
: 缓入,先慢后快,开始时慢,结束时快
ease-out
: 缓出,先快后慢,开始时快,结束时慢
ease-in-out
: 缓入缓出,先慢后快再慢,开始时慢,结束时快
step-start
: 不考虑过渡时间,直接到达终点
step-end
: 考虑过渡时间,但没有过渡效果,到了过渡时间时,瞬间到达终点
steps(n)
: 分步过渡,好像每步之间停顿一下
steps(n, start|end)
: 分步过渡,start:触发过渡时立刻走第一步,end:触发过渡时,等一会走第一步
animation-iteration-count动画重复次数
属性值:
数字
: 指定动画重复次数
infinite
: 无限循环
/* 动画重复次数 */
animation-iteration-count: 3;
/* 无限循环 */
animation-iteration-count: infinite;
animation-direction动画方向
/* 动画方向 */
animation-direction: normal;
属性值:
normal
: 默认值,动画从头到尾播放
reverse
: 动画从尾到头播放
alternate
: 含义是交替,动画从头到尾播放完后,然后再从尾到头播放
需要配合animation-iteration-count
属性联合使用,才有效果
如实现无线交替方向动画:
animation-iteration-count: infinite;
animation-direction: alternate;
alternate-reverse
: 含义是交替,动画从头到尾播放完后,然后再从尾到头播放,但动画方向是反向的
animation-fill-mode动画以外的状态(不发生动画时停留在某一帧)
/* 动画持续时间结束后,动画停留在最后一帧 */
animation-fill-mode: forwards;
属性值:
none
: 默认值,动画以外的状态不发生变化
forwards
: 动画持续时间结束后,动画停留在最后一帧
盒子从左向右移动后,动画结束后,停留在最后一帧的样式
backwards
: 动画开始前,动画停留在第一帧,并在animation-delay期间保留此值
该第一帧的样式,取决于动画方向
如下动图,第一帧from设置设置盒子颜色为蓝色,那么动画开始前,包括延迟在内,盒子颜色都是蓝色
animation-play-state动画播放状态
属性值:
running
: 默认值,动画播放
paused
: 暂停动画
/* 动画播放 */
animation-play-state: running;
/* 暂停动画 */
amimation-play-state: paused;
例如实现,鼠标悬停时动画暂停
.container:hover .child {
animation-play-state: paused;
}
复合属性
animation: animation-name animation-duration(第一个值为动画时间) animation-delay(第二个值为延迟时间) animation-timing-function animation-iteration-count animation-direction animation-fill-mode;
animation: move 1s 1s linear 3 alternate forwards;
注意:
1.一般animation-play-state
播放状态单独触发,不写入复合属性中
2.复合属性时间值书写顺序: 第一个时间值为动画时间,第二个时间值为延迟时间
过渡和动画的区别
<style>
.container {
width: 500px;
height: 100px;
background-color: #ccc;
border: 1px solid #000;
}
.transition {
width: 50px;
height: 50px;
background-color: aqua;
transition: all 1s ease;
}
.container:hover .transition {
transform: translate(450px);
background-color: green;
}
.animation {
width: 50px;
height: 50px;
background-color: green;
}
@keyframes move {
from {}
to {
transform: translate(450px);
background-color: green;
}
}
.container:hover .animation {
animation-name: move;
animation-duration: 1s;
}
</style>
<div class="container">
<div class="transition">过渡</div>
<div class="animation">动画</div>
</div>
过渡和动画区别:
1.过渡必须有触发条件,而动画可以没有触发条件
例如,过渡元素需要悬停触发,而动画页面加载后就能触发
2.过渡元素只有两种样式,开始和结束样式,而动画元素在开始和结束之间可以设置多个关键帧对应的样式
小案例
使用png图片 + 动画实现骑自行车的动图
精灵图: 把多个png图片拼接到一张png图片上,减少前端访问资源次数,提高页面渲染速度
把骑车动作的每一帧绘制到一张png图片,图片总宽高130px * 4160px,总共有32帧图片:
<style>
.container {
width: 130px;
height: 130px;
background-image: url('../resources/bike.png');
animation-name: move;
animation-duration: 1s;
animation-iteration-count: infinite;
/* 分为32帧 */
animation-timing-function: steps(32);
}
@keyframes move {
100% {
/* 精灵图高度 */
background-position: 0 -4160px;
}
}
</style>
<div class="container"></div>
多列布局
一般用于实现报纸类的多列布局
<style>
.content {
width: 500px;
height: 800px;
column-count: 2;
}
</style>
<div class="content">
<h1>邯郸学步</h1>
<p>#开始 战国时期,燕国寿陵有个少年,听说赵国都城邯郸的人走路姿势非常优美,就决定前去学习。他风尘仆仆地来到邯郸,果然见到大街上的人走路姿势十分优雅,走起路来仪态万千,举手投足间都流露出翩翩风度。少年赶紧跟着路上的行人模仿起来,人家迈左脚,他跟着迈左脚;人家迈右脚,他也跟着迈右脚。可是学了几天,他却怎么也学不会,而且越走越别扭,姿势比以前更难看了。#结束</p>
<p>#开始 少年心想:肯定是我之前的走路方式太有问题了,我一定要把它彻底抛弃,才能学会新姿势。于是他开始从头学走路,每迈出一步都要仔细推敲下一步的动作。就这样废寝忘食地学习了三个月,他每天刻苦练习,却始终没有学会邯郸人的走路姿势,反而把自己原来的走路方式也忘得精光。最后,少年彻底不知道该怎么走路了,只好爬着回到了燕国。结束</p>
<p>#开始 郸学步—东施效颦#结束</p>
<p>#开始 “邯郸学步”与“东施效颦”都有机械模仿别人而适得其反的意思,但有区别。#结束</p>
<p>#开始 1、意义不同:“东施效颦”偏重在盲目模仿,适得其反;“邯郸学步”偏重在尽管发现了别人的优点,但机械模仿,没有成功,反而连自己原先拥有的本事也失去了。2、 用法不同:“邯郸学步”常用作谦辞;“东施效颦”一般不作谦辞。#结束</p>
</div>
多列布局属性
column-count
: 直接设置列数
column-count: 2;
: 设置列数为2列
column-width
: 指定每列宽度会根据父元素宽度自动计算列数
column-width: 100px;
: 设置每列宽度为100px,根据父元素宽度自动计算列数
复合属性columns: 列数 列宽
(不推荐使用),同时指定列数和列宽
columns: 2 100px;
: 设置列数为2列,每列宽度为100px,最终的列数取决于,哪种列数最少
column-gap
: 设置列间距
column-gap: 20px;
: 设置列间距为20px,即使设置为0,列之间也会有不到一个字符宽度的距离 2
调整每列边框宽度和样式
column-rule-width: 2px;
: 设置每列边框宽度为2px
column-rule-style: solid;
: 设置每列边框样式为实线
column-rule-color: red;
: 设置每列边框颜色为红色
复合属性:
column-rule: 2px solid red;
: 设置每列边框宽度为2px,边框样式为实线,边框颜色为红色
column-span
指定元素是否跨列
属性值:
none
: 默认值,不指定跨列
all
: 横跨所有列
注意:
column-span
应用于具体的元素,而上面的几个属性是应用于容器设置的
容器内有图片时,指定图片width为100%可以对齐每个列的宽度
img {
width: 100%;
}
容器多列布局后,容器内的图片指定width: 100%其实就等于每列宽度
多列图片方案
<style>
.content {
width: 700px;
height: 800px;
column-count: 5;
}
img {
width: 100%;
transition: 0.5s ease;
}
img:hover {
transform: scale(1.2);
box-shadow: 0px 0px 10px black;
}
</style>
<div class="content">
<img src="../resources/city-1600*1600.png" alt="">
<img src="../resources/city-400*400.png" alt="">
<img src="../resources/sea.png" alt="">
<img src="../resources/shanghai-1280*853.jpg" alt="">
<img src="../resources/shenzhen-1280*826.jpg" alt="">
<img src="../resources/人物-1920*1080.png" alt="">
<img src="../resources/风景-1920*1080.jpg" alt="">
<img src="../resources/city-1600*1600.png" alt="">
<img src="../resources/city-400*400.png" alt="">
<img src="../resources/sea.png" alt="">
<img src="../resources/shanghai-1280*853.jpg" alt="">
<img src="../resources/shenzhen-1280*826.jpg" alt="">
<img src="../resources/人物-1920*1080.png" alt="">
<img src="../resources/风景-1920*1080.jpg" alt="">
<img src="../resources/city-1600*1600.png" alt="">
<img src="../resources/city-400*400.png" alt="">
<img src="../resources/sea.png" alt="">
<img src="../resources/shanghai-1280*853.jpg" alt="">
<img src="../resources/shenzhen-1280*826.jpg" alt="">
<img src="../resources/人物-1920*1080.png" alt="">
<img src="../resources/风景-1920*1080.jpg" alt="">
</div>
伸缩盒模型
简介
flex
布局,flex: 伸缩盒模型,flex布局是css3新增的布局方式,主要用于实现响应式布局。
1.2009年,Flexible Box布局被W3C纳入CSS3规范中,2012年成为W3C推荐标准。
2.它可以轻松控制: 元素分布方式,对齐方式,元素视觉顺序等
3.兼容性: 部分IE不支持,其余均已支持
4.伸缩盒模型的出现,逐渐成为一套新的布局方式
注意:
1.传统布局方式: 基于传统盒模型,主要靠 display属性 + position属性 + float属性等实现布局
2.flex布局目前在移动端应用广泛,因为传统布局不能很好的呈现在移动设备上
伸缩容器和伸缩项目
伸缩容器: 通过设置display: flex;
或display: inline-flex;
来创建伸缩容器,容器内的子元素称为伸缩项目
一个元素既可以是伸缩容器,也可以是伸缩项目
伸缩项目: 伸缩项目的子元素自动成为伸缩项目
仅伸缩项目的子元素成为伸缩项目,孙子元素,重孙元素等不是伸缩项目
属性值
inline-flex
: 将容器设置为行内伸缩容器
<style>
.container {
width: 600px;
height: 300px;
background-color: grey;
display: inline-flex;
}
.inner1,
.inner2,
.inner3 {
background-color: aqua;
height: 100px;
width: 100px;
border: 1px solid black;
box-sizing: border-box;
}
</style>
<div class="container">
<div class="inner1">1</div>
<div class="inner2">2</div>
<div class="inner3">3
<div class="inner3-1">3.1</div>
<div class="inner3-1">3.2</div>
<div class="inner3-1">3.3</div>
</div>
</div>
<div class="container">
<div class="inner1">1</div>
<div class="inner2">2</div>
<div class="inner3">3
<div class="inner3-1">3.1</div>
<div class="inner3-1">3.2</div>
<div class="inner3-1">3.3</div>
</div>
</div>
两个伸缩容器像行内块一样横向排列,由于浏览解析行内元素或行内块元素之间的换行时会变成空格,因此两个容器之间会有空格
但是我们一般不用inline-flex
,我们可以完全把他们两个容器的父容器变为伸缩容器,这样做后两个伸缩容器之间也不会存在空格
特点
伸缩容器只对子元素有布局效果
伸缩容器只对子元素有布局效果
不管伸缩容器的子元素是块元素,行内元素,还是行内块元素,成为伸缩项目后,都会块状化,变为块元素
行内元素也能设置宽高,变成了块元素
不脱离文档流,不会因为弹性容器没有指定高度产生塌陷问题
容器的主轴与侧轴方向
主轴方向: 伸缩容器的子元素排列的默认方向,默认是水平方从左到右方向,称为主轴方向
侧轴方向: 伸缩容器的子元素排列的垂直方向,称为侧轴方向,默认是垂直方向从上到下方向
侧轴始终与主轴垂直,主轴方向一旦改变,侧轴方向也会改变
flex-direction
改变容器主轴方向
作用:
改变伸缩项目的排列顺序
属性值:
row
: 设置主轴方向,默认是水平方向从左到右
此时侧轴方向是垂直方向从上到下
row-reverse
: 设置主轴方向,水平方向从右到左
此时侧轴方向是垂直方向从上到下
column
: 设置主轴方向,垂直方向从上到下
此时侧轴方向是水平方向从左到右
column-reverse
: 设置主轴方向,垂直方向从下到上
此时侧轴方向是水平方向从左到右
flex-wrap
主轴换行方式
flex-wrap: nowrap
: 默认值,不换行
伸缩项目元素根据主轴方向依次排序,并且不换行,如果总的伸缩项目宽度大于伸缩容器的宽度,每个伸缩项目宽度会被平均压缩,改变了已设置的伸缩项目宽度
这也体现了伸缩的效果
属性值:
nowrap
: 默认值,不换行,所有伸缩项目在一行内显示,宽度会被平均压缩
wrap
: 换行,当伸缩容器的宽度容不下伸缩项目时,伸缩项目就会换行
wrap-reverse
: 反向换行,即向上换行,也就是伸缩项目开始从伸缩容器左下角开始向右下角依次排列,当容不下时向上换行继续排列
flex-flow
复合属性(几乎不用)
flex-flow: flex-direction flex-wrap;
: 复合属性,设置主轴方向和换行方式
flex-flow: row-reverse wrap;
效果如下
justify-content
主轴对齐方式
justify-content
: 直译为调整内容
作用:
改变伸缩项目的对齐方式,并不能改变排列顺序,通过flex-direction
改变主轴方向从而改变排列顺序
属性值:
flex-start
: 默认值,主轴起始位置对齐,伸缩项目整体向主轴反方向对齐
flex-end
: 主轴结束位置对齐,伸缩项目整体向主轴方向对齐
center
: 主轴居中对齐,伸缩项目整体在主轴方向居中对齐
space-around
: 伸缩项目在主轴方向均等间隔排列,并且伸缩项目与伸缩容器边缘的距离是伸缩项目间距的一半
space-between
: 伸缩项目在主轴方向均等间隔排列,并且伸缩项目与伸缩容器边缘没有距离
space-evenly
: evenly直译为均匀,伸缩项目在主轴方向均等间隔排列,并且伸缩项目与伸缩容器边缘的距离是伸缩项目之间的距离
注意
justify-content
对齐方式呈现的效果受flex-direction
影响,主轴方向改变,对齐位置也发生改变
justify-content: space-between
使用比较多
align-items
侧轴方向项目对齐方式,适用于伸缩容器中只有一行伸缩项目的情况
属性值:
flex-start
: 侧轴起始位置对齐,伸缩项目整体向侧轴反方向对齐
flex-end
: 侧轴结束位置对齐,伸缩项目整体向侧轴方向对齐
center
: 侧轴居中对齐,伸缩项目整体在侧轴方向居中对齐
baseline
: 侧轴基线对齐,各个伸缩项目在侧轴方向基线对齐
stretch
: 默认值,侧轴拉伸对齐,把各个伸缩项目拉伸对齐,生效前提是伸缩项目高度没有设置,则伸缩项目会拉伸到伸缩容器的高度
align-content
侧轴方向项目对齐方式,适用于伸缩容器中有多行伸缩项目的情况
默认情况下主轴不换行,这样会影响align-content
属性生效,浏览器会提示flex-wrap: nowrap;
属性会阻止align-content
属性生效
因此要想让align-content
属性生效,必须设置flex-wrap: wrap;
或flex-wrap: wrap-reverse;
在伸缩容器设计中,为什么每行伸缩项目的高度规定由当前行最高的一个伸缩项目决定
1.确保同行项目对齐,提升视觉一致性
Flexbox 的核心目标是实现灵活且一致的布局。如果同一行内的项目高度不一致,会导致视觉上的割裂感。
2.响应式布局的适应性
动态内容(如异步加载的文本或图片)可能导致布局频繁跳动(Layout Shift)。
统一行高后,容器能更稳定地适应内容变化,提升用户体验。
3.简化布局控制
开发者无需手动计算或设置每个项目的高度,Flex 容器自动根据内容调整行高。
4.与其他布局模型的对比
传统块级元素:元素垂直堆叠,高度独立,但难以实现同行对齐。
行内元素(Inline):依赖基线对齐(Baseline Alignment),可能导致行高不可控。
align-content
属性值
flex-start
: 侧轴起始位置对齐,伸缩项目整体向侧轴反方向对齐
如下图,总共有三行,在侧轴方向上每行伸缩项目之间没有间距,并整体向侧轴起始位置对齐
flex-end
: 侧轴结束位置对齐,伸缩项目整体向侧轴方向对齐
center
: 侧轴居中对齐,伸缩项目整体在侧轴方向居中对齐
space-around
: 伸缩项目在侧轴方向均等间隔排列,并且伸缩项目与伸缩容器边缘的距离是伸缩项目间距的一半
space-between
: 伸缩项目在侧轴方向均等间隔排列,并且伸缩项目与伸缩容器边缘没有距离
space-evenly
: 伸缩项目在侧轴方向均等间隔排列,并且伸缩项目与伸缩容器边缘的距离是伸缩项目之间的距离
stretch
: 默认值,侧轴拉伸对齐,把各个伸缩项目拉伸对齐,生效前提是伸缩项目高度没有设置,则伸缩项目高度相同,并且每行伸缩项目都相同,整体高度等于容器高度
伸缩项目水平垂直居中
方案一设置容器的对齐方式:
/* 水平居中 然后垂直居中 */
justify-content: center;
align-items: center;
方案二设置项目的外边距:
margin: auto;
margin: auto不能垂直居中,在绝对定位或flex容器中可以垂直居中,他们有什么区别
当绝对定位元素同时设置 top: 0 和 bottom: 0 时,浏览器会为垂直方向创建明确的剩余空间。
margin: auto 会同时作用于水平和垂直方向,自动分配剩余空间,实现居中
Flex容器的默认侧轴对齐方式是align-items: stretch
,这会导致:
垂直空间自动分配:所有伸缩项目在交叉轴(默认是垂直方向)上被拉伸以填满容器高度(假设容器有固定高度)。
效果:即使子元素没有设置高度,也会占据父容器的全部高度。
因此伸缩项目就在垂直方向有了剩余空间,margin: auto 在上下外边距自动计算时,也就有值了。
设置项目在主轴上的基准长度
flex-basis
属性设置项目在主轴上的基准长度,默认值是auto
,即由项目自身决定。
如果主轴是横向,那么flex-basis
就是项目的宽度;如果主轴是纵向,那么flex-basis
就是项目的高度。会让已经设置的宽高失效
flex-basis: 200px;
伸缩项目自动伸长flex-grow
属性
flex-grow
属性设置每个伸缩项目自动伸缩比例,默认值是0
,即不伸缩。属性在伸缩项目上使用
当伸缩项目在容器中有剩余空间时,每个伸缩项目会根据flex-grow
属性值的比例进行伸缩
规则:
1.若flex-grow值为1,他们将等分剩余空间
2.若三个伸缩项目分别设置1,2,3,则瓜分到的剩余空间的比例是1/6,2/6,3/6
控制台带有箭头的区域代表盒子宽度增加的区域
分别对项目设置1,2,3,则瓜分到的剩余空间的比例是1/6,2/6,3/6
伸缩项目自动压缩
当容器不设置换行时,并且容器高或宽容不下伸缩项目时,伸缩项目就会压缩,控制台左箭头区域代表盒子宽度减少的区域
自动压缩的条件: 容器不能换行
下面分析压缩过程
当容器容不下项目时,项目会自动压缩
当设置容器换行时,容不下盒子3,因此换行
换行后是多行,每行都存在空间,因此再使用flex-grow
属性,则每行都等分剩余空间
flex-shrink
属性设置伸缩项目主轴方向自动压缩比例
属性值:
0
: 伸缩项目不压缩
1
: 默认值,根据比例压缩,和flex-grow
计算比例方式不一样,flex-grow: 1
是伸长区域是剩余空间平分后的空间
flex-shrink: 1
: 比例计算方式
项目压缩比例 = 项目自身宽度 / 当前行总的项目总宽度
项目压缩空间 = 剩余空间 * 项目压缩比例,即项目压缩区域
如下图,把容器宽度缩小,每个项目宽度始终保持一定相对比例,也就是说,容器压缩的空间,按照项目自身的宽度比例进行分配压缩
如果对每个项目设置不同的flex-shrink值,那么压缩比例计算方式
例如: 三个项目宽度分别为200px,300px,200px,分别设置flex-shrink: 1
, flex-shrink: 2
, flex-shrink: 3
,容器宽度收缩了300px
比例分母 = 200 * 1 + 300 * 2 + 200 * 3 = 1200
项目1压缩比例 = (项目自身宽度 * 自身flex-shrink值) / 比例分母 = 200 * 1 / 1200 = 0.167
项目2压缩比例 = (项目自身宽度 * 自身flex-shrink值) / 比例分母 = 300 * 2 / 1200 = 0.333
项目3压缩比例 = (项目自身宽度 * 自身flex-shrink值) / 比例分母 = 200 * 3 / 1200 = 0.5
计算最终的收缩大小:
项目1收缩大小 = 300 * 0.167 = 50px
项目2收缩大小 = 300 * 0.333 = 100px
项目3收缩大小 = 300 * 0.5 = 150px
如果控制台中的盒子宽度和计算后的盒子宽度不一致,都是因为浏览器也把盒子边框参与了计算,只需要把盒子边框去掉,就不会出现这种情况
容器收缩,即使收缩为0,仍然会保持项目内容的呈现
主轴方向改变后,flex-shrink
属性指的是高度压缩比例
<style>
.container {
width: 350px;
height: 400px;
background-color: grey;
margin: 0 auto;
margin-top: 50px;
display: flex;
flex-direction:column;
align-content: start;
}
.inner {
background-color: aqua;
border: 1px solid black;
box-sizing: border-box;
flex-grow: 1;
}
.inner1 {
width: 100px;
height: 100px;
}
.inner2 {
width: 100px;
flex-basis: 200px;
}
.inner3 {
width: 100px;
height: 100px;
}
</style>
<div class="container">
<div class="inner inner1">1</div>
<div class="inner inner2">2</div>
<div class="inner inner3">3</div>
</div>
flex
复合属性
flex: flex-grow flex-shrink flex-basis
可以通过工具查看简写样式代表的哪些属性
flex: 1 1 auto
简写flex: auto
/* flex-grow: 1; */
/* flex-shrink: 1; */
/* flex-basis: 100px; */
/* 复合属性 */
/* flex: 1 1 auto; */
/* 简写 */
flex: auto;
flex: 1 1 0
简写flex: 1
1: 比例拉伸
1: 比例压缩
0: 基准长度为0px
flex: 1 1 0
可简写为flex: 1
由于可以按照比例拉伸,因此项目产生拉伸仍然可以填充容器的剩余空间
flex: 1 0 auto
简写flex: none
flex: 0 0 auto
: 不拉伸,不压缩,不设置基准长度
可简写为flex: none
flex: 0 1 auto
简写flex: 0 auto
即flex初始值
flex: 0 1 auto
: 不拉伸,压缩,不设置基准长度
简写: flex: 0 auto
项目排序
order
属性设置伸缩项目的排序,默认值是0,数字越小越靠前,数字越大越靠后
作用: 不需要修改代码顺序,就能调整项目排序
align-self
设置单个项目在侧轴方向对齐方式
align-self
属性设置单个项目在侧轴方向对齐方式,默认值是auto
,auto
表示继承父容器的align-items
属性值,即父容器的侧轴方向对齐方式
响应式布局
例如,小米网站根据浏览器大小自动调整样式,浏览器宽度变窄使导航栏收纳为折叠样式
响应式布局离不开媒体查询,例如,设备类型,屏幕宽高等
媒体查询
媒体类型
@media print
: 适用于打印机设备,例如打印预览、打印机等
<style>
h1 {
height: 200px;
width: 200px;
line-height: 200px;
text-align: center;
background-image: linear-gradient(to right, #ff0000, #ffff00);
color: white;
text-shadow: 1px 1px 3px #000;
}
/* 只有在打印机上或打印机预览时,会覆盖掉之前的样式 */
/* @media print {
h1 {
background: transparent;
}
} */
</style>
<h1>你好啊!</h1>
上面代码中,没有添加媒体查询,在打印时勾选背景颜色,预览样式和页面样式一致
当添加媒体查询时,在打印预览时,就会覆盖掉之前的样式,是背景色变为透明
以上对比就是媒体查询时添加不同样式的效果,媒体查询的样式没有提高优先级,仍然遵循CSS样式优先级,也就是说如果把媒体查询样式放在h1样式前面,则媒体查询样式不会生效。
媒体查询样式一般都会放在最后书写,用于不同设备下覆盖原始样式
@media screen
: 适用于屏幕设备,例如:PC、平板电脑、手机等
@media screen {
h1 {
font-style: italic;
}
}
只有在屏幕时显示斜体,那么在打印时就不会显示斜体
@media all
: 适用于所有设备,包括打印机、屏幕等
媒体特性
@media (width:500px)
视口宽度为500px时应用样式
/* 检查视口宽度为500px,应用以下样式 */
@media (width:500px) {
h1 {
background-color: red;
}
}
@media (max-width:500px)
视口宽度小于等于500px时应用样式
/* 检查视口宽度小于等于500px,应用以下样式 */
@media (max-width:500px) {
h1 {
background-color: red;
}
}
@media (min-width:500px)
视口宽度大于等于500px时应用样式
/* 检查视口宽度大于等于500px,应用以下样式 */
@media (min-width:500px) {
h1 {
background-color: red;
}
}
@media (max-height:500px)
视口高度小于等于500px时应用样式
@media (device-width:2048px)
检测设备屏幕宽度
@media (device-width:2048px) {
h1 {
background-color: orange;
}
}
设备屏幕在2048px时,应用样式
@media (orientation:landscape|portrait)
: 检测设备屏幕方向是否为横向|竖屏,如果为横向|竖屏,则应用样式
完整列表参考: CSS3媒体查询有哪些
媒体查询运算符
逻辑与运算符,表示同时满足多个条件
and
表示同时满足多个条件
@media (min-width:500px) and (max-width:600px)
: 视口宽度大于等于500px且小于等于600px时,应用样式
@media screen and (min-width:500px) and (max-width:600px)
: 屏幕设备,视口宽度大于等于500px且小于等于600px时,应用样式
逻辑或运算符,表示满足其中一个条件即可
,
表示满足其中一个条件即可,,
可以替换为or
@media (min-width:600px), (max-width:800px)
: 视口宽度大于等于600px或小于等于800px时,应用样式
@media screen and ((max-width:600px) or (min-width:800px))
: 屏幕设备,并且视口宽度小于等于600px或大于等于800px时,应用样式
多个条件值组成一个条件时需要用()
括起来,否则无效
否定运算符,表示不满足某个条件
not
表示不满足某个条件
@media not (min-width:500px)
: 视口宽度小于500px时,应用样式
肯定运算符
only
表示肯定运算符,表示一定满足条件时,应用样式
用途让IE浏览器不应用样式:
有些属性IE不兼容时,添加only
运算符,IE由于不识别onlu因此对应的样式不会生效
@media only screen and (min-width:500px)
: 当用户使用IE浏览器时,对应的样式不生效,因为IE不识别only
运算符
常用阈值
根据不同的媒体条件,引入不同的样式
结合外部样式引入
方式一:
<link rel="stylesheet" href="./small.css">
@media screen and (max-width:600px) {
h1 {
background-color: green;
}
}
方式二:
查询条件放到中
<link rel="stylesheet" href="./small.css" media="screen and (max-width:600px)">
h1 {
background-color: green;
}
BFC
区块格式化上下文(Block Formatting Context,BFC)是 Web 页面的可视 CSS 渲染的一部分,是块级盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域
概念:
1.BFC(Block Formatting Context)块级格式化上下文,可以理解为元素的特异功能
2.该特性功能,在默认情况下处于关闭状态,当元素满足了某些条件后,就会开启BFC特性功能
3.所谓激活了特异功能,专业点就是说,该元素创建了BFC,又称开启了BFC
开启BFC能解决什么问题
1.元素开启BFC后,其子元素不再产生margin塌陷问题
2.元素开启BFC后,自己不会受其他浮动元素影响
3.元素开启BFC后,就算其子元素浮动,元素自身的高度也不会塌陷
哪些元素会开启BFC
1.根元素(html)自动开启
2.浮动的元素
3.绝对定位、固定定位的元素
4.行内块元素
5.表格单元格: table、thead、tbody、tfoot、td、th、caption
6.overflow属性值不为visible的元素
7.伸缩项目
8.多列容器
9.column-span属性为all的元素,即使该元素没有包裹在多列容器中
10.display:flow-root的元素
/* float:left; */
/* position: absolute; */
/* display: inline-block; */
/* display: table; */
/* overflow: hidden; */
/* column-count: 1; */
/* display: flow-root; */
验证开启BFC的元素能够解决问题1
body设置为伸缩容器,使父元素成为伸缩项目后,其子元素margin不会塌陷
验证开启BFC的元素能够解决问题2
验证开启BFC的元素能够解决问题3