CSS 水平垂直居中
前言
水平居中和垂直居中,已经讲的很详细了,其中可以有很多组合,为了不重复和篇幅问题,本节只列举一些常用的方法。如果你感兴趣研究,可以把前两章的水平居中和垂直居中知识点,一对多的研究,会发现有非常多的可选方法。
预储备知识
了解下面这些知识储备,可以更好的掌握本节的内容。
怪异盒模型
盒子模型一般分为标准盒模型(w3c 标准)和怪异盒模型(IE 标准)。大部分浏览器采用标准盒模型,而 IE 中则采用 Microsoft 自己的标准。
怪异模式:部分浏览器在支持 W3C 标准的同时还保留了原来的解析模式,怪异模式主要表现在 IE 内核的浏览器。
标准模式:
box-sizing:content-box;
盒子总宽度:width + padding(左右) + border(左右) + margin(左右)
怪异模式:
box-sizing:border-box;
盒子总宽度: width(width 已经包含了 padding,border 的值) + margin(左右)
定位布局
css 有 3 种定位机制:普通流,浮动,绝对定位
普通流:元素的位置由元素在 html 中的位置决定。
position 可以设置的值有 static | relative | absolute | fixed。
- static: 静态,没有特别的设置,遵循基本的定位规定。z-index 无效
- relative: 相对定位,不脱离文档流,通过 TLBR(top,left,bottom,right)定位,z-index 无效
- absolute: 绝对定位,脱离文档流,通过 TLBR 定位,z-index 有效。 选取其最近一个最有定位设置的父级对象进行定位,如果对象的父级没有设置定位属性,absolute 元素将以 body 坐标原点进行定位。
- fixed: 固定定位,相对于浏览器的可视窗口来定位,z-index 有效。
流布局
页面元素的宽度按照屏幕分辨率进行适配,整体布局不变。
网页中主要的划分区域的尺寸使用百分数(搭配 min-、max- 属性使用),例如,设置网页主体的宽度为 80%,min-width 为 960px。图片也作类似处理(width:100%, max-width 一般设定为图片本身的尺寸,防止被拉伸而失真)。
1、布局特点:屏幕分辨率变化时,页面里元素的大小会变化而但布局不变。【这就导致如果屏幕太大或者太小都会导致元素无法正常显示】
2、设计方法:使用 % 百分比定义宽度,高度大都是用 px 来固定住,可以根据可视区域 (viewport) 和父元素的实时尺寸进行调整,尽可能的适应各种分辨率。往往配合 max-width/min-width 等属性控制尺寸流动范围以免过大或者过小影响阅读。
这种布局方式在 Web 前端开发的早期历史上,用来应对不同尺寸的 PC 屏幕(那时屏幕尺寸的差异不会太大),在当今的移动端开发也是常用布局方式,但缺点明显:主要的问题是如果屏幕尺度跨度太大,那么在相对其原始设计而言过小或过大的屏幕上不能正常显示。因为宽度使用 % 百分比定义,但是高度和文字大小等大都是用 px 来固定,所以在大屏幕的手机下显示效果会变成有些页面元素宽度被拉的很长,但是高度、文字大小还是和原来一样(即,这些东西无法变得“流式”),显示非常不协调。
浮动布局
float: left | right | none | inherit
left: 左浮动
right: 右浮动
none: 默认值。元素不浮动,并会显示在其在文本中出现的位置
inherit: 规定应该从父元素继承 float 属性的值
使用浮动,div 会浮动于网页上方,为了不影响下方不需要浮动的 div,要先清除浮动
clear:left; 不允许有向左漂浮的标签
clear:right; 不允许有向右漂浮的标签
clear:both; 不允许有任何方向漂浮的标签
绝对定位 + margin:auto
当 top、bottom 为 0 时,margin-top&bottom 设置 auto 的话会无限延伸占满空间并且平分;
当 left、right 为 0 时,margin-left&right 设置 auto 的话会无限延伸占满空间并且平分;
div{
width: 200px;
height: 200px;
background: green;
position:absolute;
left:0;
top: 0;
bottom: 0;
right: 0;
margin: auto;
}
绝对定位 + 负 margin
div{
width:200px;
height: 200px;
background:green;
position: absolute;
left:50%;
top:50%;
margin-left:-100px;
margin-top:-100px;
}
绝对定位 +transform
元素未知宽度 如果元素未知宽度,
div{
width: 200px;
height: 200px;
background: green;
position:absolute;
left:50%; /* 定位父级的 50% */
top:50%;
transform: translate(-50%,-50%); /*自己的 50% */
}
flex 布局
使用 flex 布局 子元素设置
flex-direction: column;
justify-content: center;
使项目主轴垂直,然后再对子元素居中显示
.box{
height:600px;
display:flex;
justify-content:center; // 子元素水平居中
align-items:center; // 子元素垂直居中
/* aa 只要三句话就可以实现不定宽高水平垂直居中。 */
}
.box>div{
background: green;
width: 200px;
height: 200px;
}
table-cell
实现居中
设置
display:table-cell;
text-align:center;
vertical-align: middle;
vertical-align: middle
去对齐 after 伪元素
利用 inline-block 的 vertical-align:middle
去对齐 after 伪元素实现效果更加好,居中块的尺寸可以做包裹性、自适应内容,兼容性也相当好。
缺点是水平居中需要考虑 inline-block 间隔中的留白(代码换行符遗留问题。)
.warp {
text-align: center;
overflow: auto;
width: 200px;
height: 200px;
background-color: orange;
}
.example3 {
display: inline-block;
background-color: red;
vertical-align: middle;
width: 100px;
height: 100px;
}
.warp:after {
content: '';
display: inline-block;
vertical-align: middle;
height: 100%;
margin-left: -0.25em;
/* To offset spacing. May vary by font */
}
或者下面的方式
.wrapper{
width: 400px;
height: 400px;
text-align: center;
border: 2px solid blue;
}
.wrapper:after{
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.content{
display: inline-block;
vertical-align: middle;
width: 100px;
height: 100px;
background-color: red;
}
伪元素的另外一种实现方式(兄弟节点)
<div class="wrapper">
<div class="content"></div>
<div class="brother"></div>
</div>
.wrapper{
width: 400px;
height: 400px;
text-align: center;
border: 2px solid blue;
}
.content, .brother {
display: inline-block;
vertical-align: middle;
}
.content {
width: 100px;
height: 100px;
background-color: red;
}
.brother {
height: 400px;
}
下面讲水平和垂直同时居中,知识点就是基于水平居中和垂直居中的。
p{
margin: 0;
}
.d1{
width: 500px;
height: 500px;
border: 3px dashed #999999;
/*仅适用于单行文本 定义行高 = 元素内容高度(包含边框、内边距) */
line-height: 494px;
}
.d2{
width: 400px;
height: 400px;
border: 3px dashed green;
line-height: 494px;
}
/*块级元素垂直居中 1*/
.d3{
width: 400px;
height: 400px;
border: 3px dashed blue;
}
.c1{
width: 100px;
height: 100px;
background-color: palegreen;
position: relative;
top: 50%;
margin-top: -50px;
}
/* 块级元素垂直居中 2. 父元素的 display 改为 table-cell,并添加垂直居中 vertical-align: middle; */
.d4{
width: 400px;
height: 400px;
border: 3px dashed blue;
display: table-cell;
vertical-align: middle;
}
.c2{
width: 100px;
height: 100px;
background-color: palegreen;
}
<!-- 单行文本、单个内联元素垂直居中 -->
<div class="d1">
jigoerjwiojiofejigoerjw
</div>
<!-- 图片的垂直居中 -->
<div class="d2">
<img src="eq.png"/>
</div>
<!-- 块级元素 -->
<div class="d3">
<div class="c1"></div>
</div>
<div class="d4">
<div class="c2"></div>
</div>
button 作为父元素
button#parent{ /*改掉button默认样式就好了,不需要居中处理*/
height: 150px;
width: 200px;
outline: none;
border: none;
}
#son{
display: inline-block; /*button自带text-align: center,改为行内水平居中生效*/
}
优点:简单方便,充分利用默认样式 缺点:只适用于行内内容;需要清除部分默认样式;水平垂直居中兼容性很好,但是 ie 下点击会有凹陷效果!
vh 视窗居中
原理:vh 为视口单位,视口即文档可视的部分,50vh 就是视口高度的 50/100,设置 50vh 上边距再
#son{
margin: 50vh auto 0;
transform: translateY(-50%);
}
代码中的0
如果去掉,则会多出滚动条并且上下都是 50vh 的 margin。如果去掉就给 body 加上overflow:hidden;