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

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

<style>
.container{
text-align: center;
}
</style>
<div class="container">
<img src="Mars.png">
<p>火星</p>
</div>

实际的效果如下:

火星

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

火星

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

但实际上是希望文字描述向左对齐,这样就不得不在文字描述添加一个text-align:left的属性,覆盖父元素的属性,并且如果还有更多的子元素也需要这样做,覆盖属性本身就是下策,因此这里采用其它的办法。由于显示的图片是变化的,宽高是不定的,所以一般会显示地给图片设置一个宽高。如果知道宽度就可以用margin: 0 auto的方法,左右的margin值设置为auto,浏览器就会自动设置左右的margin值为容器剩余宽度的一半:

火星

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

代码如下:

<style>
figure{
width: 100px;
margin
: 0 auto;
}
figcaption{
text-align: center;
}
</style>
<div class="container">
<figure>
<img src="Mars.png">
<figcaption>火星</figcaption>
</figure>
<p class="desc">火星(Mars)是太阳系八大行星之一,天文符号是♂</p>
</div>

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

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

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

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

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

效果如下:

火星

使用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垂直居中。

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

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

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

<style>
.mask{
position: absolute; width: 100%; height: 100%;
}
.outer{
position
: relative;
top
: 50%;
left
: 50%;
margin-top
: -100px;
margin-left
: -100px;
}
.container{
width: 200px;
height: 200px;
display: table-cell;
vertical-align: middle;
}
</style>
<div class="mask">
<div class="outer">
<div class="container"> </div>
</div>
</div>

效果如下:

火星

这种办法的缺点是需要知道高度,无法根据内容长短自适应。所以就有了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的话,可能会导致换行:

<style>
.container{
position: relative;
}
.nav{
position:absolute;
left: 50%;
transform: translate(-50%, 0);
bottom: 0;
}
</style>
<div class="container">
<figure>
<img src="Mars.png">
</figure>
<p class="nav"><span>地形</span><span>气候</span><span>运动</span></p>
</div>

效果如下:

地形气候运动

可以看到,本来应该在一行显示的p元素却换行了,这是因为在一个relative元素里面absolute定位的子元素会尽可能地不超过容器的边界,通过把行内元素换行的方式。由于设置left为50%,导致p元素超了边界,所以就换行了,即使再translate -50%但已经晚了。即使是交换下两者的位置也是一样的效果,看得出浏览器执行的顺序始终是以absolute的定位优先。所以这种方法还是有不适合的场景,主要是用于左右居中定位为absolute的的情况。

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

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

效果如下:

地形气候运动

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

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

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

    <div class="container">
<img src="Mars.png">
<span>photo</span>
</div>

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

photo

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

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

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

photo

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

photo

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

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

效果:

photo

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

<style>
.container{
width: 150px;
height: 150px;
text-align: center;
}
.container img{
vertical-align: middle;
}
.container:before
{
content: "";
vertical-align: middle;
line-height: 150px;
}
</style>
<div class="container">
<img style="vertical-align:middle;" src="Mars.png">
</div>

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

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

上下居中效果:

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

        .container{
position: relative;
} .container img{
position: absolute;
left:;
top:;
right:;
bottom:;
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;
}

效果:

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

如果上文有不妥的地方,或者读者有其它的居中方式,还请指出

  个人博客: http://yincheng.site/css-align

参考:

1. How to vertically align an image inside div StackOverflow

2. A Complete Guide to Flexbox

