将Div中的超大图像居中


175

我一直在试图找出如何仅使用CSS在div内居中放置超大图像的方法。

我们使用的是流畅的布局,因此图像容器的宽度会随着页面宽度的变化而变化(div的高度是固定的)。该图像位于一个div中,并带有一个插入框阴影,以使您看起来就像在浏览页面时一样。

图像本身的大小已设置为以其最大可能值填充周围的div(设计具有max-width值)。

如果图像小于周围的div,则很容易做到:

margin-left: auto;
margin-right: auto;
display: block; 

但是,当图像大于div时,它仅从左边缘开始,并偏离右中心(我们正在使用overflow: hidden)。

我们可以指定一个width=100%,但是浏览器无法很好地调整图像的大小,而Web设计围绕高质量的图像进行。

关于将图像居中以overflow:hidden均匀切掉两个边缘的任何想法吗?


2
你曾经解决过@Tom这个问题吗?目前,我遇到了同样的问题。:)
ctrlplusb

我认为您的图像宽度会有所不同。
otherDewi 2013年

Answers:


365

尝试这样的事情。无论其大小如何,这都应使任何巨大的元素相对于其父元素在垂直和水平方向上居中。

.parent {
    position: relative;
    overflow: hidden;
    //optionally set height and width, it will depend on the rest of the styling used
}

.child {
    position: absolute;
    top: -9999px;
    bottom: -9999px;
    left: -9999px;
    right: -9999px;
    margin: auto;

}

4
太棒了:这与任何元素都有效。即使使用html 5视频...谢谢!
taseenb

3
据我了解:之所以起作用,是因为它创建了一个(希望是)大于图像(2 * 9999px x 2 * 9999px)的元素,并将图像居中于该元素内(边距:自动)。因此,只要图像不超过2 * 9999px,它就可以正常工作。
Michael Krupp 2014年

16
为什么不-100%用于上/右/下/左?这样,容器实际上可以具有任何宽度。
西蒙

15
是的,我也遇到了这个-100%问题^^。顺便说一句:如果你加min-widthmin-height100%你基本上得到一个background-size: cover;与图像标记的行为- > 的jsfiddle
西蒙

3
@HarrisonPowers好吧,父母必须具有一定的身高,无论是固定的还是动态的。如果某些其他内容正在填充div使其具有高度(例如,例如文本),它也将起作用。
hyounis 2014年

162

这是一个旧的Q,但是没有flexbox或position absolute的现代解决方案是这样的。

margin-left: 50%;
transform: translateX(-50%);

那为什么行得通呢?
乍一看,似乎我们向右移动了50%,然后又向左移动了50%。那将导致零位移,那又如何呢?
但是50%并不相同,因为上下文很重要。如果使用相对单位,则边距将作为元素宽度的百分比计算,而变换将是相对于同一元素的50%。

在添加CSS之前,我们有这种情况

       +-------------------------------------------+
       | Parent element P of E                     |
       |                                           |
       +-----------------------------------------------------------+
       | Element E                                                 |
       +-----------------------------------------------------------+
       |                                           |
       +-------------------------------------------+

随着增加的风格,margin-left: 50%我们有

       +-------------------------------------------+
       | Parent element P of E                     |
       |                                           |
       |                     +-----------------------------------------------------------+
       |                     | Element E                                                 |
       |                     +-----------------------------------------------------------+
       |                     |                     |
       +---------------------|---------------------+
       |========= a ========>|

       a is 50% width of P

然后transform: translateX(-50%)移回左侧

       +-------------------------------------------+
       | Parent element P of E                     |
       |                                           |
+-----------------------------------------------------------+
| Element E                 |                               |
+-----------------------------------------------------------+
|<============ b ===========|                      |
       |                    |                      |
       +--------------------|----------------------+
       |========= a =======>|

       a is 50% width of P
       b is 50% width of E

不幸的是,这仅适用于水平居中,因为边距百分比计算始终相对于宽度。即不仅margin-leftmargin-right,而且还margin-topmargin-bottom相对于宽度被计算。

浏览器兼容性应该没问题:https : //caniuse.com/#feat=transforms2d


它不适用于垂直对齐(当.inner具有比.out大的高度时)
cronfy

1
@cronfy号。垂直将不起作用,因为margin-top: 50%它将是宽度的 50%。不是所需的高度。
yunzen

2
到目前为止,这是最优雅的解决方案
Souhaieb Besbes

寻找一会儿,最好的,最简单的解决方案;干杯
lauWM

2
这是纯粹的巫师魔法。谢谢!在Safari和Chrome中完美运行(添加-webkit-transform: translateX(-50%);了很好的工具)
Nick Schneble

22

在div内放置一个大div,将其居中,并将图像居中于该div中。

这使它水平居中:

HTML:

<div class="imageContainer">
  <div class="imageCenterer">
    <img src="http://placekitten.com/200/200" />
  </div>
</div>

CSS:

.imageContainer {
  width: 100px;
  height: 100px;
  overflow: hidden;
  position: relative;
}
.imageCenterer {
  width: 1000px;
  position: absolute;
  left: 50%;
  top: 0;
  margin-left: -500px;
}
.imageCenterer img {
  display: block;
  margin: 0 auto;
}

演示:http//jsfiddle.net/Guffa/L9BnL/

也可以将其垂直居中,也可以将其用于内部div,但是需要将图像的高度绝对地放置在其中。


最后,图像的左边缘居中于“ imageContainer”内。正如我上面评论的,我们的图像容器div是流体宽度和固定高度。
2013年

