CSS 水平居中

🌙
手机阅读
本文目录结构

前沿

对元素水平居中,是我们写静态页面的一个最最基础的操作,本节介绍水平居中的方法。

预储备知识

了解下面这些知识储备,可以更好的掌握本节的内容。

margin

这里 margin 属性用于控制对象的上、右、下、左 4 个方向的外边距。当 margin 使用两个参数时,第一个参数表示上下边距,而第二个参数则表示左右边距。

margin 还支持一个叫 auto 的属性值,auto 值是让浏览器自动判断边距。 效果图:

元素的类型

学之前你需要了解displayinline/inline-block/block熟悉的概念

  • inline 是内联元素
  • inline-block 是内联块元素
  • block 是块级元素

元素脱标文档流的特点

  • 可以随意设置宽高
  • 宽高默认由内容决定
  • 不再受标准流的约束
  • 不再严格按照从上到下、从左到右排布
  • 不再严格区分块级、行内级,块级、行内级的很多特性都会消失
  • 不再给父元素汇报宽高数据
  • 脱标元素内部默认还是按照标准流布局

关于 table 的 display 可选值:

  • table:指定对象作为块元素级的表格,相当于 html 标签<table>
  • inline-table:指定对象作为内联元素级的表格,相当于 html 标签<table>
  • table-caption:指定对象作为表格标题,相当于 html 标签<caption>
  • table-cell:指定对象作为表格单元格,相当于 html 标签<td>
  • table-row:指定对象作为表格行,相当于 html 标签<tr>
  • table-row-group:指定对象作为表格行组,相当于 html 标签<tbody>
  • table-column:指定对象作为表格列,相当于 html 标签<col>
  • table-column-group:指定对象作为表格列组显示,相当于 html 标签<colgroup>
  • table-header-group:指定对象作为表格标题组,相当于 html 标签<thead>
  • table-footer-group:指定对象作为表格脚注组,相当于 html 标签<tfoot>

还有一些协助属性:

  • border-collpase:用来决定表格的边框是分开的还是合并的。在分隔模式下,相邻的单元格都拥有独立的边框。在合并模式下,相邻单元格共享边框。
  • border-spacing: 规定相邻单元格边框之间的距离(只适用于 边框分离模式 )。相当于 HTML 中的 cellspacing 属性,但是第二个可选的值可以用来设置不同于水平间距的垂直间距。
  • table-layout:定义了用于布局表格单元格,行和列的算法。(auto:表格及单元格的宽度取决于其包含的内容。fixed:表格和列的宽度通过表格的宽度来设置,某一列的宽度仅由该列首行的单元格决定。)
  • vertical-align:用来指定行内元素(inline)或表格单元格(table-cell)元素的垂直对齐方式。

操作 inline 元素

inline 元素全称 Inline Elements,英文原意:An inline element does not start on a new line and only takes up as much width as necessary. 一个内联元素不会开始新的一行,并且只占有必要的宽度。

常见的内联元素有

  • <a> - 链接
  • <b> - 粗体(不推荐)
  • <br> - 换行
  • <em> - 强调
  • <font> - 字体设定(不推荐)
  • <i> - 斜体
  • <img> - 图片
  • <input> - 输入框
  • <label> - 表格标签
  • <select> - 项目选择
  • <small> - 小字体文本
  • <span> - 常用内联容器,定义文本内区块
  • <strike> - 中划线
  • <strong> - 粗体强调
  • <sub> - 下标
  • <sup> - 上标
  • <textarea> - 多行文本输入框
  • <tt> - 电传文本
  • <u> - 下划线

介绍

一个标签元素表现形式为 display:inline;(无论是 HTML 元素本身的默认,还是 CSS 属性设置后的表现,两者均可以产生有效的内联元素);如果我们对这个元素进行水平居中,可以直接对父元素进行操作,设置父元素的文本对齐方式为居中即可 (text-align: center;)。

这种方式缺点:由于 text-align 是可继承属性,会影响到后代的行内内容;即父元素内部的所有元素都会继承这个属性,从而它的子元素内部的文本都会居中显示了,因此需要对子元素的文本居中方式单独设定。

: 如果子元素宽度大于父元素宽度则无效。

核心代码

text-align: center

例子

