通过line-height使得文字垂直居中,但是往往由于我们使用时,文字的宽度不固定,当出现下面的情况时,会让我们感觉通过line-height:使得文字处于水平垂直居中的错觉
<!DOCTYPE html>
<html lang="zh">
<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>
.box1{
/* height:50px; */
background-color: #bfa;
line-height:50px;
/* float:left; */
}
</style>
</head>
<body>
<div class="box1">
<span>在繁华中自律,在落魄中自愈</span>
</div>
</body>
</html>
通过使用line-height使得文字垂直居中了,但是很明显是没有水平居中的
下面的例子会使得,让我们觉得line-height能够使得文字除了垂直居中外,还能够水平居中的错觉
<!DOCTYPE html>
<html lang="zh">
<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>
.box1{
/* height:50px; */
background-color: #bfa;
line-height:50px;
float:left;
}
</style>
</head>
<body>
<div class="box1">
<span>在繁华中自律,在落魄中自愈</span>
</div>
</body>
</html>
上面之所以,会让我们觉得使用line-heigt使得文字水平垂直居中的错觉,是因为,.box1的宽度是由span里面的文字决定的,这里形成了水平居中的错觉,是.box1的宽度由span里面的文字决定的,才造成了我们认为line-height能够使得文字水平居中的错觉,但是line-height能够使得文字垂直居中,这一点不可否认
通过定位使得一个块元素在其父元素内水平垂直居中(有多种方式:第一种:left:0 right:0 top:0 bottom:0px margin:auto 第二种:直接进行计算出top等应该等于的非0值)
通过background-position使得背景图片在其父元素内水平垂直居中
通过verticle-align使得文字在其父元素内不是真正意义上的垂直居中(看bilibili视频中的第82和第83个视频就知道了)
通过在table中的td元素中,利用verticle-align:middle使得文字或者是其它的任何位于td中的子元素在td中垂直居中
通过浮动和外边距和内边距的配合,实现块元素在其父元素内水平垂直居中
注意:vertical-align本来是用来设置文字的垂直对齐样式的,但是如果把vertical-align放到td元素里面,那么它就变牛逼了,也就是此时在td中,通过设置vertical-align就可以影响到td中的所有的元素了,而不是像在非td元素中,设置vertical-align只能影响元素中的文字了,并且在td元素中设置vertical-align为middle就是真正意义上的垂直居中了,注意对这个地方的真正意义上的理解,这个可以去看对应的第82和第83个视频
最重要的一点是:要明确vertical-align和text-align一定是针对文字的,但是,有个特例,就是,在td(单元格)里面中设置verticle-align,那么这个verticle可以对td中的任何元素(块元素、行内元素、文字等)实现真正意义上的垂直居中了,或者是不实现真正意义上的垂直据中,实现任何元素的垂直对齐的其它方式(重点关注在于,td中设置vertical-align不再像在非td元素中设置vertical-align那样,只能文字的垂直对齐起作用),这里指的文字应该可以是a标签,以及div等块元素内的文字吧???,下去可以去测试下
上面中的文字可以是位于a标签中的文字,可以用下面的元素进行测试
<!DOCTYPE html>
<html lang="zh">
<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>
table{
width:50%;
border:1px solid black;
border-spacing:0px;
border-collapse:collapse;
}
td{
border:1px solid black;
height:100px;
vertical-align:middle;
text-align:center;
}
tbody > tr:nth-child(2n+1){
background-color: #bfa;
}
.box1{
width:300px;
height:300px;
background-color: orange;
display:table-cell;
vertical-align:middle;
}
.box2{
width:100px;
height:100px;
background-color: pink;
margin:0px auto;
}
.box3{
width:100px;
height:100px;
background-color: silver;
}
</style>
</head>
<body>
<div class="box1">
<div class="box2"></div>
aaa
</div>
<div class="box1">
<div class="box2"></div>
aaa
</div>
<div class="box3"></div>
bbb
<table>
<tr>
<td><a href="javascript">学号</a></td>
<td>姓名</td>
<td>性别</td>
<td>年龄</td>
<td>地址</td>
</tr>
<tr>
<td>1</td>
<td>孙悟空</td>
<td>男</td>
<td>18</td>
<td>花果山</td>
</tr>
<tr>
<td>2</td>
<td>猪八戒</td>
<td>男</td>
<td>28</td>
<td>高老庄</td>
</tr>
<tr>
<td>3</td>
<td>沙和尚</td>
<td>男</td>
<td>38</td>
<td>流沙河</td>
</tr>
<tr>
<td>4</td>
<td>唐僧</td>
<td>男</td>
<td>16</td>
<td>女儿国</td>
</tr>
</table>
</body>
</html>
验证text-align对块元素不起作用
<!DOCTYPE html>
<html lang="zh">
<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>
table{
width:50%;
border:1px solid black;
border-spacing:0px;
border-collapse:collapse;
}
td{
border:1px solid black;
height:100px;
vertical-align:middle;
text-align:center;
}
tbody > tr:nth-child(2n+1){
background-color: #bfa;
}
.box1{
width:300px;
height:300px;
background-color: orange;;
}
.box2{
width:100px;
height:100px;
background-color: pink;
text-align:center;
}
</style>
</head>
<body>
<div class="box1">
<div class="box2"></div>
</div>
<table>
<tr>
<td>学号</td>
<td>姓名</td>
<td>性别</td>
<td>年龄</td>
<td>地址</td>
</tr>
<tr>
<td>1</td>
<td>孙悟空</td>
<td>男</td>
<td>18</td>
<td>花果山</td>
</tr>
<tr>
<td>2</td>
<td>猪八戒</td>
<td>男</td>
<td>28</td>
<td>高老庄</td>
</tr>
<tr>
<td>3</td>
<td>沙和尚</td>
<td>男</td>
<td>38</td>
<td>流沙河</td>
</tr>
<tr>
<td>4</td>
<td>唐僧</td>
<td>男</td>
<td>16</td>
<td>女儿国</td>
</tr>
</table>
</body>
</html>
现在改为如下:
box2在box1中水平居中实现了,但是垂直据中,可以怎么实现呢?
除了利用定位等其它方法外,有没有其它的方式?
下面介绍一种利用表格中的单元格的形式(table-cell)的方式,table中的td其实就是table-cell(单元格)
注意上面box1中的display的使用,以及vertical-align是在把块元素设置为table-cell之后,再在box1中写vertical-align的,而不是把vertical-align写在box2中的,但是margin-align是写在box2中的
注意区分vertical-align,text-align与margin、bottom的区别
上面把box1这个块元素变成了tabel-cell单元格的形式,会有有什么影响呢?
例如:是否还独占一行?
<!DOCTYPE html>
<html lang="zh">
<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>
table{
width:50%;
border:1px solid black;
border-spacing:0px;
border-collapse:collapse;
}
td{
border:1px solid black;
height:100px;
vertical-align:middle;
text-align:center;
}
tbody > tr:nth-child(2n+1){
background-color: #bfa;
}
.box1{
width:300px;
height:300px;
background-color: orange;
display:table-cell;
vertical-align:middle;
}
.box2{
width:100px;
height:100px;
background-color: pink;
margin:0px auto;
}
.box3{
width:100px;
height:100px;
background-color: silver;
}
</style>
</head>
<body>
<div class="box1">
<div class="box2"></div>
aaa
</div>
<div class="box1">
<div class="box2"></div>
aaa
</div>
<div class="box3"></div>
bbb
<table>
<tr>
<td>学号</td>
<td>姓名</td>
<td>性别</td>
<td>年龄</td>
<td>地址</td>
</tr>
<tr>
<td>1</td>
<td>孙悟空</td>
<td>男</td>
<td>18</td>
<td>花果山</td>
</tr>
<tr>
<td>2</td>
<td>猪八戒</td>
<td>男</td>
<td>28</td>
<td>高老庄</td>
</tr>
<tr>
<td>3</td>
<td>沙和尚</td>
<td>男</td>
<td>38</td>
<td>流沙河</td>
</tr>
<tr>
<td>4</td>
<td>唐僧</td>
<td>男</td>
<td>16</td>
<td>女儿国</td>
</tr>
</table>
</body>
</html>
只能和自己在一行,不能和别的在一行,别的元素,依然会在tabel-cell元素的下面
利用position实现垂直居中的注意点
行内元素的宽和高默认是由其子元素决定的,而且,你会发现,行内元素的宽和高,在检查工具中,显示的是auto
<!DOCTYPE html>
<html lang="zh">
<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>
*{
margin:0px;
padding:0px;
}
.box1{
/* width:100px;
height:100px; */
/* position:absolute; */
background-color:#bfa;
/* left:0px;
right:0px;
top:0px;
bottom:0px; */
/* margin:auto; */
/* text-align:center; */
}
</style>
</head>
<body>
<div class="box1">
<span>在繁华中自律,在落魄中自愈</span>
</div>
</body>
</html>
而且,此时,我并没有给span的父元素(.box1)的宽和高设置固定明确的值,但是在浏览器中,你会发现,.box1是有宽度和高度的
但是,这并不意味着,我们就可以直接把没有明确指定固定宽和高的元素,通过定位垂直居中
<!DOCTYPE html>
<html lang="zh">
<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>
*{
margin:0px;
padding:0px;
}
.box1{
/* width:100px;
height:100px; */
position:absolute;
background-color:#bfa;
left:0px;
right:0px;
top:0px;
bottom:0px;
margin:auto;
/* text-align:center; */
}
</style>
</head>
<body>
<div class="box1">
<span>在繁华中自律,在落魄中自愈</span>
</div>
</body>
</html>
上面的元素box1的大小怎么又变了呢?而且,还铺满了全屏,因为需要满足那个等式关系,此时margin:auto的话,由于width和height没有固定的明确的写出的宽度(注意明确这个意思),所以,宽度和高度会自动设置满足那个式子,为了使得.box1水平垂直居中,目前只能这么做
<!DOCTYPE html>
<html lang="zh">
<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>
*{
margin:0px;
padding:0px;
}
.box1{
width:100px;
height:100px;
position:absolute;
background-color:#bfa;
left:0px;
top:0px;
right:0px;
bottom:0px;
margin:auto;
text-align:center;
}
</style>
</head>
<body>
<div class="box1">
<span>在繁华中自律,在落魄中自愈</span>
</div>
</body>
</html>
做法时,给固定明确的宽和高
但是,值得注意是,不给.box1明确的宽和高,并不影响它,定位时,位置的移动
<!DOCTYPE html>
<html lang="zh">
<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>
*{
margin:0px;
padding:0px;
}
.box1{
/* width:100px;
height:100px; */
position:absolute;
background-color:#bfa;
top:100px;
left:100px;
}
</style>
</head>
<body>
<div class="box1">
<span>在繁华中自律,在落魄中自愈</span>
</div>
</body>
</html>
对于没有明确指定宽和高的元素(比如上面的span和块元素),我们可以如何实现垂直居中的效果呢?除了试试用margin,line-height,vertical-align、text-align、table-cell外,我们可以借助平移变换来实现没有明确指定宽和高的元素的水平垂直居中
上面就实现了水平居中,垂直居中,可以同理的设置
完整代码如下所示:
<!DOCTYPE html>
<html lang="zh">
<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>
* {
margin: 0px;
padding: 0px;
}
span{
background-color:#bfa;
/* 这里的span的开启定位的包含块指的是根元素html */
position:absolute;
left:50%;
top:50%;
transform:translateX(-50%) translateY(-50%);
}
</style>
</head>
<body>
<span>在繁华中自律,在落魄中自愈</span>
</body>
</html>
注意上面的方法,有点类似于“小米商城”练习中,那个首页的右侧固定定位的工具条,都是,先使用一个相对的百分数来确定一个大概的位置
另外,特别值得注意的是上面translateX(-50%)和translatesY(-50%)之间要用空格隔开
针对什么时候利用空格隔开,什么时候利用逗号隔开,自己可以在这里先自己总结一下
像上面对transform这是有简写属性的,里面书写的时候,是要用空格隔开的
鸭子表中,块元素使用%,利用定位实现了水平和垂直居中,这是为什么呢?这个和前面的有所不同,前面的是都没有一个明确的固定的值出现,这个地方%是居于明确的固定的值出现的,所以可以使用定位和%来实现垂直居中,具体实现,可以参见下面的代码???
<!DOCTYPE html>
<html lang="zh">
<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>
.clock-wrapper{
width:800px;
height:800px;
/* background-color:red; */
margin:200px auto;
position:relative;
border-radius:50%;
background-image:url("../img/14/1024px-Analogue_clock_face.svg.png");
background-size:contain;
}
.clock-wrapper > div{
left:0px;
right:0px;
top:0px;
bottom:0px;
margin:auto;
position:absolute;
}
.clock-wrapper > div > div{
position:absolute;
left:0px;
right:0px;
margin:0px auto;
}
.hour-wrapper{
width:70%;
height:70%;
animation:clock 60s steps(60) infinite;
}
.hour{
width:1px;
height:50%;
background-color:red;
}
.min-wrapper{
width:55%;
height:55%;
animation:clock 3600s steps(60) infinite;
}
.min{
width:2px;
height:50%;
background-color:black;
}
.sec-wrapper{
width:40%;
height:40%;
animation:clock 46800s linear infinite;
}
.sec{
width:3px;
height:50%;
background-color:black;
position:absolute;
}
@keyframes clock{
from{
transform:rotateZ(0deg);
}
to{
transform:rotateZ(360deg);
}
}
</style>
</head>
<body>
<div class="clock-wrapper">
<div class="hour-wrapper">
<div class="hour"></div>
</div>
<div class="min-wrapper">
<div class="min"></div>
</div>
<div class="sec-wrapper">
<div class="sec"></div>
</div>
</div>
</body>
</html>
从结构上看,.clock-wrapper是.hour-wrapper和.min-wrapper以及.sec-wrapper的父元素,虽然.hour-wrapper和.min-wrapper以及.sec-wrapper的宽和高是用的百分数表示,看似没有明确的指明宽和高,但是,他们的父元素已经明确的给出了宽和高,因此,这里的hour-wrapper和.min-wrapper以及.sec-wrapper是相当于明确的给出了宽和高的,因此可以通过定位和top等的设置,实现水平垂直居中的
总结:明确给出元素宽和高是指,本身直接给出宽和高(width:XXpx和height:XXpx)或者是其父元素给出具体的宽和高,然后利用百分比的关系,得到该元素的具体的宽和高,言外之意,不能通过元素默认的宽和高由什么组成,来确定该元素的宽和高明确指定了
注意:这个表的思想,其实用到了两点
1. 中心的重合(所以需要设置一个外部容器.clock-wrapper)
2. 针不动,其父元素动
弹性盒里面实现弹性元素的水平垂直居中对齐
<!DOCTYPE html>
<html lang="zh">
<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>
*{
margin:0px;
padding:0px;
}
ul{
width:600px;
/* 父元素此时指定了高度 */
height:800px;
list-style:none;
border:10px solid red;
display:flex;
flex-direction:row;
/* 设置元素主轴空白处理方式 */
/* justify-content:flex-start; */
/* 设置主轴的元素是否换行 */
flex-wrap:wrap;
/* align-item */
justify-content:center;
align-items:center;
}
li{
width:200px;
/* 父元素的子元素此时不指定高度 */
/* height:200px; */
background-color:#bfa;
font-size:50px;
flex-shrink: 0;
line-height:100px;
text-align:center;
}
ul > li:nth-child(1){
background-color:#bfa;
}
ul > li:nth-child(2){
background-color:yellow;
}
ul > li:nth-child(3){
background-color:pink;
}
ul > li:nth-child(4){
background-color:silver;
}
ul > li:nth-child(5){
background-color:tomato;
}
</style>
</head>
<body>
<ul>
<li>
1
</li>
<!-- <li>
2
<div>2</div>
</li>
<li>
3
<div>3</div>
<div>3</div>
</li>
<li>
1
</li>
<li>
2
<div>2</div>
</li> -->
</ul>
</body>
</html>
思考,在上面的程序中,不能使用align-content(处理侧轴方向上的元素的空白的方式,能否实现元素垂直居中,然后结合处理弹性盒里面的元素的主轴方向上的空白,来实现弹性盒里面的元素的水平居中,然后二者结合在,最后实现弹性盒里面的弹性元素的水平和垂直方向的双向居中吗
?)
下面,使用下面的代码进行验证
<!DOCTYPE html>
<html lang="zh">
<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>
*{
margin:0px;
padding:0px;
}
ul{
width:600px;
/* 父元素此时指定了高度 */
height:800px;
list-style:none;
border:10px solid red;
display:flex;
flex-direction:row;
/* 设置元素主轴空白处理方式 */
/* justify-content:flex-start; */
/* 设置主轴的元素是否换行 */
flex-wrap:wrap;
/* align-item */
justify-content:center;
/* align-items:center; */
align-content:center;
}
li{
width:200px;
/* 父元素的子元素此时不指定高度 */
/* height:200px; */
background-color:#bfa;
font-size:50px;
flex-shrink: 0;
line-height:100px;
text-align:center;
}
ul > li:nth-child(1){
background-color:#bfa;
}
ul > li:nth-child(2){
background-color:yellow;
}
ul > li:nth-child(3){
background-color:pink;
}
ul > li:nth-child(4){
background-color:silver;
}
ul > li:nth-child(5){
background-color:tomato;
}
</style>
</head>
<body>
<ul>
<li>
1
</li>
<!-- <li>
2
<div>2</div>
</li>
<li>
3
<div>3</div>
<div>3</div>
</li>
<li>
1
</li>
<li>
2
<div>2</div>
</li> -->
</ul>
</body>
</html>
上面两种方式均实现了弹性盒里面的元素水平垂直居中
但是,值得注意是,上面弹性盒子中的弹性元素只有一个,上面不管使用align-items:center还是使用align-content:cente得到的效果均一样:弹性元素水平垂直居中,但是当弹性盒子里面的弹性元素不只一个,而且还是分行的话,使用align-items:center还是align-content:center,二者还是有区别的
在上面的情况下,使用align-items:center
<!DOCTYPE html>
<html lang="zh">
<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>
*{
margin:0px;
padding:0px;
}
ul{
width:600px;
/* 父元素此时指定了高度 */
height:800px;
list-style:none;
border:10px solid red;
display:flex;
flex-direction:row;
/* 设置元素主轴空白处理方式 */
/* justify-content:flex-start; */
/* 设置主轴的元素是否换行 */
flex-wrap:wrap;
/* align-item */
justify-content:center;
align-items:center;
/* align-content:center; */
}
li{
width:200px;
/* 父元素的子元素此时不指定高度 */
/* height:200px; */
background-color:#bfa;
font-size:50px;
flex-shrink: 0;
line-height:100px;
text-align:center;
}
ul > li:nth-child(1){
background-color:#bfa;
}
ul > li:nth-child(2){
background-color:yellow;
}
ul > li:nth-child(3){
background-color:pink;
}
ul > li:nth-child(4){
background-color:silver;
}
ul > li:nth-child(5){
background-color:tomato;
}
</style>
</head>
<body>
<ul>
<li>
1
</li>
<li>
2
<div>2</div>
</li>
<li>
3
<div>3</div>
<div>3</div>
</li>
<li>
1
</li>
<li>
2
<div>2</div>
</li>
</ul>
</body>
</html>
在上面的情况下,使用align-content:center
<!DOCTYPE html>
<html lang="zh">
<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>
*{
margin:0px;
padding:0px;
}
ul{
width:600px;
/* 父元素此时指定了高度 */
height:800px;
list-style:none;
border:10px solid red;
display:flex;
flex-direction:row;
/* 设置元素主轴空白处理方式 */
/* justify-content:flex-start; */
/* 设置主轴的元素是否换行 */
flex-wrap:wrap;
/* align-item */
justify-content:center;
/* align-items:center; */
align-content:center;
}
li{
width:200px;
/* 父元素的子元素此时不指定高度 */
/* height:200px; */
background-color:#bfa;
font-size:50px;
flex-shrink: 0;
line-height:100px;
text-align:center;
}
ul > li:nth-child(1){
background-color:#bfa;
}
ul > li:nth-child(2){
background-color:yellow;
}
ul > li:nth-child(3){
background-color:pink;
}
ul > li:nth-child(4){
background-color:silver;
}
ul > li:nth-child(5){
background-color:tomato;
}
</style>
</head>
<body>
<ul>
<li>
1
</li>
<li>
2
<div>2</div>
</li>
<li>
3
<div>3</div>
<div>3</div>
</li>
<li>
1
</li>
<li>
2
<div>2</div>
</li>
</ul>
</body>
</html>