CSS常见居中讨论的更多相关文章

  1. IE6的那些css常见bug(汇总)

    IE6的那些css常见bug(汇总) 我的微博终于在前几天建立了 虽说很早之前就知道博客园这个地方 但怕自己不能坚持去写一些东西一直没有建.这几天 我做了这个决定 把我的博客建起来 每周发一些看到的, ...

  2. CSS常见布局问题整理

    实现div的水平居中和垂直居中 多元素水平居中 实现栅格化布局 1. 实现div的水平居中和垂直居中 实现效果: 这大概是最经典的一个题目了,所以放在第一个. 方法有好多, 一一列来 主要思路其实就是 ...

  3. css CSS常见布局解决方案

    CSS常见布局解决方案说起css布局,那么一定得聊聊盒模型,清除浮动,position,display什么的,但本篇本不是讲这些基础知识的,而是给出各种布局的解决方案.水平居中布局首先我们来看看水平居 ...

  4. 前端进阶系列(二):css常见布局解决方案

    水平居中布局 margin+定宽 <div class="parent"> <div class="child">Demo</di ...

  5. CSS中居中的完全指南(中英对照翻译)

    翻译自:https://css-tricks.com/centering-css-complete-guide/ Centering things in CSS is the poster child ...

  6. 【转】css布局居中和CSS内容居中区别和对应DIV CSS代码

    原文地址:http://www.divcss5.com/jiqiao/j771.shtml css布局居中和CSS内容居中区别和对应DIV CSS代码教程与图文代码案例篇 对于新手来说DIV CSS布 ...

  7. 使用Flexbox实现CSS竖向居中

    竖向居中需要一个父元素和一个子元素合作完成. <div class="flexbox-container"> <div>Blah blah</div& ...

  8. CSS标签居中

    CSS标签居中是相对于父标签说的,即在父标签的中居中.通常是在子标签中使用margin:0 auto,来使子标签居中.此外子标签需要有固定的宽度才行,比如 子标签为div时,div的宽度默认占父标签的 ...

  9. css常用居中

    对一个已知大小的元素上下左右居中(已知大小了,直接margin也就行了): css如下:.parent{height:100px;width:100px;background:grey;positio ...

随机推荐

  1. 前端学HTTP之重定向和负载均衡

    前面的话 HTTP并不是独自运行在网上的.很多协议都会在HTTP报文的传输过程中对其数据进行管理.HTTP只关心旅程的端点(发送者和接收者),但在包含有镜像服务器.Web代理和缓存的网络世界中,HTT ...

  2. 博客使用BOS上传图片

    1.博客平台的选定 从大学开始做个人主页算起,最开始是使用html,CSSS写简单的页面,后面大学毕业之后接触到了WordPress,就开始用WordPress搭建网站.现在还维护着一个农村网站.ht ...

  3. Velocity初探小结--velocity使用语法详解

    做java开发的朋友一般对JSP是比较熟悉的,大部分人第一次学习开发View层都是使用JSP来进行页面渲染的,我们都知道JSP是可以嵌入java代码的,在远古时代,java程序员甚至在一个jsp页面上 ...

  4. vue.js初探

    前言 入手2016最火前端框架之一vue.js.大概从网上找了些资料看了下vue.js,从网上的资料来看只能惊叹其发展速度太快,让我意外的是其作者是华人的前提下作品这么受欢迎. 网上的博客和教程各种组 ...

  5. from表单提交数据之后,后台对象接受不到值

    如果SSH框架下,前段页面通过from表单提交数据之后,在后台对象显示空值,也就是接收不到值得情况下.首先保证前段输入框有值,这个可以在提交的时候用jQuery的id或者name选择器alert弹出测 ...

  6. JavaScript将字符串中的每一个单词的第一个字母变为大写其余均为小写

    要求: 确保字符串的每个单词首字母都大写,其余部分小写. 这里我自己写了两种方法,或者说是一种方法,另一个是该方法的变种. 第一种: function titleCase(str) { var new ...

  7. 【干货分享】流程DEMO-补打卡

    流程名: 补打卡申请 业务描述: 当员工在该出勤的工作日出勤但漏打卡时,于一周内填写补打卡申请. 流程相关文件: 流程包.xml 流程说明: 直接导入流程包文件,即可使用本流程 表单:  流程: 图片 ...

  8. Supermap iCloudManager -负载均衡

    Supermap icm负载均衡理解: 应用场景:地图出图 子节点1和子节点2中的服务保持一致,一般情况下设置的是匿名用户通过nginx访问服务信息,所以不需要登录. 1.通过nginx分发请求,(轮 ...

  9. Android菜单项内容大全

    一.介绍: 菜单是许多应用中常见的用户界面组件. Android3.0版本以前,Android设备会提供一个专用"菜单"按钮呈现常用的一些用户操作, Android3.0版本以后, ...

  10. CentOS7 安装Mono及Jexus

    CentOS7安装Mono及Juxes 1 安装Mono 1.1 安装yum-utils 因为安装要用到yum-config-manager,默认是没有安装的,所以要先安装yum-utils包.命令如 ...