把简单作好也不简单-css水平垂直居中

44年前咱们把人送上月球,但在CSS中咱们仍然不能很好实现水平垂直居中。javascript

做者:Icarus
原文连接:xdlrt.github.io/2016/12/15/…css

水平垂直居中有相同点也有不一样点,接下来讨论常见的方式。html

如无特殊说明,如下示例html均为:java

<div class="md-warp">
    <span class="md-main"></span>
</div>复制代码

基础样式为:css3

.md-warp{
    width: 400px;
    height: 300px;
    max-width: 100%;
    border: 1px solid #000;
}
.md-main{
    display: block;
    width: 100px;
    height: 100px;
    background: #f00;
}复制代码

水平居中

margin法

须要知足三个条件:git

  • 元素定宽
  • 元素为块级元素或行内元素设置display:block
  • 元素的margin-leftmargin-right都必须设置为auto
    三个条件缺一不可。

demo:

.md-main{
    margin: 0 auto;
}复制代码


定位法

须要知足三个条件:github

  • 元素定宽
  • 元素绝对定位,并设置left:50%
  • 元素负左边距margin-left为宽度的一半

demo1:

.md-warp{
    position: relative;
}
.md-main{
    position: absolute;
    left: 50%;
    margin-left: -50px;
}复制代码


有些时候咱们的元素宽度可能不是固定的,不用担忧,咱们依然可使用定位法实现水平居中,此时须要用到css3中的transform属性中的translate,可使元素移动时相对于自身的宽度和高度。
须要注意,这种方法须要IE9+才能够实现。web

demo2

.md-warp{
    position: relative;
}
// 注意此时md-main不设置width为100px
.md-main{
    position: absolute;
    left: 50%;
    -webkit-transform: translate(-50%,0);
    -ms-transform: translate(-50%,0);
    -o-transform: translate(-50%,0);
    transform: translate(-50%,0);
}复制代码

不定宽

文字水平居中

对于单行文字来讲,直接使用text-align: center便可。
多行文字能够看做一个块级元素参考margin法和定位法。浏览器

垂直居中

定位法

和水平居中相似,只是把left:50%换成了top:50%,负边距和transform属性进行对应更改便可。布局

优势:能在各浏览器下工做,结构简单明了,不需增长额外的标签。

demo1:

.md-warp{
    position: relative;
}
.md-main{
    position: absolute;
    /* 核心 */
    top: 50%;
    margin-top: -50px;
}复制代码


运用css3中的clac()属性能简化部分代码:

.md-warp{
    position: relative;
}
.md-main{
    position: absolute;
    /* 核心 */
    top: calc(50% - 50px);
}复制代码


demo2

.md-warp{
    position: relative;
}
.md-main{
    position: absolute;
    top: 50%;
    // 注意此时md-main不设置height为100px
    -webkit-transform: translate(0,-50%);
    -ms-transform: translate(0,-50%);
    -o-transform: translate(0,-50%);
    transform: translate(0,-50%);
}复制代码

不定高

单行文本垂直居中

须要知足两个条件:

  • 元素内容是单行,而且其高度是固定不变的。
  • 将其line-height设置成和height的值同样
<div><span>这是一段文字</span></div>复制代码
div{
    width: 400px;
    height: 300px;
    border: 1px solid #000;
}
span{
    line-height: 300px;
}复制代码
这是一段文字

以上是一些常规办法,接下来是利用CSS3新特性实现的示例。

视窗单位的解决办法(垂直居中)

若是想避免使用绝对定位,咱们仍然能够利用translate()方法,其值恰好是元宽度和高度的一半。可是,咱们如何不使用top和left将元素从top和left移动50%的偏移量呢?

首先想到的是给margin属性一个百分数,像这样:

.md-main{
    margin: 50% auto 0;
    transform: translateY(-50%);
}复制代码

效果以下所示:



咱们发现并无出现预想的结果,这是由于margin的百分比计算是相对于父容器的width来计算的,甚至包括margin-topmargin-bottom

咱们若是仍然想让元素在视窗中居中,仍是有救的。CSS3定义了一种新的单位,称为相对视窗长度单位。

如下摘自w3cplus
vw是相对于视窗的宽度。与你预期恰好相反,1vw至关于视窗宽度的1%,而不是100%
vw类似的是,1vh至关于视窗高度的1%
若是视窗的宽度小于高度,1vmin等于1vw,反之,若是视窗宽度大于高度,1vmin等于1vh
若是视窗的宽度大于高度,1vmax等于1vw,反之,若是视窗宽度小于高度,1vmax等于1vh

在上个示例的基础上,咱们须要给margin设置vh单位:

.md-warp{
    position: relative;
}
.md-main{
    position: absolute;
    margin: 50vh auto 0;
    transform: translateY(-50%);
}复制代码

注意:这种方法最大的局限是只能适用于元素在视窗中垂直居中,若是是在局部的某个地方就无能为力了。

Flexbox的解决方案

若是不考虑浏览器的兼容性,Flexbox无疑是最好的解决方案,由于它的出现就是为了解决这样的问题。

完成这项工做只须要两个样式,在须要水平垂直居中的父元素上设置display:flex和在水平垂直居中的元素上设置margin:auto

.md-warp{
    display:flex;
}
.md-main{
    margin: auto;
}复制代码


Flexbox的实现文本的水平垂直居中一样很简单。

.md-warp{
    display:flex;
}
.md-main{
    display: flex;
  align-items: center;
  justify-content: center;
    margin: auto;
}复制代码

我是字啊

补充:

inline-block配合伪类的解决方案

.md-warp{
  font-size: 0;
}
.md-warp:before{
  content:'';
  display:inline-block;
  width: 0;
  height:100%;
  vertical-align:middle;
}
.md-main{
  display:inline-block;
  vertical-align:middle;
  font-size: 14px;
}复制代码

引自demo.doyoe.com/css/alignme…
首先要了解垂直方向的对齐排版需使用 vertical-align ,而且只应用于inline level, inline-block level 及 table-cells 元素上;其次 vertical-align 的对齐就基于每一个 line box(行框) 的,简单的说,inline level元素按照 Normal flow 水平排版出一行就会造成一个line box,其高度由内容造成,若是换行,则又是另外一个line box,全部一段文本可能会分布在多个line box里,这些不重叠的line box被称做为a vertical stack of line boxes(一个垂直堆叠的线框集合)这些。
换句话说,咱们的垂直居中是要在每一个line box中进行处理。而上例中咱们想让一行文本在名叫demo的高100px的容器里垂直居中,这时有个问题就是demo容器并不是该行文本的line box,因此就算定义vertical-laign为middle也没法让该行文本在demo容器中垂直居中。咱们知道line box的高度是由内容造成的,这时咱们能够额外建立一个与该行文本处于同一line box的元素,同时将新增元素的高度定义为与demo容器相同,此时line box的高度将与demo一致,文本将会在line box内垂直居中,即一样实现了在demo容器中垂直居中。

绝对垂直居中

.md-warp{
  position: relative;
}
.md-main{
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
}复制代码

经常使用在弹出层的定位中。

结语

  • 绝对定位一般不是一个很好的选择,由于它对总体的布局影响至关的大。
  • 在一些浏览器中,可能会致使元素出现略微的模糊,那是由于元素有可能被放置在半个像素位置上。咱们能够经过transform-style:preserve-3d来解决,但这是一个Hack手段,不能保证它不会过期。

以上各类方法稍加组合便可同时实现水平和垂直居中,这些就是平时用到较多的一些居中的方法,但愿你们看完以后有收获:)

相关文章
相关标签/搜索