博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
学会常用的CSS居中方式
阅读量:4117 次
发布时间:2019-05-25

本文共 4979 字,大约阅读时间需要 16 分钟。

640?wx_fmt=jpeg

作者 | 李银城

居中无疑是切图经常遇到的问题,一方面根据不同的场景使用合适的居中方式,另一方面能使用简单的居中方式就先使用简单的兼容性好的,而不是动不动就用JS算一下。

先来一个常见的案例,把一张图片和下方文字进行居中:

      

640?wx_fmt=jpeg

首先处理左右居中,考虑到img是一个行内元素,下方的文字内容也是行内元素,因此直接用text-align即可:

   
   

火星

实际的效果如下:

640?wx_fmt=jpeg

这样做的问题是,直接在最外层的container设置一个text-align的属性,导致所有子元素都会继承,假设图片标题下方还有文字描述,那么这个文字描述也会被居中,如下所示:

640?wx_fmt=jpeg

火星(Mars)是太阳系八大行星之一,天文符号是♂

但实际上是希望文字描述向左对齐,这样就不得不在文字描述添加一个text-align:left的属性,覆盖父元素的属性,并且如果还有更多的子元素也需要这样做,覆盖属性本身就是下策,因此这里采用其它的办法。

由于显示的图片是变化的,宽高是不定的,所以一般会显示地给图片设置一个宽高。如果知道宽度就可以用margin: 0 auto的方法,左右的margin值设置为auto,浏览器就会自动设置左右的margin值为容器剩余宽度的一半:

640?wx_fmt=jpeg

火星(Mars)是太阳系八大行星之一,天文符号是♂

 代码如下:

    
       
           
           
火星
       
       

火星(Mars)是太阳系八大行星之一,天文符号是♂

   

需要注意的是,这个办法对上下居中不适用。

使用margin: 0 auto可以说是最常见的左右居中方法,不仅适用于块元素也适用于行内元素。很多网页的布局都是主体内容固定宽度同时居中显示,例如淘宝PC端:

 640?wx_fmt=png

 查看最外层的容器的样式就可以发现使用了margin: 0 auto:

640?wx_fmt=png

 接下来讨论垂直居中,麻烦的是垂直居中。不过垂直居中有一个比较通用的办法,那就是借助table-cell的垂直居中。方法是给父容器添加以下属性:

.container{     display: table-cell;    vertical-align: middle;}

效果如下:

640?wx_fmt=jpeg

使用table-cell的缺点是容器的magin属性失效了,因为margin不适用于表格布局。所以如果要把container居中的话,使用margin: 0 auto就不起作用了。

解决的办法是在container外层再套多一个容器,然后让这个display为block的容器margin: 0 auto就可以了。

另外一个缺点是table-cell的元素设置宽高为百分比的时候将不起作用,常见的场景是要将宽度设置为外层容器宽度的100%,解决办法是将container的宽度设置成一个很大的值,例如3000px,这样就达到100%的目的。

还有一个问题是不兼容IE6/7,但现在生产环境基本上不需要兼容IE6/7了。

这种方法有失效的时候,那就是container需要设置position为absolute时。

因为设置position: absolute就会把(非flex)元素的display强制设置成block。解决办法还是模仿上面的,外层再套多一个容器,将absolute作用于这个容器,副作用是设置内层container的height和width为百分比时会失效(除非将它的position也设置成absolute)。由于这个原因,导致有一种情况不能使用display: table-cell垂直居中。

 这种场景就是需要在页面弹个框,这个框的位置需要在当前屏幕左右上下居中:

640?wx_fmt=png

 通常需要将这个框的positiion设置成absolute,这个时候table-cell就不能发挥作用了,即使你在外面再套多两层,最外层为absolute,里层为table-cell,但由于里层无法设置height为外层的100%,也就是说高度无法刚好占满整个屏幕,所以不能起作用。

 解决办法是使用relative定位,设置top为50%,再设置margin-top为元素高度的负的一半。

一开始设置top 50%,将弹框的起始位置放到页面中间,然后再设置margin-top为弹框高度的一半取负,这样使得弹框在页面中间位置再往上移一半自身的高度,这样就刚好在正中间了,左右居中也可类似处理:

   
       
       
   

效果如下:

640?wx_fmt=jpeg

 这种办法的缺点是需要知道高度,无法根据内容长短自适应。

所以就有了transform的方法,将margin-top一个具体的负值改成transform: translate(0, -50%),由于translate里面的面百分比是根据元素本身的高度计算的,于是就可以达到自适应的效果。将上面outer样式改为:

  .outer{        position: relative;        top: 50%;        left: 50%;         width: 200px;        transform: translate(-50%, -50%);    }

 这个办法十分地方便,为了提高兼容性,需要添加-ms-和-webkit-前缀,缺点是IE8不支持。

上面的两种办法:margin-top一个负值和translate -50%都有一个潜在的弊端, 就是如果设置left为50%是借助position为absolute的话,可能会导致换行:

   
           
   
     

