图片在已知尺寸容器中水平垂直居中的办法

图片分为已知尺寸和未知尺寸的,已知尺寸的水平垂直居中相对比较容易,不再多说。这里着重介绍未知尺寸的,列出几种常见方法出来,供大家参考。

考虑如下问题:

1
2
3
4
5
6
请实现一个图片展示功能,使图片在父元素中水平垂直居中展示,信息如下:
1.父容器宽高均为500px
2.图片具体宽高未知,但宽高均不超过500px

要求:
1.不使用javascript,仅通过css实现

大概有几种解法:

以下办法兼容性各有不同,慎重使用

background大法

通过background设置图片在容器内居中

css代码

1
2
3
4
5
6
7
.container {
  width: 500px;
  height: 500px;
  background-image: url(/assets/images/avatar_430.jpg);
  background-position: center;
  background-repeat: no-repeat;
}

html代码

1
<div class="container"></div>

table-cell大法

通过设置display:table-cell

css

1
2
3
4
5
6
7
.container {
  width: 500px;
  height: 500px;
  display: table-cell;
  text-align: center;
  vertical-align: middle;
}

html

1
2
3
<div class="container">
  <img src="/assets/images/avatar_430.jpg" alt="图片居中">
</div>

flex大法

通过 flex 的布局居中

css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.container {
  width: 500px;
  height: 500px;
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
  -webkit-align-items: center;
  -ms-flex-align: center;
  align-items: center;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
  -ms-flex-pack: center;
  justify-content: center;
}

html

1
2
3
<div class="container">
  <img src="/assets/images/avatar_430.jpg" alt="图片居中">
</div>

transform大法

通过 position: absolute;transform 搭配使用

css

1
2
3
4
5
6
7
8
9
10
11
12
13
.container {
  position: relative;
  width: 500px;
  height: 500px;
}
.container img {
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
      -ms-transform: translate(-50%, -50%);
          transform: translate(-50%, -50%);
}

html

1
2
3
<div class="container">
  <img src="/assets/images/avatar_430.jpg" alt="图片居中"> 
</div>

margin:auto 大法

通过 margin:auto 和 top,right,bottom,left 为 0 搭配使用

css

1
2
3
4
5
6
7
8
9
10
11
12
13
.container {
  position: relative;
  width: 500px;
  height: 500px;
}
.container img {
  position: absolute;
  margin: auto;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

html

1
2
3
<div class="container">
    <img src="/assets/images/avatar_430.jpg" alt="图片居中">
</div>

grid大法

css

1
2
3
4
5
6
7
8
9
10
.container {
  width: 500px;
  height: 500px;
  display: grid;
  justify-items: center;
  -webkit-box-align: center;
  -webkit-align-items: center;
      -ms-flex-align: center;
          align-items: center;
}

html

1
2
3
<div class="container">
   <img src="/assets/images/avatar_430.jpg" alt="图片居中">
</div>

截至本稿发出时(2018-08-26),grid兼容性不是很好,如下图所示: grid兼容性


writing-mode大法

这个方法比较冷门,可能好多同学都没特别了解过writing-modewriting-mode能改变内容的显示方向。最初是用来作文字排版用的,比较常用的场景就是中国古诗词的垂直显示。如有兴趣了解,可以移步至CSS writing-mode与文字垂直排版实例

css:

1
2
3
4
5
6
7
8
9
.container {
  writing-mode: vertical-lr;
  text-align: center;
}
.wrapper {
  writing-mode: horizontal-tb;
  display: inline-block;
  width: 100%;
}

html:

1
2
3
4
5
<div class="container">
  <div class="wrapper">
    <img src="/assets/images/avatar_430.jpg" alt="图片居中">
  </div>
</div>

object-fit大法

如果仅考虑本题的图片居中场景,则可以使用object-fit这个css属性。object-fit官方描述如下:

The object-fit CSS property specifies how the contents of a replaced element should be fitted to the box established by its used height and width.

是不是看不懂?其实我也看不懂😂。大概意思是说:object-fit属性指定了一个替换元素的内容如何适应到它的框(这个框有可能是指定了宽高的)。

那什么是替换元素

其内容不受CSS视觉格式化模型控制的元素,比如image, 嵌入的文档(iframe之类)或者applet。比如,img元素的内容通常会被其src属性指定的图像替换掉。替换元素通常有其固有的尺寸:一个固有的宽度,一个固有的高度和一个固有的比率。比如一幅位图有固有用绝对单位指定的宽度和高度,从而也有固有的宽高比率。另一方面,其他文档也可能没有固有的尺寸,比如一个空白的html文档。

CSS渲染模型不考虑替换元素内容的渲染。这些替换元素的展现独立于CSS。object, video, textarea, input也是替换元素,audio和canvas在某些特定情形下为替换元素。

使用CSS的content属性插入的对象是匿名替换元素。

object-fit有5个值:

  • fill: 填充。默认值。替换内容拉伸填满整个content box, 不保证保持原有的比例。
  • contain: 包含。保持原有尺寸比例。保证替换内容尺寸一定可以在容器里面放得下。因此,此参数可能会在容器内留下空白。
  • cover: 覆盖。保持原有尺寸比例。保证替换内容尺寸一定大于容器尺寸,宽度和高度至少有一个和容器一致。因此,此参数可能会让替换内容(如图片)部分区域不可见。
  • none: 无。保持原有尺寸比例。同时保持替换内容原始尺寸大小。
  • scale-down: 缩减。就好像依次设置了none或contain, 最终呈现的是尺寸比较小的那个。

在这里,我们使用none即可。

1
2
3
4
5
.container img {
  width: 100%;
  height: 100%;
  object-fit: none;
}

实际上,我们这里省略了另一个属性object-position。这个属性用来控制替换元素内容的显示位置,一般是与object-fit一起使用的,它的默认值是center center, 与我们当前场景符合,所以在这里我们省略了它。它的值所有值列举如下:


描述 备注
left top 左上 如果只指定第一个值,则第二个值默认为 center
left center 左中
left bottom左下
right top右上
right center右中
right bottom右下
center top中部居顶
center center横竖居中
center bottom中部居底
x% y% 第一个是水平位置,第二个是垂直位置。比如:左上是0% 0%, 右下是:100% 100% 如果只指定x%,则 y% 为 50%
xpos ypos 第一个是水平位置,第二个是垂直位置。比如:左上是0 0,单位可以是像素(px)或其它css单位,也可使用百分比 如果只指定xpos,则 ypos 为 50%,你可以混合使用 数值和百分比