能够让不定宽高元素水平和垂直居中的方法

1、display:table和diaplay:table-cell

这个方案是理解上最容易的,因为table具备垂直居中的属性,所以很容易通过属性就能实现。

<style>
.container {
  display: table;
}
.inner {
  display: table-cell;
  vertical-align:middle;
  text-align:center;
}
</style>
<div class="container">
  <div class="inner">
  you own content
  </div>
</div>

这种情况下,我们可以通过随意改变.inner的宽高,当内部的内容仍然保持居中状态。

2、position:absolute、50%和translate

在css3里面提供了translate函数,它的主要作用是位移,传给transform属性。

<style>
.container {
  position: relative;
}
.inner {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
</style>
<div class="container">
  <div class="inner">
    your own content
  </div>
</div>

html代码和上面一样。translate(-50%, -50%)将会将元素位移自己宽度和高度的-50%。这种方法其实和最上面被否定掉的margin负值用法一样,可以说是margin负值的替代方案。这样你就非常容易理解了。这个方法最厉害的地方是不需要确定.inner的宽高,而.container的宽高也不需要手动设置,如果它自己本身就被撑大的话。这里只是为了演示方便,才特意给它设置了宽高。

3、vw vh和translate

vh和vw是两个比较偏的单位,是指“viewport的height和width的1%”,比如说50vh就是当前视口(窗口的高度,实验中包含了滚动条)高度的50%。也就是说vw将获得和1%差不多的window宽度。因此用在fixed的时候更加适合。

<style>
.inner {
   position:fixed;
   top: 50vh;
   left: 50vw;
   transform: translate(-50%, -50%); 
}
</style>
<div class="inner">
  this is a box fixed in center of screen
</div>

其实和使用50%没有太大的差别,因为这时top、left取的50%是相对于父元素的,和margin、padding不一样。如果非得要margin的话,就可以从这里衍生出变体:

 .inner2 {
   position:fixed;
   top: 0;
   left: 0;
   margin: 50vh 0 0 50vw;
   transform: translate(-50%, -50%); 
}

vh vw只能从窗口的大小去考虑,不适合正常的文本流。不过有的时候可以非常有用,特别是在做全屏应用的时候,比如full page。

4、:before和display:inline-block

这也是一种处理方式,通过伪类:before在元素内增加新元素后在用display:inline-block,通过高度的处理得到想要的效果。

<style>
.container{
    text-align: center;
}
.container:before {
    content: '';
    display: inline-block;
    height: 100%;
    vertical-align: middle;
}
.inner {
    display: inline-block;
}
</style>
<div class="container">
    <div class="inner">
        this is a box fixed in center of screen<br>The second line
    </div>
</div>

这个方案是比较特别一些,不是很好理解。首先,.container水平居中没问题。接着,给.container伪类:before设定为height:100%,这样可以用一个伪元素在.container获得与父元素等高的空间。然后用inline-block和vertical-align: middle改变对齐的基线,关于这一点,我也不甚懂,这里有一篇文章可以参考。通过:before之后,.container内的行级元素的对齐基线就跑到居中的位置,也就实现了垂直居中对齐。这个时候,如果里面仅一排文字,其实可以不用.inner,但是上面的例子里面有一个
,这就不一样了。如果直接把文字放在.container里面,
之前的文字会基于:before基线,会保持垂直对齐的状态。但是
之后的文字会另起一行,这一行将起始于:before的下一行,所以会在:before的100%高度下面,导致被顶出.container。但是如果把文字放在.inner里面,再让.inner为inline-block,就可以使.inner和:before处于同一基线,这样就让整个.inner处于垂直居中的状态。

5、css3 flex

css3新增了布局相关的属性,其中flex布局可以非常简单地帮我们实现我们想要的效果。

<style>
.container {
    display: flex;
    align-items: center;
    justify-content: center;
}
</style>
<div class="container">
    <div class="inner">
        this is a box fixed in center of screen<br>The second line
    </div>
</div>

简单解释一下,当display: flex时,表示该容器内部的元素将按照flex进行布局。align-items: center表示这些元素将相对于本容器水平居中,justify-content: center也是同样的道理垂直居中。对.container赋予了这些样式之后,作为它的内部元素.inner自己自觉的居中了。而且这里你会发现,由于没有使用text-align: center,.inner里面的文字是不会居中的,也就是说仅仅.inner这个容器居中而已。

总结
从上面的几种可行的方案,大致可以分为两类:display对齐方案、translate位移方案。display方案是充分发挥css的布局特性,利用布局和UI引擎的特性来控制布局中的对齐方式。而translate方案则是利用位移,通过先50%的位移,可以是通过position,也可以是通过margin vw vh,但是完成之后,在通过translate把元素拉回去,之所以用translate而不是margin是因为translate是相对于元素本身,而margin不是。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值