1
@Tom:如果删除width容器上的设置,它将是父级的宽度,即使页面比图像窄,图像也会居中,即,将隐藏与右侧一样多的左侧边缘:jsfiddle.net/Guffa/L9BnL/2
Guffa

感谢您的灵感。我对.imageCenter使用position:relative。这样,我就不需要位置:父容器的相对位置。
user3153298 2015年

这个问题有很多聪明的窍门,但它们都有缺点。有些工作“更好”,但一点也不容易理解。此解决方案非常合理,图像通常在要裁剪的更宽的div中居中。感觉不对,但是它确实可以在不违反网络物理定律的情况下工作。我选择了这个选项,而不是其他一些很难理解的技巧,即使它确实有点脏。
Radley Sustaire '18

9

游戏晚了,但是我发现这种方法非常直观。 https://codepen.io/adamchenwei/pen/BRNxJr

的CSS

.imageContainer {
  border: 1px black solid;

  width: 450px;
  height: 200px;
  overflow: hidden;
}
.imageHolder {
  border: 1px red dotted;

  height: 100%;
  display:flex;
  align-items: center;
}
.imageItself {
  height: auto;
  width: 100%;
  align-self: center;

}

的HTML

<div class="imageContainer">
  <div class="imageHolder">
    <img class="imageItself" src="http://www.fiorieconfetti.com/sites/default/files/styles/product_thumbnail__300x360_/public/fiore_viola%20-%202.jpg" />
  </div>
</div>

3
真好!也可以简化。技巧是通过display: flex在父容器和align-self: center图像上完成的。这是一个优化的版本:codepen.io/anon/pen/dWKyey
caiosm1005

5

请勿在图片标签上使用固定或明确的宽度或高度。相反,对其进行编码:

      max-width:100%;
      max-height:100%;

例如:http//jsfiddle.net/xwrvxser/1/


1
然后,在图像周围留出空间,我相信他们会尽力避免这种情况。
Eoin

3

我非常喜欢将图片作为div / node的背景,background-position: center因此无论屏幕大小如何,您都可以使用该属性将其居中


9
这不是使用图像的便捷方式。对于装饰性图像,它可能工作得很好,但是,任何提供信息的图像都需要文本。
user2532030

0

宽度和高度仅作为示例:

parentDiv{
    width: 100px;
    height: 100px;
    position:relative; 
}
innerDiv{
    width: 200px;
    height: 200px;
    position:absolute; 
    margin: auto;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
}

如果您的父div的左侧和顶部不是屏幕窗口的顶部和左侧,它必须为您工作。这个对我有用。


似乎没有什么不同。由于宽度是可变的,不确定高度是否固定,而高度固定在父div上。
2013年

2
如果图像小于容器,则此技术有效。
otherDewi 2013年

0

我发现这是没有flex的更优雅的解决方案:

.wrapper {
    overflow: hidden;
}
.wrapper img {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    /* height: 100%; */ /* optional */
}

0

以@yunzen的出色答案为基础:

我猜很多搜索此主题的人都在尝试将大图像用作“英雄”背景图像,例如在首页上。在这种情况下,他们通常希望文本出现在图像上并在移动设备上很好地缩小。

这是用于此类背景图像的完美CSS(在<img>标记上使用):

/* Set left edge of inner element to 50% of the parent element */
margin-left: 50%;

/* Move to the left by 50% of own width */
transform: translateX(-50%);

/* Scale image...(101% - instead of 100% - avoids possible 1px white border on left of image due to rounding error */
width: 101%;

/* ...but don't scale it too small on mobile devices - adjust this as needed */
min-width: 1086px;

/* allow content below image to appear on top of image */
position: absolute;
z-index: -1;

/* OPTIONAL - try with/without based on your needs */
top: 0;

/* OPTIONAL - use if your outer element containing the img has "text-align: center" */
left: 0;

-1

您可以使用的一种选择是object-fit: cover它的行为类似于background-size: cover。有关对象拟合的更多信息。

忽略下面的所有JS,仅用于演示。

这里的关键是您需要在包装器内设置图像并为其提供以下属性。

.wrapper img {
  height: 100%;
  width: 100%;
  object-fit: cover;
}

我在下面创建了一个演示,您可以在其中更改包装器的高度/宽度并在游戏中查看。图像将始终垂直和水平居中。它将占据其父代宽度和高度的100%,并且不会被拉伸/挤压。这意味着可以保持图像的纵横比。可以通过放大/缩小来应用更改。

唯一的缺点object-fit是它在IE11上不起作用

// for demo only
const wrapper = document.querySelector('.wrapper');
const button = document.querySelector('button');
const widthInput = document.querySelector('.width-input');
const heightInput = document.querySelector('.height-input');


const resizeWrapper = () => {
  wrapper.style.width = widthInput.value + "px";
  wrapper.style.height = heightInput.value + "px";
}

button.addEventListener("click", resizeWrapper);
.wrapper {
  overflow: hidden;
  max-width: 100%;
  margin-bottom: 2em;
  border: 1px solid red;
}

.wrapper img {
  display: block;
  height: 100%;
  width: 100%;
  object-fit: cover;
}
<div class="wrapper">
  <img src="https://i.imgur.com/DrzMS8i.png">
</div>


<!-- demo only -->
<lable for="width">
  Width: <input name="width" class='width-input'>
</lable>
<lable for="height">
  height: <input name="height" class='height-input'>
</lable>
<button>change size!</button>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.