在阅读此文章之前要搞明白行内元素和块级元素的区别,和其常用的标签
行内元素垂直居中
1. 设置外层块元素的height,line-height为相同的值
适用范围:作用于单行为文字,使文字垂直居中显示
原理:line-height与font-size的计算之差(在css中成为“行间距”)分为两半,分别加到一个文本行内容的顶部和底部。(可以包含这些内容的最小框就是行框)实现了单行文字居中,代码如下:
<body> <style> .container { height: 50px; line-height: 50px; background:aqua; }
.content { background-color: bisque; } </style>
<div class="container"> <span class="content">垂直居中</span> </div></body>
2. vertical-align
适用范围:外层块元素包含大于一个行内元素需要垂直居中时 (如图片和文字需要垂直居中显示时),可以通过对图片的标签或文字的标签(行内元素)设置vertical-align,可以达到效果;
特点:
- 父级块元素不需要设置宽高
- 只需将基线较高的行内元素设置
vertial-align就行
vertical-align属性的定义:该属性定义行内元素的基线相对于该元素所在行的基线的垂直对齐。允许指定负长度值和百分比值。这会使元素降低而不是升高。在表单元格中,这个属性会设置单元格框中的单元格内容的对齐方式。
<body> <style> .container { background: aqua; }
.content { background-color: bisque; }
img { vertical-align: middle; } </style>
<div class="container"> <span class="content">垂直居中</span> *[Image missing: bd_logo1.png]* </div></body>
3. 外层父元素display: table-cell;vertical-align: middle
特点:
- 外层元素需要设置高度
适用范围: 适用于在块元素内存在单个行内块元素,将它垂直居中;
<body> <style> .container { background: aqua; height: 300px; display: table-cell; vertical-align: middle; } </style>
<div class="container"> *[Image missing: bd_logo1.png]* </div></body>[Image missing: image-20200326110227357.png]
4. display:flex; align-items:center
特点:
- flex布局
- 父元素可以不设置高度,宽度由内部行内元素撑起(这里设置高度是为了看的更清楚)
<body> <style> .container { height: 300px; background: aqua; display: flex; align-items: center; }
img { max-width: 300px; } </style>
<div class="container"> <span>12111111111111111111111111111111111111111111111111eeeeeeeeeeee1111111dwaedwqqqqqqqqqqqqqqqqq</span> *[Image missing: bd_logo1.png]* </div>
</body>
5. 绝对定位+负外边距;
适用范围:包裹的行内元素必须是可以设置高度的,但是像文本元素是不建议使用这个的,因为文本的内容不确定,除非定高且设置超出溢出
<body> <style> .container { height: 300px; background: aqua; position: relative; }
img { height: 200px; margin-top: -100px; top: 50%; position: absolute; } </style>
<div class="container"> *[Image missing: bd_logo1.png]* </div>
</body>块级元素垂直居中
类似,不解释
多行文本垂直居中
利用 display:table;和display:table-cell; 来实现多行文本的垂直居中
<body> <style> .container { height: 300px; background: aqua; display: table; }
p { display: table-cell; vertical-align: middle; background-color: bisque; } </style>
<div class="container"> <p> dsadwqdssacadseqdsfcdsfsasddsa dwqdssacadseqdsfcdsfsasddsadwqd ssacadseqdsfcdsfsasddsadwqdssaca dseqdsfcdsfsasddsadwqdssacadseqds fcdsfsasddsadwqdssacadseqdsfcdsfsasd </p> </div>
</body>未知元素的宽高情况
在前面的实现行内元素的垂直居中中有提到几种方法
1. 组合使用display:table-cell和vertical-align、text-align,
使父元素内的所有行内元素水平垂直居中(内部div设置display:inline-block即可)这在子元素不确定宽度和高度时
与其他一些display属性类似,table-cell同样会被其他一些css属性破坏,例如float,position:absolute,所以在使用display:table-cell时,尽量不要使用float或者position
<body> <style> .father { width: 400px; height: 200px; border: 1px solid #000; display: table-cell; text-align: center; vertical-align: middle; }
.son { width: 200px; height: 100px; background: red; display: inline-block; } </style>
<div class="father"> <div class="son"> display:table-cell;</br>text-align:center;</br> vertical-align:middle </div> </div>
</body>
对table-cell元素设置百分比(如100%)的宽高值是无效的,但是可以将元素设置display
<body> <style> html, body { height: 100%; margin: 0; padding: 0; }
#box { display: table; width: 100%; height: 100%; }
.father { width: 400px; height: 200px; border: 1px solid #000; display: table-cell; text-align: center; vertical-align: middle; }
.son { width: 200px; height: 100px; background: red; display: inline-block; } </style> <div id="box"> <div class="father"> <div class="son"> display:table-cell;</br>text-align:center;</br> vertical-align:middle </div> </div> </div>
</body>
2. display 的方法
参考上面所说的行内元素的方法
-
设置container的display的类型为flex,激活为flexbox模式。
-
justify-content定义水平方向的元素位置
-
align-items定义垂直方向的元素位置
3. display +伪元素生成content内容
实现原理:原理:利用inline-block的vertical-align: middle去对齐before伪元素,before伪元素的高度与父对象一样,就实现了高度方向的对齐。居中块的尺寸可以做包裹性、自适应内容,兼容性也相当好。缺点是水平居中需要考虑inline-block间隔中的留白(代码换行符遗留问题。)。(宽度是已知的,高度可以是未知的)
(这里子元素加了宽高是为了方便看,去掉也无所谓)
<body> <style> .father { width: 400px; height: 200px; border: 1px solid #000; text-align: center; }
.father:before { content: " "; display: inline-block; vertical-align: middle; height: 100%; }
.son { width: 200px; height: 100px; background: red; display: inline-block; vertical-align: middle; } </style>
<div class="father"> <div class="son"> display:inline-block;</br>伪元素生成content内容</br> </div> </div>
</body>4. 绝对定位+transform反向偏移。
position
原理很简单:由于top、left偏移了父对象的50%宽度高度,所以需要利用transform反向偏移居中块的50%宽高
transform的计算基准是元素本身,所以这里可以用50%来做反向偏移
(这里子元素加了宽高是为了方便看,去掉也无所谓)
<body> <style> .father { width: 400px; height: 200px; border: 1px solid #000; position: relative; }
.son { width: 200px; height: 100px; background: red; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } </style>
<div class="father"> <div class="son"> position:absolute;</br>left:50%;top:50%;</br>transform </div> </div>
</body>
知道元素宽高的情况下
1.绝对定位相对定位( 绝对定位+margin:auto;position ; left:0; top:0; right:0; bottom:0; margin )
一个条件都不能少
<body> <style> .father { width: 400px; height: 200px; position: relative; border: 1px solid #000; }
.son { width: 200px; height: 100px; background: red; position: absolute; left: 0; top: 0; bottom: 0; right: 0; margin: auto; } </style>
<div class="father"> <div class="son"> position:absolute;</br> left:0; top:0;</br> right:0; bottom:0; </br>margin:auto </div> </div></body>
原理:
当一个绝对定位元素,其对立定位方向属性同时有具体定位数值的时候,流体特性就发生了。
具有流体特性绝对定位元素的margin
如果一侧定值,一侧auto,auto为剩余空间大小; 如果两侧均是auto, 则平分剩余空间; 例如,下面的CSS代码:
.father { width: 300px; height:150px; position: relative;}.son { position: absolute; top: 0; right: 0; bottom: 0; left: 0;}如图所示流体元素会布满整个父元素,此时.son这个元素的尺寸表现为“格式化宽度和格式化高度”,和的“正常流宽度”一样,同属于外部尺寸,也就是尺寸自动填充父级元素的可用尺寸的
[Image missing: image-20200326150745436.png]
然后,此时我们给.son设置尺寸,例如
.son { position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 200px; height: 100px;}
此时宽高被限制,原本应该填充的空间就被多余了出来,这多余的空间就是margin:auto计算的空间,因此,如果这时候,我们再设置一个margin:auto,那么:
.son { position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 200px; height: 100px; margin: auto;}我们这个.son元素就水平和垂直方向同时居中了
2. 绝对定位+margin反向偏移
在上面的行内块元素种有提及到
position:absolute; top:50%; left:50%; margin-left:-(width+padding)/2+'px'; margin-top:-(height+padding)/2+'px';margin值的设置不能使用百分比,因为margin是基于父元素的宽度来计算百分比的
这个原理和上面的方案4很相似,由于top、left偏移了父对象的50%宽度高度,所以需要利用margin反向偏移居中块的50%宽高