css居中
- CSS居中情况:
- 网页元素水平居中;horizontally
- 网页元素垂直居中;vertically
- 网页元素同时实现水平居中和垂直居中;
更新:2018.6.17
一、水平居中
lineheight
absolute + 负margin
absolute + margin auto
absolute + calc
absolute + transform
table
css-table
flex
(一)行内或类行内元素
- 实现方式:使用
text-align
实现水平居中
这种方法可以让 inline/inline-block/inline-table/inline/flex 等类型的元素实现居中
- 代码:
div.center {
text-align: center;
background: hsl(0, 100%, 97%); // HSL colors 用于使背景颜色保持一致。
div.center img {
width: 33%;
height: auto;
}
- 缺点:这种方案没有使图片垂直居中:需要给
<div>
添加 padding 或者给内容添加 margin-top 和 margin-bottom使容器与内容之间有一定的距离。
(二)块级元素
(1)单个块级元素:
- 实现方案:使用
margin: auto
居中
设置方法:
margin-left
和margin-right
为 auto(前提是已经为元素设置了适当的 width 宽度,否则块级元素的宽度会被拉伸为父级容器的宽度)
- 示例代码
<main class="block-parent">
<div class="block-horizon-center">我是一个居中的块级元素</div>
</main >
.block-horizon-center {
width: 200px;
margin-left: auto;
margin-right: auto;
/* U can also do this */
margin: 0 auto;
}
- 使用
margin:0 auto;
注意: 必须使用display: block使 margin: 0 auto对img元素生效。
div.center {
background: hsl(60, 100%, 97%);
}
div.center img {
display: block;
width: 33%;
height: auto;
margin: 0 auto;
}
- 缺点:这种方式实现水平居中和上面使用text-align的方法有相同局限性。
(2)多个块级元素
实现方式:多个块级元素在同一水平线上居中,通过设置display 值。
具体实现
方法1:设置
display:inline-block
,
方法2:设置display:flexbox
- 示例代码
<main class="inline-block-horizon-center">
<div>我是一个居中的块级元素。</div>
<div>我是一个居中的块级元素,而且我有更多的内容。</div>
<div>我是一个居中的块级元素。</div>
</main>
<main class="flex-horizon-center">
<div>我是一个居中的块级元素。</div>
<div>我是一个居中的块级元素,而且我有更多的内容。</div>
<div>我是一个居中的块级元素。</div>
</main>
main div {
max-width: 125px;
}
.inline-block-horizon-center {
text-align: center;
}
.inline-block-horizon-center div {
display: inline-block;
/* U may like do this although it's not necessary */
vertical-align: middle/top;
}
.flex-horizon-center {
display: flex;
justify-content: center;
}
二、垂直居中
(一)行内或类行内元素
(1)单行 single line
方案(1):使用 padding
属性
实现方法
给元素添加等值的
padding-top
和padding-bottom
示例代码
.link {
padding-top: 30px;
padding-bottom: 30px;
}
方案(2):
- 实现方法:使用
line-height
属性
已知文本不会换行,让
line-height
和height
的值相等
- 示例代码
.single-inline-parent {
height: 30px;
line-height: 30px;
white-space: nowrap; /* 强制不换行 */
overflow: hidden; /* 文本溢出时隐藏 */
text-overflow: ellipsis; /* 溢出内容为省略号 */
}
(2)多行 multiple lines
情况一:多行不定高
- 使用 padding 属性
- 使用 flexbox 相关属性
- 使用“幽灵元素”
方案(1):使用 padding
属性
实现方法:设置
padding-top
和padding-bottom
实现垂直居中示例代码
<div>
<span class="multi-line-vertical-center">
I'm vertically centered multiple lines of text.I'm vertically centered multiple lines of text.I'm vertically centered multiple lines of text.I'm vertically centered multiple lines of text.
</span>
</div>
.multi-line-vertical-center {
padding-top: 30px;
padding-bottom: 30px;
/* 也可以这样写 */
padding: 30px 10px;
overflow: hidden;
}
方案(2): 使用 flexbox
实现方法:使用 flexbox 实现垂直居中,
因为对于父级容器为 display: flex 的元素来说,它的每一个子元素都是垂直居中的
示例代码
<div class="flex-center">
<p>我是flexbox容器中垂直居中的多行文本。</p>
</div>
.flex-center {
display: flex;
justify-content: center;
width: 240px;
}
方案(3):使用 "幽灵元素"(ghost element)
- 实现方式:使用 伪元素
首先,在需要垂直居中的元素上添加伪元素,将伪元素的
height
等于父级容器的height
然后,为文本添加vertical-align: middle;
- 示例代码
<div class="ghost-center">
<p>I'm vertically centered multiple lines of text in a container. Centered with a ghost pseudo element</p>
</div>
.ghost-center {
position: relative;
}
.ghost-center::before {
content: " ";
display: inline-block;
height: 100%;
width: null;
vertical-align: middle;
}
.ghost-center p {
display: inline-block;
vertical-align: middle;
/* 如果这个不起作用,可能需要把 width 设置为:比如 width: 100px; */
}
情况二:多行定高
父级元素定高时,采用的方法
方案(1):使用 padding
属性
- 实现方法:对于多行文本,同样可以使用等值 padding-top 和 padding-bottom 的方式实现垂直居中。
方案(2):使用 table-cell
和 vertical-align
属性
- 实现方法:为文本设置一个类似 table-cell 的父级容器,然后使用 vertical-align 实现垂直居中
注意:IE8- 版本无效
<div class="center-table">
<p>I'm vertically centered multiple lines of text in a CSS-created table layout.</p>
</div>
.center-table {
display: table;
width: 240px;
height: 250px;
}
.center-table p {
display: table-cell;
vertical-align: middle;
}
- 方法3:可以使用
flexbox
实现垂直居中,对于父级容器为display: flex
的元素来说,它的每一个子元素都是垂直居中的:
.flex-center-vertically {
display: flex;
justify-content: center;
flex-direction: column;
height: 400px;
}
(二)块级元素
情况一:元素定高
- 实现方法:设置绝对定位的
top
、margin-top
值
首先,让元素 绝对定位 到父容器的中心点,
然后,设置 负向margin
,负值的大小为其自身高度的一半
。注意::
如果父元素设置了padding
,则计算 负向margin
时,负值的大小为:其自身高度的一半再加上父元素的内边距
- 示例代码
<main>
<div>
我是一个具有固定高度的块级元素,在我的父级元素中垂直居中。
</div>
</main>
main {
position: relative;
}
main div {
position: absolute;
top: 50%;
height: 100px;
margin-top: -50px;
}
情况二:元素的高度未知
无法获知元素的具体高度是非常常见的一种状况,比如:视区宽度变化,会触发布局重绘,从而改变高度;对文本施加不同的样式会改变高度;文本的内容量不同会改变高度;当宽度变化时,对于宽高比例固定的元素(比如图片),也会自动调整高度……
方案(1):
- 实现方法:定位属性
positin
和 变换
首先,需要先将元素定位到容器的中心位置,
然后,使用transform
的translate
属性,将元素的中心和父容器的中心重合
- 示例代码
<main>
<div>
I'm a block-level element with an unknown height, centered vertically within my parent.
</div>
</main>
main {
position: relative;
}
main div {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
方案(2):使用 flexbox
实现方法:使用
flexbox
实现垂直居中:示例代码
<main>
<div>
I'm a block-level element with an unknown height, centered vertically within my parent.
</div>
</main>
main {
display: flex;
flex-direction: column;
justify-content: center;
}
(三)行内/块级元素
- 使用
transform
属性,从单行文本、段落到box,都会垂直对齐。
.verticalcenter{
position: relative;
top: 50%;
-webkit-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
}
问题:目前浏览器对Transform的支持是需要关注的,Chrome 4, Opera 10, Safari 3, Firefox 3, and Internet Explorer 9均支持该属性。
三、实现水平居中且垂直居中
- 三种类型:
宽高固定元素、宽高不固定元素、flex
方案(1):使用 table-cell
居中
使用
display: table-cell
,可以实现水平居中和垂直居中,外部容器设置为行内块元素;适用情况:
注意:这种方法需要添加额外的元素作为外部容器。、
示例代码
<div class="center-aligned">
<div class="center-core">
<img src="jimmy-choo-shoe.jpg">
</div>
</div>
.center-aligned {
display: table;
background: hsl(120, 100%, 97%);
width: 100%;
}
.center-core {
display: table-cell;
text-align: center;
vertical-align: middle;
}
.center-core img {
width: 33%;
height: auto;
}
- 注意:为了使div 不折叠必须加上 width: 100%,外部容器元素也需要加上一定高度使得内容垂直居中。给html和body设置高度后,也可以使元素在body垂直居中。此方法在IE8+浏览器上生效。
方案(2):使用 absolute
定位居中
- 这种方案有非常好的跨浏览器支持。
注意:有一个缺点就是必须显式声明外部容器元素的
height
:
- 示例代码
.absolute-aligned {
position: relative;
min-height: 500px;
background: hsl(200, 100%, 97%);
}
.absolute-aligned img {
width: 50%;
min-width: 200px;
height: auto;
overflow: auto;
margin: auto;
position: absolute;
top: 0; left: 0;
bottom: 0; right: 0;
}
- 实现方法2:
首先,设定父级容器为相对定位的容器,
.
然后,设定子元素绝对定位的位置:
position: absolute;
top: 50%;
`left: 50%
;
.
最后,使用负向 margin 实现水平和垂直居中,margin 的值为宽高(具体的宽高需要根据实际情况计算padding
)的一半。
.parent {
position: relative;
}
.child {
width: 300px;
height: 100px;
padding: 20px;
position: absolute;
top: 50%;
left: 50%;
margin: -70px 0 0 -170px;
}
- 补充:视口居中:模态窗
内容元素:position: fixed,z-index: 999,记住父容器元素 position: relative
- 示例代码
.Absolute-Center.is-Fixed {
width: 50%;
height: 50%;
overflow: auto;
margin: auto;
position: fixed;
top: 0; left: 0; bottom: 0; right: 0;
z-index: 999;
}
(三)宽高不固定元素
- 使用
translate
居中 - 代码:
<main>
<div>
我是一个具有未知高度和宽度的块级元素,在我的父级中垂直居中。
</div>
</main>
main {
position: relative;
}
main div {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
缺点:
- CSS transform 在部分就浏览器上需要使用 前缀。
- 不支持 IE9 以下的浏览器。
- 外部容器需要设置height (或者用其他方式设置),因为不能获取 绝对定位 的内容的高度。
- 如果内容包含文字,现在的浏览器合成技术会使文字模糊不清。
- 使用transform 有一个缺陷,就是当计算结果含有小数时(比如 0.5),会让整个元素看起来是模糊的,一种解决方案就是为父级元素设置 transform-style: preserve-3d; 样式:
示例代码
.parent-element {
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.element {
position: relative;
top: 50%;
transform: translateY(-50%);
}
(四)使用 flexbox
居中
- 示例代码
<main>
<div>
我是一个具有未知宽度和高度的块级元素,在我的父级中垂直居中。
</div>
</main>
main {
display: flex;
justify-content: center;
align-items: center;
}
(五)使用calc居中
在某些情况下比flexbox更全面:
示例代码
.center {
background: hsl(300, 100%, 97%);
min-height: 600px;
position: relative;
}
.center img {
width: 40%;
height: auto;
position: absolute;
top: calc(50% - 20%);
left: calc(50% - 20%);
}
calc
允许你基于当前的页面布局计算尺寸。在上面的简单计算中, 50% 是容器元素的中心点,但是如果只设置50%会使图片的左上角对齐div的中心位置。 我们需要把图片向左和向上各移动图片宽高的一半。计算公式为:
top: calc(50% - (40% / 2));
left: calc(50% - (40% / 2));
- 在现在的浏览其中你会发现,这种方法更适用于当内容的宽高为固定尺寸:
.center img {
width: 500px; height: 500px;
position: absolute;
top: calc(50% - (300px / 2));
left: calc(50% - (300px – 2));
}
- 这种方案和flex一样有许多相同的缺点: 虽然在现代浏览器中有良好的支持,但是在较早的版本中仍然需要浏览器前缀,并且不支持IE8。
.center img {
width: 40%; height: auto;
position: absolute;
top: calc(50% - 20%);
left: calc(50% - 20%);
}