<div style="
    border: 1px solid #666;
    text-align: center;
    height: 100px;
">
    <span>阿西河前端教程</span>
</div>

操作 inline-block 元素

inline-block 元素,英文释义:inline-block elements are like inline elements but they can have a width and a height. 它像内联元素,但具有宽度和高度。

inline-block 元素是通过 CSS 进行设置而来的;常见的设置是把图片或按钮设置高度和宽度(比如imginput),然后居中显示;这时候 imginput 标签就是这种内联块元素标签。

介绍

如果一个标签元素表现形式为 display:inline-block;,我们对这个元素进行水平居中;

我们可以像设置display:inline;一样设置它的父元素,设置父元素的文本对齐方式为居中即可;

核心代码

text-align: center;

例子

<div style="
    border: 1px solid #666;
    height: 50px;
    text-align: center;
">
    <input style="
    display: inline-block;
    height: 40px;" value="阿西河前端教程" type="button" />
</div>

下面是一个导航条的例子,也是经常用到的,但是改为inline-block后,换行、空格会产生元素间隔。

<div style="
    border: 1px solid #666;
    height: 50px;
    text-align: center;
">
    <input style="
        display: inline-block;
        height: 40px;" value="阿西河前端教程1" type="button" />
    <input style="
        display: inline-block;
        height: 40px;" value="阿西河前端教程2" type="button" />
</div>

text-align:center 只对行内内容有效,所以我们要对子元素为块级的元素使用 text-align:center, 就必须将子元素设置为 display: inline; 或者 display: inline-block;

操作 block 元素(定宽)

block 元素全称 Block-level Elements,英文原意:A block-level element always starts on a new line and takes up the full width available (stretches out to the left and right as far as it can). 一个块级元素总是开始新的一行,并且占据可获得的全部宽度(左右都会尽可能的延伸到它能延伸的最远)

常见的块元素有 :

  • <div> - 最常用的块级元素
  • <p> - 段落
  • <dl> - 和 dt dd 搭配使用的块级元素
  • <form> - 交互表单
  • <h1> - 大标题
  • <hr> - 水平分隔线
  • <ol> - 排序表单
  • <ul> - 非排序列表

使用 margin: 0 auto; 属性

介绍

一个标签元素表现形式为 display:block;,如果我们使用margin: 0 auto;对这个元素进行水平居中;首先我们对该元素进行设置宽度,无论是px为单位,还是百分比的宽度均可以,然后通过左右外边距auto就可以进行居中;

当设置 margin-right: auto;时候,右边空出来,靠近左侧;当设置 margin-left: auto;时候,左边空出来,靠近右侧。当左右同时设置为auto, 会均分剩余空间,也就是两边保留相同的边距,又因为宽度是固定的,所以达到了居中效果;另外,如果上下的 margin 设置了 auto,其计算值为 0

注意margin: 0 auto; 实现水平居中的前提是,元素的宽度已知,不能为 auto,当宽度值未知时就不能使用本方法了;宽度也必须小于父元素,否则就无效了。

核心代码

width: 500px;
margin: 0 auto;

建议:相对于margin: 0 auto;,更推荐使用下面的这种写法

margin-left: auto;
margin-right: auto;

例子

<div
    style="
        border: 1px solid #666;
        width: 500px;
        margin: 0 auto;
    ">
    阿西河前端教程
</div>

使用定位和负 margin-left 属性

介绍

很多时候,我们需要在基于定位的基础上进行居中;比如某个 div 必须要设置一个相对定位或者绝对定位的时候;

核心代码

position:relative;
width:固定宽度;
left:50%;
margin-left:-宽度的一半;

例子

<div style="
    border: 1px solid #666;
    position:relative;
    width:500px;
    left:50%;
    margin-left:-250px;
    ">
        阿西河前端教程
</div>

原理

先向左移动 屏幕的 50%,此时 div 的左边处于 50% 中线的位置;这时候再通过margin-left向左移动 div 的宽度一半;这就会让 div 的中线和浏览器视口的中线重合,从而达到了居中的目的。

calc属性

介绍

这种方式原理和上面使用负margin-left的原理输类似的,虽然没有用到margin-left;

核心代码

position: absolute;
width:宽度;
left: calc(50% - 一半的宽度);