效果如下:

640?wx_fmt=jpeg

 

 可以看到,本来应该在一行显示的p元素却换行了,这是因为在一个relative元素里面absolute定位的子元素会尽可能地不超过容器的边界,通过把行内元素换行的方式。由于设置left为50%,导致p元素超了边界,所以就换行了,即使再translate -50%但已经晚了。

即使是交换下两者的位置也是一样的效果,看得出浏览器执行的顺序始终是以absolute的定位优先。所以这种方法还是有不适合的场景,主要是用于左右居中定位为absolute的的情况。

另外一个CSS3居中的办法是使用flex布局,flex布局居中十分容易和方便,只需要在父容器添加三行代码,例如上面的居中情况,可将.nav的样式改为:

.nav{        position:absolute;        bottom: 0;        display: flex;        align-items: center;        justify-content: center;        width: 100%; }

效果如下:

640?wx_fmt=jpeg

 flex布局在自适应领域的功能真的是非常强大,不过IE的兼容性不好,所以说可能的话,不要太去照顾IE了。

 

上面讨论的都是一些复合元素的居中,接下来分析单纯的行内元素的垂直居中。

主要是要借助vertical-align: middle。如下,有一张图片和文字:

  
       
       
photo    

 如果不做任何处理,那么默认的垂直居中是以baseline为基准:

640?wx_fmt=jpeg

为了让它们能够垂直居中,需要改变它们的居中方式:

       .container img,        .container span{            vertical-align: middle;        }

注意每个元素都需要设置,效果:

640?wx_fmt=jpeg

 如果container的高度比图片还要高:

640?wx_fmt=jpeg

为了让中间的内容能够在container里上下居中,可以设置文字的line-height为container的高度,那么文字就上下居中了,由于照片是和文字是垂直居中的,所以照片在container里也上下居中了,代码:

       .container span{            vertical-align: middle;            line-height: 150px;        }

 

效果:

640?wx_fmt=jpeg

这也就给了一个启示,如果需要垂直居中一个div里的比div高度小的照片,可以添加一个元素,让它的line-height等于div的高度,如下:

       

 或者是弄一个inline-block的元素,设置height为100%,这种的兼容性更好:

       .container:before{            content: "";            display: inline-block;            vertical-align: middle;             height: 100%;        }

上下居中效果:

640?wx_fmt=jpeg

 

还有另外一种方法借助absolute定位和margin: auto:

       .container{            position: relative;        }               .container img{            position: absolute;            left: 0;            top: 0;            right: 0;            bottom: 0;            margin: auto;        }

 这个方法的神奇之处在于最后的margin: auto,这种方法也适用于div,但是需要给div显式指定一个height,不然div的height会达到外层容器的100%。

如果图片比container大,这种方法就不适用了。因为有一种比较常见的场景是:照片有一边和container一样高,另外一边按照片的比例缩放,照片居中显示,超出的截断,这种应该叫“占满”(occupy)布局。这种情况,只需要把left/right/top/bottom/设成一个很大的负值即可:

       .container img{            position: absolute;            left: -9999px;            top: -9999px;            right: -9999px;            bottom: -9999px;            margin: auto;        }        .container{            overflow: hidden;        }

效果:

640?wx_fmt=jpeg

综合上面的讨论,左右居中常用text-align和margin: 0 auto,上下居中一种办法是借助table-cell,另外一种是设置top: 50%和margin-top/translate(0, -50%)结合的办法,还有就是使用flex布局,对于行内元素设置vertical-align: middle,同时借助一个高度为100%的元素达到垂直居中的效果。

最后是position: absolute和margin: auto结合使用的办法。可以说没有一个方法可以100%适用,可以根据不同的情况合理结合使用。

如果上文有不妥的地方,或者你有其它的居中方式,欢迎留言交流学习。

640?wx_fmt=jpeg

转载地址:http://lzdpi.baihongyu.com/

你可能感兴趣的文章
码农租房有学问
查看>>
日本 IT 圈神作之书,好懂得可怕
查看>>
面试开挂!208 个最常见 Java 面试题全解析
查看>>
毕业 985,工作 996:)
查看>>
实战:用 C 语言实现操作系统
查看>>
Java 与底层操作系统的交互细节
查看>>
看完这篇 Linux 的基本操作你就会了!
查看>>
为什么大部分码农做不了架构师?
查看>>
Redis ,真的不完美
查看>>
Java 面试如何坐等 offer?
查看>>
5 分钟入门 Python 协程
查看>>
学会 C 语言真可以开发很多东西吗?
查看>>
现在学 NLP 还来得及吗?
查看>>
代码案例讲解程序员的第一性原理
查看>>
iOS 工程开发中的 Code Review
查看>>
大型微服务架构稳定性建设策略
查看>>
现在哪个 UI 会写代码?
查看>>
前端 「人傻钱多 」 速来!
查看>>
实现 AI 换脸的第一步:人脸搜索
查看>>
Python 数据分析师必备技能!
查看>>