CSS(Cascading Style Sheet)层叠级联样式表 {#csscascading-style-sheet层叠级联样式表}
CSS3 概述 {#css3-概述}
- CSS3 在 CSS2 版本的基础上,新增了很多特性,例如边框圆角、动画效果。
- 在 CSS2 的时代,实现圆角必须要用图片才能实现,而 CSS3 只要一行样式就能实现圆角。
- 在 CSS3 的时代,动画效果一定要使用 JavaScript 配合复杂的 CSS 样式操作才能实现(或者用 jQuery 这种第三方库)。CSS3 同样可以简单地实现动画效果,而且效果更佳。
- 早些年头,因为浏览器的兼容问题,并未广泛引用,但是近几年,随着随着各大浏览器厂商的标准化,大家可以畅快第使用 CSS3 了
CSS3 新特性 {#css3-新特性}
- 边框圆角
- 阴影
- 形变:旋转、缩放、位移
- 过渡效果
- 动画效果
- 媒体查询
- flex 布局
- grid 布局
等等(选择器、字体)......
CSS的三种导入方式 {#css的三种导入方式}
行内(内联)样式 {#行内内联样式}
<!--内联样式权重高于嵌入样式,不建议使用,用得越多就越难维护-->
<h1 style="color: yellow">标题</h1>
嵌入样式 {#嵌入样式}
<style>
h1{
color: red;
}
</style>
外部样式(推荐) {#外部样式推荐}
- HTML文件中使用link标签引入外部样式(链接式)
<link rel="stylesheet" href="CSS/style.css">
- HTML文件中在style标签内使用@import(导入式)
<style>
/*CSS 2.1所特有的写法,不推荐使用*/
@import url("我的第一个CSS程序/CSS/style.css");
</style>
- CSS文件
/*CSS注释*/
h1{
color: blue;
}
三种方式的优先级 {#三种方式的优先级}
- 行内样式最优先
- 内部样式和外部样式谁后执行谁生效
选择器 {#选择器}
基本选择器 {#基本选择器}
id选择器 {#id选择器}
#id-name{
`}
`
标签选择器 {#标签选择器}
/*选择P标签*/
p{
`}
`
类选择器 {#类选择器}
.class-name{
`}
`
<!--一个标签可以加多个class-->
<h1 class="class1 class2">
hello
</h1>
通配符选择器 {#通配符选择器}
*{
`}
`
选择器优先级 {#选择器优先级}
相同选择器:后面的覆盖前面的 {#相同选择器后面的覆盖前面的}
不同选择器:id选择器(100)>class选择器(10)>标签选择器(1) {#不同选择器id选择器100class选择器10标签选择器1}
层级选择器:按权重累加计算 {#层级选择器按权重累加计算}
<style>
/*100+10=110*/
.box #txt{
color:red;
}
/*100+1=101*/
#box2 h1{
color:blue;
/*color:blue !important;
这样写可以设置最高权重
*/
}
</style>
<div class="box" id="box2">
<h1 class="title title2" id="txt">
hello
</h1>
</div>
层级选择器 {#层级选择器}
后代选择器 {#后代选择器}
/*选中body标签下的所有P标签*/
body p{
`}
`
子代选择器 {#子代选择器}
/*只选中直属于body标签的P标签,不包括body中其他标签下的*/
body>p{
`}
`
相邻兄弟选择器 {#相邻兄弟选择器}
/*只选中属于class类的P标签的下一个P标签*/
.class+p{
`}
`
通用选择器 {#通用选择器}
/*选中所有属于class类的P标签向下的所有P标签*/
.class~p{
`}
`
组合选择器 {#组合选择器}
h1,h2{
`}
`
结构伪类选择器(条件) {#结构伪类选择器条件}
/*选中ul的第一个子元素*/
ul li:first-child{
}
/选中ul的最后一个子元素/
ul li:last-child{
}
/从当前p元素的父级元素下选择第2个元素,第2个元素是P才生效/
p:nth-child(2){
}
/从当前p元素的父级元素下选择第1个p元素/
p:nth-of-type(1){
}
/鼠标移动到a标签上时对a标签生效/
a:hover{
}
/鼠标移动到a标签上时对p标签生效/
a:hover \> p{
`}
`
伪元素选择器(增加元素) {#伪元素选择器增加元素}
/*
CSS2:伪类选择器和伪元素选择器都是一个冒号
CSS3:让伪元素选择器增加一个冒号
目前浏览器两者都支持
*/
h1::before{
content:"在h1前面"
}
h1::after{
content:"在h1后面"
}
`/`可以起到装饰作用`/
.classname::before,.classname::before{
content:"-----"
}
`
属性选择器 {#属性选择器}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.main a{
float: left;
color: #bd200d;
background: blue;
display: block;
text-align: center;
height: 50px;
width: 50px;
border-radius: 50px;
font: bold 20px/50px Arial;
margin-right: 10px;
text-decoration: none;
}
/*属性选择器
语法:a[]{}
[]中可以写属性名、属性名=属性值
= 绝对相等
*= 包含
^= 以这个开头
$= 以这个结尾
......
*/
/*存在id属性的元素*/
a[id]{
color: black;
}
/*id为特定值的元素*/
a[id="id1"]{
color: aqua;
}
/*id中存在2的元素*/
a[id*="2"]{
color: yellow;
}
/*class中存在b的元素*/
a[class*="b"]{
background: gray;
}
/*href中以http开头的元素*/
a[href^="http"]{
width: 100px;
}
/*href中以ppt结尾的元素*/
a[href$="ppt"]{
height: 100px;
}
/*a类中有id的元素*/
.a[id]{
width: 200px;
}
</style>
</head>
<body class="main">
<a href="https://www.baidu.com" class="a b c" id="id1">1</a>
<a href="https://www.jd.com">2</a>
<a href="https://www.taobao.com">3</a>
<a href="image/a.png" class="a" id="id2">4</a>
<a href="image/b.jpg" class="b" id="id3">5</a>
<a href="video/c.mp4" class="c">6</a>
<a href="audio/d.mp3">7</a>
<a href="file/e.ppt" class="a c">8</a>
<a href="file/f.docx" class="b c">9</a>
<a href="file/g.xls" class="a b">10</a>
</body>
</html>
美化网页元素 {#美化网页元素}
字体样式 {#字体样式}
<!--
font-family: 字体(中英文字体用,隔开);
font-size: 字体大小(单位px,em......);chrom浏览器最小值为12px
font-weight: 字体粗细(bold 粗体,也可以用数字);
color: 字体颜色;
line-height: 行高;
font-style: 字体风格(oblique 斜体);
-->
<style>
body{
font: oblique bold 20px/50px "楷体";
}
a{
font-family: "Times New Roman" ,楷体;
font-size: 50px;
font-weight: bold;
color: red;
line-height: 50px;
font-style: oblique;
}
</style>
文本样式 {#文本样式}
<!--
color颜色:
1.单词(red,green,blue...)
2.RGB(color:rgb(0,255,0))
3.RGBA(color:rgba(0,0,255,0.1))
R:红(0~255)
G:绿(0~255)
B:蓝(0~255)
A:透明度(0~1)
排版水平居中 text-align: center;
首行缩进2字符 text-indent: 2em;
行高和块的高度一致时就可以上下居中:
height: 200px;
line-height: 200px;
下划线 text-decoration: underline;
中划线 text-decoration: line-through;
上划线 text-decoration: overline;
去划线 text-decoration: none;
垂直居中 vertical-align: middle;
--\>
\<style\>
h1{
color: rgba(0,255,0,20%);
text-align: center;
}
p{
text-indent: 2em;
height: 200px;
line-height: 200px;
text-decoration: underline;
}
/去超链接的下划线/
a{
text-decoration: none;
}
/多标签选择器/
img,span{
/垂直居中排列/
vertical-align: middle;
}
\</style\>
`<p>
<img src="../Resources/image/Cover.jpg">
<span>文字</span>
</p>
`
超链接伪类 {#超链接伪类}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
/*初始状态*/
a{
color: black;
text-decoration: none;
}
/*鼠标悬停状态*/
a:hover{
color: orange;
}
/*鼠标按住未释放的状态*/
a:active{
color: blue;
}
/*以上三个可以同时存在,都能生效*/
/*链接被访问过的状态*/
a:visited{
color: gray;
}
/*链接未被访问过的状态*/
a:link{
color: red;
}
/*visited和link优先级最高,只要有一个生效,其他的就不生效了*/
</style>
</head>
<body>
<a href="https://www.baidu.com????" target="_blank">百度</a>
</body>
</html>
文字阴影(text-shadow) {#文字阴影text-shadow}
<style>
p{
color: gray;
/*text-shadow: 阴影颜色 水平偏移(允许负值) 垂直偏移(允许负值) 模糊距离*/
text-shadow: #bd200d 5px 5px 2px;
}
</style>
<p>Hello word!</p>
列表样式(list-style) {#列表样式list-style}
- none:去掉圆点
- circle:空心圆
- square:方块
- decimal:数字
- inside:列表样式在边距之内
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#nav{
background: gray;
width: 180px;
height: 140px;
}
.title{
color: black;
font-size: 15px;
font-weight: bold;
height: 30px;
line-height: 30px;
background: red;
text-indent: 1em;
margin-bottom: -10px;
}
ul li{
height: 20px;
list-style: none;
}
a{
color: #090909;
font-size: 10px;
text-decoration: none;
}
a:hover{
color: orange;
text-decoration: underline;
}
</style>
</head>
<body>
<div id="nav">
<h2 class="title">全部商品分类</h2>
<ul>
<li><a href="#">图书</a> <a href="#">居家</a></li>
<li><a href="#">电器</a> <a href="#">服装</a></li>
<li><a href="#">数码</a> <a href="#">办公</a></li>
<li><a href="#">彩票</a> <a href="#">食品</a></li>
</ul>
</div>
</body>
</html>
背景 {#背景}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body{
/*渐变色*/
background-color: #4158D0;
background-image: linear-gradient(13deg, #4158D0 0%, #C850C0 46%, #FFCC70 100%);
}
div{
height: 1000px;
width: 1000px;
/*border:边框宽度,边框样式(solid实线),边框颜色*/
border: 1px solid red;
background-image: url("../../Resources/image/kl.jpg");
/*默认是平铺的*/
background-repeat: repeat;
}
#div1{
/*横向平铺*/
background-repeat: repeat-x;
}
#div2{
/*纵向平铺*/
background-repeat: repeat-y;
}
#div3{
/*不平铺*/
background-repeat: no-repeat;
background-position: 100px 200px;
}
</style>
</head>
<body>
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
<div id="div4"></div>
</body>
</html>
盒子模型 {#盒子模型}
margin:外边距 :top\right\bottom\left padding内边距 :top\right\bottom\left border:边框:width\style\color(border属性简写的三个值是没有顺序要求的)
border-style:
| 值 | 描述 | |--------|--------| | none | 定义无边框 | | dotted | 定义点状边框 | | dashed | 定义虚线 | | solid | 定义实线 | | double | 定义双线 |
元素宽高计算 {#元素宽高计算}
- 默认情况下
元素的实际宽度 = border-left + border-right + width + padding-left + padding-right;
元素的实际高度 = border-top + border-bottom + width + padding-top + padding-bottom;
- 设置box-sizing:border-box;(很方便的属性)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
/*元素边距初始化*/
*{
margin: 0;
padding:0;
box-sizing:border-box;
}
#login{
border: 1px solid gray;
/*auto自动对齐实现元素水平居中*/
margin: 0 auto;
padding: 0;
width: 300px;
}
#login div:nth-of-type(1) input{
/*border:粗细 样式(solid:实线,dashed:虚线) 颜色*/
border: 3px solid black;
}
#login div:nth-of-type(2) input{
border: 3px dashed red;
}
form{
background-color: orange;
}
input[type=submit]{
color: #bd200d;
background-color: #C850C0;
}
input[type=submit]:hover{
color: #4158D0;
}
#app>div>img{
width: 100px;
height: 100px;
/*设置边框圆角*/
border-radius: 50px;
/*居中*/
display: block;/*把img从内联元素变为块元素*/
margin: 0 auto;
/*设置边框阴影*/
/* 颜色 水平偏移 垂直偏移 模糊距离*/
box-shadow: #bd200d 0px 0px 20px;
}
</style>
\</head\>
\<body\>
\<div id="app"\>
\<div\>
\<img src="../../Resources/image/kl.jpg"\>
\</div\>
\<div id="login"\>
\<h2\>会员登录\</h2\>
\<form action="#"\>
\<div id="username"\>
\<span\>用户名:\</span\>
\<input type="text"\>
\</div\>
\<div\>
\<span\>密码:\</span\>
\<input type="password"\>
\</div\>
\<div\>
\<input type="submit" value="登录"\>
\</div\>
\</form\>
\</div\>
`</div>
</body>
</html>
`
浮动 {#浮动}
- 块元素:可以设置宽度和高度,独占一行
<h1></h1> <p></p> <div></div> <ul></ul> <li></li>
- 行内/内联元素:不可以设置宽度和高度,不独占一行
<span></span> <a></a> <strong></strong>
- 行内块元素:可以设置宽度和高度,不独立成行
<img> <input> <button></button>
display属性(改变元素的分类) {#display属性改变元素的分类}
- block:转换为块元素
- inline:转换为行内元素
- inline:block:转换为行内块元素
- none:隐藏元素
两个div在同一行显示 {#两个div在同一行显示}
将元素设置为浮动元素(float),块元素可以在同一行显示,脱离文档流
==float属性的值:none\left\right==
行内元素可以被包含在块元素中,反之不可以
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div{
width: 100px;
height: 100px;
border:2px solid red;
display: inline-block;
float: right;
}
span{
width: 100px;
height: 100px;
border:2px solid red;
display:inline-block;
/*浮动*/
float: right;
/*
clear:何处不允许有浮动元素
both:左右两侧
right:右侧
left:左侧
*/
clear: both;
}
h1{
display: none;
}
</style>
`</head>
<body>
<div>div块元素</div>
<span>span行内元素</span>
<h1>消失不见</h1>
</body>
</html>
`
父级边框塌陷问题解决方案(清除浮动造成的不良影响) {#父级边框塌陷问题解决方案清除浮动造成的不良影响}
- 增加父级元素的高度
#father{
height: 100px;
}
- 增加一个空的div标签
<style>
.clear{
clear: both;
margin: 0;
padding: 0;
}
</style>
`<div id="father">
<!--在父级元素内部最下面-->
<div class="clear"></div>
</div>
`
- 在父级元素中加一个overflow
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#father{
border: 1px solid red;
overflow: hidden;
}
#father div img{
float: right;
}
</style>
</head>
<body>
\<div id="father"\>
\<div\>
\<img src="../../Resources/image/aimiliya.webp"\>
\</div\>
\<div\>
\<img src="../../Resources/image/kl.jpg"\>
\</div\>
\</div\>
`</body>
</html>
`
- ==在父类中加伪元素(推荐)==
.clear::before,.clear::after{
content: "";
display: block;
clear:both;
}
例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
<style>
*{
margin: 0;
padding: 0;
}
.clear::before,.clear::after{
content: "";
display: block;
clear:both;
}
.aside{
width: 50px;
height: 50px;
border:1px solid red;
float:left;
box-sizing: border-box;
}
.content{
width: 50px;
height: 50px;
border:1px solid red;
float:left;
box-sizing: border-box;
}
.box{
background-color:blue;
width: 300px;
height: 300px;
}
</style>
</head>
<body>
<div class="container clear">
<div class="content">
内容
</div>
<div class="aside">
边栏
</div>
</div>
<div class="box">
</div>
</body>
</html>
定位(position) {#定位position}
默认取值为static
相对定位(relative) {#相对定位relative}
对象遵循常规流,并且参照自身在常规流中的位置通过top,right,bottom,left这4个定位偏移属性进行偏移时不会影响常规流中的任何元素。特异性 ------移动元素后,元素本来占有的位置会保留,然后会相对原来的位置定位 。如图:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body>div{
display: block;
margin: 0 auto;
padding: 4px;
border: 2px solid red;
width: 300px;
height: 300px;
}
a{
color: white;
text-align: center;
line-height: 100px;
text-decoration: none;
background-color: pink;
display: block;
width: 100px;
height: 100px;
}
a:hover{
background-color: blue;
}
body>div>div:nth-of-type(2){
position: relative;
top: -100px;
right: -200px;
}
body>div>div:nth-of-type(4){
position: relative;
top: -100px;
right: -200px;
}
body>div>div:nth-of-type(5){
position: relative;
top: -300px;
right: -100px;
}
</style>
</head>
<body>
<div>
<div><a href="?">链接1</a></div>
<div><a href="?">链接2</a></div>
<div><a href="?">链接3</a></div>
<div><a href="?">链接4</a></div>
<div><a href="?">链接5</a></div>
</div>
</body>
</html>
绝对定位 {#绝对定位}
对象脱离常规流,此时偏移属性参照的是离自身最近的定位祖先元素,如果没有**已定位的(非static)**祖先元素,则一直回溯到body元素。盒子的偏移位置不影响常规流中的任何元素,其margin不与其他任何margin折叠。通常可以把父级元素设置为relative来改变默认的body元素 。如图:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body{
border: 2px solid red;
height: 2000px;
}
body>div{
display: block;
margin: 0 auto;
padding: 4px;
border: 2px solid red;
width: 300px;
height: 2000px;
}
a{
color: white;
text-align: center;
line-height: 100px;
text-decoration: none;
background-color: pink;
display: block;
width: 100px;
height: 100px;
}
a:hover{
background-color: blue;
}
body>div>div:nth-of-type(2){
position: sticky;
top: 300px;
right: -100px;
/*设置不透明度*/
opacity: 0.2;
}
body>div>div:nth-of-type(4){
position: absolute;
top: 0px;
right: 0px;
}
body>div>div:nth-of-type(5){
position: fixed;
bottom: 0px;
right: 0px;
}
</style>
</head>
<body>
<div>
<div><a href="?">1</a></div>
<div><a href="?">sticky</a></div>
<div><a href="?">3</a></div>
<div><a href="?">absolute</a></div>
<div><a href="?">fixed</a></div>
</div>
</body>
</html>
固定定位(fixed) {#固定定位fixed}
脱离文档流,默认参照物为浏览器视窗位置
常用于返回顶部等常驻页面的元素。
z-index {#z-index}
用整数值来定义堆叠级别。可以为负值。 数值大的在前方显示。
CSS3新特性 {#css3新特性}
边框圆角 {#边框圆角}
-
border-radius
:左上 右上 右下 左下 -
如果设置两个值,第一个值表示左上和右下,第二个值表示右上和左下。
border: 1px solid red;
-
四个角是一样的
border-radius: 50px;
-
左上 右上 右下 左下
border-radius: 10px 20px 30px 40px;
-
左上右下 右上左下
border-radius: 20px 40px;
-
高度宽度相同时,边框圆角设成 50%才能设成正圆。
border-radius: 50%;
阴影 {#阴影}
-
box-shadow: 10px 20px 30px blue;
参数分别表示:x 轴偏移量,y 轴偏移量,模糊半径,阴影颜色(不设置颜色为黑色)
box-shadow: 10px 20px 30px;
蓝色阴影
box-shadow: 10px 20px 30px blue;
x 轴偏移量为 100px;
box-shadow: 100px 20px 30px blue;
y 轴偏移量为 200px;
box-shadow: 10px 200px 30px blue;
模糊半径,越大越模糊
box-shadow: 10px 20px 50px blue;
形变transform {#形变transform}
-
rotate();旋转 deg 单位表示角度
/*顺时针旋转 45° 单位是 deg 角度*/ transform: rotate(45deg);
-
scale();缩放
/*缩放 0.5 倍*/ transform: scale(0.5);
-
translate();位移
/*位移 可以设百分数% 具体值单位是 px 横坐标向右位移 50px 纵坐标向下位移 100px*/ transform: translate(50px, 100px);
-
transform 都是同一个属性,分开写会被覆盖,所以多个形变要加空格
transform: rotate(45deg) translate(50px, 100px);
过渡效果transition {#过渡效果transition}
通过transition属性,可以设置元素的过渡效果,
==当某个属性被设置成过渡属性后,属性的值如果发生变化,就会以动画的形式从初始状态过渡到结束状态==
-
transition-property
过渡属性(例如 transform) -
transition-duration
过渡持续时间(例如 1s) -
transition-timing-function
过渡函数 -
transition-delay
过渡延迟时间
简写:transition: 属性 秒数 函数 延迟;
/* transition-property: transform; */
/* transition-duration:1s; */
transition: transform 1s ease 1s;
/* transition-property: transform; */
/* transition-duration:1s; */
transition: transform 1s;
设置多个值:transition: 属性 秒数,属性 秒数;
/* transition-property: transform; */
/* transition-duration:1s; */
/* transition-timing-function:ease; */
transition: transform 1s, width 1s, height 1s;
过渡属性transition-property {#过渡属性transition-property}
/* 形变 */
transition-property:transform;
/* 宽度 */
transition-property:width;
/* 外边距 */
transition-property:margin;
过渡持续时间transition-duration {#过渡持续时间transition-duration}
/*尽量不超过0.5s*/
transition-duration: 0.5s;
过渡函数transition-timing-function {#过渡函数transition-timing-function}
-
ease: 开始和结束慢,中间快。默认值。
-
linear: 匀速。
-
ease-in:开始慢。
-
ease-out: 结束慢。
-
ease-in-out: 和 ease 类似,但比 ease 幅度大。
过渡延迟时间transition-delay {#过渡延迟时间transition-delay}
transition-delay: 1s;
设置形变旋转原点 {#设置形变旋转原点}
transform-origin: 0 0;
以动画的形式从 0 到 45 度,这就是过渡效果。
overflow(设置溢出) {#overflow设置溢出}
正常情况下内容超出容器,会溢出。
-
设置成 hidden。会把溢出的内容隐藏。
overflow: hidden;
-
设置成 auto,如果哪边溢出哪边就显示滚动条
overflow: auto;
动画效果 {#动画效果}
动画与过渡的区别:
过渡效果通常用户与浏览器进行交互(例如 hover)
动画效果,可以交互,也可以在网页加载时直接执行,并且可以让效果更复杂。
动画属性(animation) {#动画属性animation}
-
animation-name
: 规定需要绑定到选择器的 keyframe 名称... -
animation-duration
: 规定完成动画所花费的时间,以秒或毫秒计。 -
animation-timing-function
: 规定动画的速度曲线函数. -
animation-delay
: 规定在动画开始之前的延迟。 -
animation-iteration-count
: 规定动画应该播放的次数。infinite 无限次
keyframes(定义动画) {#keyframes定义动画}
- 按百分比指定动画
- from...to...指定动画
注意:开始与结束相同,可以让动画更平滑
@keyframes anim {
0% {
transform: translate(0px, 0px);
}
100% {
transform: translate(900px, 100px);
}
}
`/* from:0%, to:100% */
from{
transform: rotate(0deg);
}
to{
transform: rotate(360deg);
}
`
停止动画效果 {#停止动画效果}
animation-play-state: paused;
旋转唱片 {#旋转唱片}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
@keyframes spin {
100%{
transform: rotate(360deg);
}
}
img{
height: 300px;
border-radius: 50%;
animation: spin 2s linear infinite ;
}
img:hover{
animation-play-state: paused;
}
</style>
</head>
<body>
<div class="img">
<img src="../images/jay.jpg" alt="">
</div>
</body>
</html>
flex 布局 {#flex-布局}
flex 是 flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性,任何一个容器都可以指定为 flex 布局。这是一种更先进的布局方式,可以让网页布局更简洁,更易于维护。
flex布局的元素会把自己的一级子元素排成一行,并将他们变成可以伸缩,易排列的盒子。当我们为父盒子设为 flex 布局以后,子元素的 float、clear 和 vertical-align 属性将失效。
伸缩布局=弹性布局=伸缩盒布局=弹性盒布局=flex 布局
flex 布局原理 {#flex-布局原理}
就是通过给父盒子添加 flex 属性,来控制子盒子的位置和排列方式
.box{
display: flex;
}
此容器会变成一个flex容器(flex container),容器内部的元素被称为flex项目(flex item),在这个容器内部浮动会失效,通过设置flex容器的css样式,可以改变内部项目的布局方式。
基本概念 {#基本概念}
将元素设置为 display:flex;元素会变为一个 flex 容器。容器内部的元素为 flex 元素或者叫 flex 项目(flex-item)。
- main axis:主轴
- cross axis:交叉轴
flex 容器中的默认效果 {#flex-容器中的默认效果}
父元素是默认充满宽度的
- flex 项目在 flex 容器中延主轴排列。并且块元素不会独立成行。
- flex 项目高度适应 flex 容器高度(同行内元素)
设置 flex 容器 {#设置-flex-容器}
关于主轴的属性 {#关于主轴的属性}
-
flex-direction:
设置 flex 项目排列方向,设置 主轴 的方向
flex-direction是flex控制横向延展还是纵向延展的属性。
值:
-
row(默认值): 主轴为水平方向 ,起点在左端 。 从左到右
row-reverse: 主轴为水平方向 ,起点在右端 。 从右到左 column: 主轴为垂直方向 ,起点在上沿 。 从上到下 column-reverse: 主轴为垂直方向 ,起点在下沿 。 从下到上
注意:使用这个属性之前一定要确定好主轴是哪个
-
-
justify-content:
flex 项目在 主轴 的排列方式
设置 主轴 上的子元素排列方式
值:
- flex-start(默认值): 左对齐 从头部开始 如果主轴是 x 轴,则从左到右 flex-end: 右对齐 从尾部开始排列 center: 居中 在主轴居中对齐 (如果主轴是 x 轴则水平居中) space-between: 两端对齐 ,项目之间的间隔都相等 平分剩余空间 space-around: 每个项目两侧的间隔相等 。所以,项目之间的间隔比项目与边框的间隔大一倍。先两边贴边 再平分剩余空间(重要) 类似于每个项目的 margin-left、margin-right 相等。
关于交叉轴的属性 {#关于交叉轴的属性}
-
align-items:
flex 项目在 交叉轴 的排列方式
设置侧轴上的子元素排列方式在子项为单项(单行)时使用
值:
- flex-start: 交叉轴的起点对齐 。 flex-end: 交叉轴的终点对齐 。 center: 交叉轴的中点对齐。 stretch(延申)(默认值):如果项目未设置高度或设为 auto ,将占满整个容器的高度。
-
align-content:
设置交叉轴 上的子元素排列方式(多行)只能用于子项出现换行的情况(多行),在单行下是没有效果的。
值:
- flex-start(默认值): 左对齐 从头部开始 如果主轴是 x 轴,则从左到右 flex-end: 右对齐 从尾部开始排列 center: 居中 在主轴居中对齐 (如果主轴是 x 轴则水平居中) space-between: 两端对齐 ,项目之间的间隔都相等 平分剩余空间 space-around: 每个项目两侧的间隔相等 。所以,项目之间的间隔比项目与边框的间隔大一倍。先两边贴边 再平分剩余空间(重要) 类似于每个项目的 margin-left、margin-right 相等。
其他属性 {#其他属性}
-
flex-wrap:
设置子元素是否换行
如果不设置换行,如果一行要满了,则项目的宽度会缩小。
默认的子元素是不换行的,如果装不开,会缩小子元素的宽度,放到父元素里面。
值:
-
nowrap:不换行;
wrap:换行。
-
-
flex-flow:
复合属性,相当于设置了 flex-direction 和 flex-wrap.
flex-flow: row wrap;
=flex-direction: row;
+flex-wrap: wrap;
设置 flex 项目 {#设置-flex-项目}
-
flex-grow:属性定义项目的放大比例,默认为 0 ,空间充足,等比例补全。
-
flex-shrink:定义了项目的缩小比例,默认为 1 ,即如果空间不足,该项目将缩小。
-
flex-basis:主轴排列为宽度,交叉轴排列为高度,设置 px ,默认值为 auto。
-
flex:综合上面的三个样式。flex 属性定义子项目分配 剩余空间 ,用 flex 来表示占多少份数(fraction)。
如果不设每个项目(3 个)的宽度只设容器宽度,那么
/* 1 份 */ flex: 1; /* 1 份 2 份 1 份 */ flex: 1; flex: 2; flex: 1;
-
align-self:flex 项目的对齐方式,控制子项自己在侧轴上的排列方式。
align-self 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖 align-items 属性。默认值为 auto,表示继承父元素的 align-items 属性,如果没有父元素,则等同于 stretch.
值:
- auto flex-start flex-end center baseline stretch
-
order 属性:
定义项目的排列顺序
数值越小,排列越靠前,默认为 0
注意: 与 z-index 不一样。
写 flex 布局的大概思路 {#写-flex-布局的大概思路}
-
将容器转换为 flex 容器。 display: flex;
-
先设置主轴方向
(默认的) x 轴
flex-direction: row;
y 轴
flex-direction: column;
-
设置主轴上子元素的排列方式(水平居中) justify-content: flex-start / flex-end / center / space-between / space-around
-
设置侧轴上子元素的排列方式(垂直居中) 单行找 align-items 多行找 align-content (单行) align-items: flex-start / flex-end / center / stretch (多行) 前提是要换行 flex-wrap:wrap; align-content: flex-start / flex-end / center / space-around / space-between / stretch
grid 布局 {#grid-布局}
grid布局与flex布局对比 {#grid布局与flex布局对比}
grid布局可以为网页提供更强大的布局功能,它与flex布局的区别是。
- flex布局为一维布局,一般一行或一列的布局使用flex布局。
- grid布局为二维布局,同时需要兼顾行与列的布局,可以使用gird布局。
如果不考虑兼容问题,flex布局和grid布局可以很好地替代浮动布局。
grid布局基本概念 {#grid布局基本概念}
grid容器的水平区域成为行(row),垂直区域成为列(column),行与列之间的交叉是单元格(cell),划分网格的线称为网格线(gird line),了解了这些基本概念之后,就可以开始用相应的css属性设置grid容器中的项目了
display: grid;
grid 容器属性 {#grid-容器属性}
-
grid-auto-flow
- row 默认排列方式(可以不写) 从左到右 从上到下
- colum 竖着排列 从左到右 从上到下
-
grid-template-columns与grid-template-rows
按像素来设置单元格 单元格与 grid 项目不一样的
grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px;
按比例来设置单元格
grid-template-columns: 100px 1fr 2fr; grid-template-rows: 100px 100px 100px;
grid 项目 在 单元格 中的 对齐方式 {#grid-项目-在-单元格-中的-对齐方式}
-
justify-items:
stretch 默认值 水平拉伸 start 单元格开始的位置(左) end 单元格结尾的位置(右) center 单元格居中的位置(中)
值:
- start 左 end 右 center 中 stretch 水平拉伸
-
align-items:
stretch 默认值 垂直拉伸 start 单元格开始的位置(上) end 单元格结尾的位置(下) center 单元格居中的位置(中)
值:
-
start 上
end 下
center 中
stretch 垂直拉伸
-
单元格 在整个 grid 的 容器 中的 对齐方式 {#单元格-在整个-grid-的-容器-中的-对齐方式}
-
justify-content:
值:
-
start
end
center
stretch
-
-
align-content:
值:
-
start
end
center
stretch
-
-
grid-auto-columns: 溢出列的尺寸
值:
- 数字 px;
-
grid-auto-rows:
溢出行的尺寸
值:
- 数字 px;
grid 项目属性 {#grid-项目属性}
grid 项目对齐方式 {#grid-项目对齐方式}
-
justify-self:
值:
- start 左 end 右 center 中 stretch 水平拉伸
-
align-self:
值:
- start 上 end 下 center 中 stretch 垂直拉伸
单元格合并 {#单元格合并}
-
横向合并单元格
grid-columns-start: 数字;
grid-columns-end: 数字;
简写:
grid-columns: 数字 / 数字;
-
纵向合并单元格
grid-rows-start: 数字;
grid-rows-end: 数字;
简写:
grid-rows: 数字 / 数字;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style type="text/css">
.container {
display: grid;
width: 800px;
height: 500px;
border: 1px solid red;
/* (可以不写)默认排列方式 从左到右 从上到下 123 456 789 */
grid-auto-flow: row;
/* 按像素来设置单元格 单元格与grid项目不一样的 */
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
/* 溢出列的尺寸 */
grid-auto-columns: 50px;
/* 溢出行的尺寸 */
grid-auto-rows: 50px;
}
.item {
border: 1px solid red;
}
.first {
/* 横向合并单元格 */
/* grid-column-start: 2;
grid-column-end:4; */
grid-column: 2 / 4;
/* 纵向合并单元格 */
grid-row: 2 / 4;
/* grid-row-start: 2; */
/* grid-row-end:4; */
/* 设置grid项目的对齐方式 */
/* justify-self: center;
align-self: center; */
}
</style>
\</head\>
`<body>
<div class="container">
<div class="item first">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<!-- <div class="item">10</div>
<div class="item">11</div> -->
</div>
</body>
</html>
`
媒体查询 {#媒体查询}
响应式页面概述 {#响应式页面概述}
这个是bootstrap的中文文档网站,大家可以用chrome浏览器来模拟手机端的浏览效果,可以看到手机端和电脑端访问同一个网页时,都能获得比较好的浏览体验。也就是说,一套代码可以同时适应多个设备。这样的网页就是响应式网页。
这样的网页,就是基于媒体查询实现的。
这里需要特别注意的是,我们访问同一个网站的地址,用手机可以正常浏览,用电脑也可以正常浏览,这并不一定就是响应式页面,例如晓舟报告官网就是响应式的,它只是针对终端设备的不同,展示了两套代码而已。响应式页面强调的是一套代码。
媒体查询 {#媒体查询-1}
通过媒体查询,我们让css检测到浏览器视窗的展示尺寸,然后根据不同的浏览器视窗尺寸设置不同的样式,进而实现了同一套代码适应不同设备的功能。
max-width {#max-width}
媒体查询是CSS3中增加的新特性,可以使用@media来定义不同的条件和样式,窗口尺寸(或设备尺寸)满足指定条件的时候才会应用指定的样式,实例代码如下所示。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.box{
width:200px;
height:200px;
background-color: red;
}
/* 小于指定宽度,样式生效 */
@media screen and (max-width:600px){
.box{
background-color: blue;
}
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
首先我们来看上面代码的效果,当全屏打开浏览器的时候(PC端的浏览方式),我们可以看到div元素的背景色为红色,当我们将浏览器的窗口缩小(移动端的浏览方式),当浏览器尺寸宽度小于600px的时候,元素的背景色会变成蓝色,这就是利用媒体查询实现的最基本的响应式页面,同一个文件,在不同设备上呈现着不同的样式。
在上面的代码中,max-width定义的就是标准,符合标准就会让下面的样式生效,max-width这个标准的意思就是:小于指定宽度,样式生效。
min-width
同样,我们也可以定义"大于指定宽度,样式生效",实例代码如下所示。
@media screen and (min-width:600px){
.box{
background-color: blue;
}
}
上述代码与demo01的效果刚好相反,PC端呈现蓝色,移动端呈现红色,min-width的意思是:大于指定宽度,样式生效。
多个标准
我们也可以给一个媒体查询定义多个标准,实例代码如下所示。
@media screen and (min-width:600px) and (max-width:900px){
.box{
background-color: blue;
}
}
通过上面的方法,我们可以定义一个有多个标准的媒体查询,在上面的代码中,窗口大于600px并且小于900px的时候,样式生效,我们可以将浏览器窗口由大到小的收缩,可以看到元素颜色变化了两次。
响应式页面的缺点 {#响应式页面的缺点}
在真实项目开发中,响应式页面并不常用,主要是因为一下几点。
- 为终端定制的页面,用户体验更好。
- 响应式页面代码量会增多,影响网页性能。
- 网页后期维护成本增加。
除非网页具备以下特点:
- 网页本身并不复杂。
- 对用户体验要求不高。
- 希望多终端访问,又希望降低开发成本。
就可以选择响应式页面了。
rem布局 {#rem布局}
PC端页面的网页重构,我们使用最多的单位是px。因为在PC端,大部分页面效果我们都可以设置成固定尺寸,但是在手机端,这种方案是不可行的,我们必须要按照百分比呈现页面,才能保证网页在任何设备上可以正常显示。为了实现这样的功能,我们可以将所有的尺寸都设置成百分比,但是这样会给前端开发带来大量的计算工作。为了实现百分比的效果,又能省去大量的计算工作,我们使用rem布局。
单位概述 {#单位概述}
-
px:像素
-
em:相对于父级的 font-size 值,父级的 font-size 值越大,子级的 em 就越大
-
rem:相对于 html 标签的 font-size 值
-
html font-size: N px; 1rem 代表 N px; 10rem 代表 10N px;
根据移动端浏览器宽度通过 js 来自适应 rem 单位 {#根据移动端浏览器宽度通过-js-来自适应-rem-单位}
利用rem单位可以制作出适应不同尺寸设备的页面。
首先考虑一个问题,rem的参照物是html元素的font-size属性,那么如果html的font-size属性不变的话,我们使用的rem单位仍然是一个固定的单位,所以我们需要做的是让html元素的font-size属性在不同的设备中设置不同的值,这就需要一段js代码了,代码如下所示(fontsizeset.js)
(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
docEl.style.fontSize = 100 * (clientWidth / 720) + 'px';
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
我们并不需要理解上面的这段代码是如何执行的,只需要知道这段代码可以检测设备的尺寸,并通过设备的尺寸设置html元素的font-size值,这个font-size值会根据设备尺寸的变化而变化,这样我们设置相同的rem值,就会起到百分比的作用了。
来看一个实际案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- 在html中引入fontsizeset.js文件 -->
<script src="fontsizeset.js"></script>
<style>
*{
margin:0px;
padding:0px;
}
.box{
width: 3.6rem;
height:3.6rem;
background-color: red;
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
在上面的代码中,我们将div的宽和高都设置成了3.6rem,用浏览器打开,发现元素宽度与高度相同,并且宽度始终是窗口宽度的50%。这说明rem布局与百分比布局能实现相同的效果。
四、设计稿量尺 {#四设计稿量尺}
我们再从web开发流程的角度来看,为什么rem布局比百分比布局更加简便,使用rem布局的流程如下所示:
- 首先,我们拿到设计师的设计稿,通常设计稿的宽度为640px、720px、1080px。
- 然后再来看看我们的fontsizeset.js文件中的一段代码,第二个数字720就是设计稿的宽度,如果设计稿是1080px,我们需要将fontsizeset.js中的720改成1080。
docEl.style.fontSize = 100 * (clientWidth / 720) + 'px';
- 最后量尺的时候,如果设计稿中的元素尺寸为x,那么元素的尺寸我们就可以设置成x/100rem(这个100就是上面代码中的第一个数字,具体示例可以看下一节内容)。
我们引入的js文件是720px的设计稿,那么假如设计稿中有一个360px的元素,则该元素广告就是原设计稿的一半,这样我们通过换算可以得到这个元素在网页中的尺寸是3.6rem,所以当我们设置成3.6rem的时候,不管视窗的尺寸如何变化,元素的宽度始终都是整个页面的50%。
通过上述的方法,就可以很容易制作出按百分比排列的页面布局了,这就是rem布局的优势。