例子

<div style="
  border: 1px solid #666;
  position: absolute;
  width:500px;
  left: calc(50% - 250px);
  ">
    阿西河前端教程
</div>

原理

calc() 此 CSS 函数允许在声明 CSS 属性值时执行一些计算。

绝对定位和margin:0 auto;

介绍

当必须使用绝对定位的场景下,除了上面的负边距以外,还可以使用 left:0;right:0;margin:0 auto;

注意:这种场景用在,必须使用绝对定位,又有要元素居中的场景,和上面介绍的设置宽度,然后使用margin:0 auto;还是有场景使用的区别。

核心代码

position: absolute;
width:500px;
left:0;
right:0;
margin:0 auto;

例子

<div style="
    border: 1px solid #666;
    position: absolute;
    width:500px;
    left:0;
    right:0;
    margin:0 auto;
    ">
        阿西河前端教程
</div>

原理

当设置绝对定位和margin:0 auto;时候,此时 margin 并不会起效果;单独设置left:0; 或者 right:0; 都会让元素贴在一边;同时设置定位和边距,即可让auto生效;

这种方式通过设置各个方向的距离都是 0,此时再把 margin 设为 auto,平分边距,就可以在各个方向上居中了;这也是一种兼容性很好的方法;

操作 block 元素(不定宽)

我们经常会遇到不定宽度块级元素的使用,如分页导航,因为分页的数目不定,所以不能用宽度限制住。或者做多语言的常见,某个字段在中英文下占用的空间不相同,所以也不能用宽度限制。

设置display:table;属性

通过给要居中显示的元素,设置 display:table,然后设置 margin:0 auto 来实现;也有用 display:table-cell;,原理都是类似的;

核心代码

display:table;
margin:0 auto;

例子

<div style="
    border: 1px solid #666;
    display:table;
    margin:0 auto;
">
    阿西河前端教程
</div>

设置display:inline;属性

改变块级元素的 dispaly 为 inline 或者 inline-block 类型,然后使用 text-align:center 来实现居中效果。这种方法的缺点是改变了元素的属性,比如将块级元素的 display 设置为 inline,于是少了很多功能,比如盒子模型。

这个方法,和操作 inline 元素的原理一样,这里加深一下印象。

核心代码

父级

text-align:center;

子级

display:inline;

例子

<div style="text-align:center;">
    <p style="display:inline; border: 1px solid #666;">阿西河前端教程</p>
</div>

设置 float: left;属性

介绍

通过给父元素设置 float,然后给父元素设置 position:relative 和 left:50%,子元素设置 position:relative 和 left:-50% 来实现水平居中。

这种方法可以保留块状元素仍以 display:block 的形式显示,优点不添加无语议表标签,不增加嵌套深度;但它的缺点是设置了 float: left; 脱离文档流,可能会带来一定的副作用。比如你设置了背景色,布局会就产生混乱。

核心代码

float: left;
position: relative;
left: 50%;

例子

<div style="
    float: left;
    position: relative;
    left: 50%;
    border: 1px solid #666;
">
    <div>阿西河前端教程</div>
</div>

flex 布局

介绍

只需把要处理的块状元素的父元素设置 display:flex;justify-content:center;,原理就是设置当前主轴对齐方式为居中

注意:设为 flex 布局以后,子元素的 float、clear 和 vertical-align 属性将失效

核心代码

display:flex;
justify-content:center;

例子

<div style="
    display:flex;
    justify-content:center;
">
    <div >阿西河</div>
    <div >前端教程</div>
</div>

grid 属性

介绍

网格布局也是和 flex 一样,都是很常见的布局方式。

核心代码

display: grid;

例子

<div class="wp">
    <div class="box">123123</div>
</div>
.wp {
    display: grid;
}
.box {
    align-self: center;
    justify-self: center;
}

CSS3 的 transform 属性

使用 CSS3 中新增的 transform 属性,自身宽度一半,等同于margin-left: -50px; 子元素设置如下:

核心代码

position:absolute;
left:50%;
transform:translate(-50%,0);

transform:translate(-50%,0);transform:translateX(-50%); 均可。

例子

.son{
    position:absolute;
    left:50%;
    transform:translateX(-50%);
}

使用:before

除了上面介绍的两种方法以外,我们还可以使用一种技巧性比较强的方法,其 html 代码和上面的是一样的,这里就不贴了。

其 css 代码如下,

/* This parent can be any width and height */
.parent {
    text-align: center;
}
.parent:before {
    content: '';
    display: inline-block;
    height: 100%;
    vertical-align: middle;
    margin-right: -0.25em; /* Adjusts for spacing */
 }
/* The element to be centered, can also be of any width and height */
.centered {
    display: inline-block;
    vertical-align: middle;
 }

我们着重看一下这里.parent:before 元素的样式,这里的:before 伪元素起了很重要的作用,它拥有和 .parent 元素一样的高度,而且设置了.vertical-align: middle,同时给.centered 元素设置了 display: inline-blockvertical-align: middle

其实这里的 .parent:before 为下面的 .centered 元素提供了可以绝对居中的容器。

这里有一个 jsfiddle。 http://jsfiddle.net/gejiawen/8su978hm/1/

<center> 标签

这个属于 HTML 标签,因为和居中相关,所以提一下,<center>标签默认就有水平居中的效果,虽然该特性已经从 Web 标准中删除,不推荐使用;

但是实际在浏览器中,都支持这个标签,目前兼容性很好,但也许会在未来的某个时间停止支持,请谨慎选择使用。

小结

一般情况下 text-align:center,marin:0 auto; 就够了,无兼容性要求,推荐 flex

方法 居中元素定宽高固定 PC 兼容性 移动端兼容性
absolute + 负 margin ie6+, chrome4+, firefox2+ 安卓 2.3+, iOS6+
absolute + margin auto ie6+, chrome4+, firefox2+ 安卓 2.3+, iOS6+
absolute + calc ie9+, chrome19+, firefox4+ 安卓 4.4+, iOS6+
absolute + transform ie9+, chrome4+, firefox3.5+ 安卓 3+, iOS6+
writing-mode ie6+, chrome4+, firefox3.5+ 安卓 2.3+, iOS5.1+
lineheight ie6+, chrome4+, firefox2+ 安卓 2.3+, iOS6+
table ie6+, chrome4+, firefox2+ 安卓 2.3+, iOS6+
css-table ie8+, chrome4+, firefox2+ 安卓 2.3+, iOS6+
flex ie10+, chrome4+, firefox2+ 安卓 2.3+, iOS6+
grid ie10+, chrome57+, firefox52+ 安卓 6+, iOS10.3+

一行一列的应用

一列式布局是所有布局的基础,也是最简单的布局形式,一列式布局是一种固定的宽度的布局样式,一般是一个带有 header、center、和 footer 三个并列的布局。

<div id="layout">1列固定宽度</div>

CSS:

/*1列固定宽度*/
#layout{
        background-color: #cccccc;
        border: 2px solid #333333;
        width: 300px;
        height: 300px;
}

效果图:

一列宽度自适应

自适应布局能够根据浏览器窗口的大小,自动改变其宽度或高度值。良好的自适应布局网站对不同分别率的显示器都能够提供最好的显示效果。

默认状态下的 div 将占据整行空间,即是宽度为 100% 的自适应布局。一列自适应布局只要改变这个设置,将固定值改为百分比值的形式便可以了。

自适应的优势是,当扩大或缩小浏览器窗口大小时,其宽度还将维持着与浏览器当前宽度比例的 80% 范围。

<div id="layout-self-adaption">1列宽度自适应</div>

CSS:

/*1列宽度自适应*/
#layout-self-adaption{
        background-color: #cccccc;
        border: 2px solid #333333;
        width: 80%;
        height: 300px;
}

效果图:

一列固定宽度居中

页面整体居中是网页设计中常见的形式,div 本身支持 align="center"属性,可以让 div 呈现居中状态。但是 align 对齐属性是一种样式代码,写在 XHTML 的 div 属性中,不符合分离原则。

<div id="layout-center">1列固定宽度居中</div>

CSS:

/*1列固定宽度居中*/
#layout-center{
    background-color: #cccccc;
    border: 2px solid #333333;
    width: 300px;
    height: 300px;
    margin: 0px auto;
}

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

于2021年离开前端领域,目前重心放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>

于2021年离开前端领域,目前从事区块链方面工作了