在 Div 中居中超大图像

Posted

技术标签:

【中文标题】在 Div 中居中超大图像【英文标题】:Center Oversized Image in Div 【发布时间】:2013-01-11 19:35:39 【问题描述】:

我一直在尝试解决如何仅使用 css 在 div 中将超大图像居中。

我们使用的是流体布局,因此图像容器的宽度会随着页面宽度的变化而变化(div 的高度是固定的)。该图像位于一个 div 中,带有一个嵌入的 boxshadow 值,以使您看起来好像正在浏览该图像的页面。

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

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

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

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

我们可以指定width=100%,但浏览器在调整图像大小方面做得很糟糕,而且网页设计以高质量图像为中心。

关于使图像居中以使overflow:hidden 均匀地切断两个边缘的任何想法?

【问题讨论】:

你有没有解决过这个问题@Tom?我现在遇到了同样的问题。 :) 我假设您的图像宽度不同。 【参考方案1】:

这是一个旧的 Q,但是没有 flexbox 或绝对位置的现代解决方案就是这样工作的。

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

.outer 
  border: 1px solid green;
  margin: 20px auto;
  width: 20%;
  padding: 10px 0;
  /*   overflow: hidden; */


.inner 
  width: 150%;
  background-color: gold;
  /* 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%); 
<div class="outer">
  <div class="inner">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos exercitationem error nemo amet cum quia eaque alias nihil, similique laboriosam enim expedita fugit neque earum et esse ad, dolores sapiente sit cumque vero odit! Ullam corrupti iure eum similique magnam voluptatum ipsam. Maxime ad cumque ut atque suscipit enim quidem. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Excepturi impedit esse modi, porro quibusdam voluptate dolores molestias, sit dolorum veritatis laudantium rem, labore et nobis ratione. Ipsum, aliquid totam repellendus non fugiat id magni voluptate, doloribus tenetur illo mollitia. Voluptatum.</div>
</div>

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

我们在添加 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

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

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

【讨论】:

它不适用于垂直对齐(当 .inner 的高度大于 .outer 时) @cronfy 否。垂直它不起作用,因为margin-top: 50% 将是 宽度 的 50%。不是所需的高度。 这是迄今为止最优雅的解决方案 寻找解决方案一段时间,最好,最简单的;干杯 这是纯粹的巫师魔法。谢谢!在 Safari 和 Chrome 中完美运行(添加了 -webkit-transform: translateX(-50%); 以获得良好的衡量标准)【参考方案2】:

将一些 flex 和溢出设置为隐藏很简单。

<!DOCTYPE html>
<html lang="en">
<head>
    <style>
        div 
            height: 150px;
            width: 150px;
            border: 2px solid red;
        
            overflow: hidden;
            display: flex;
            align-items: center;
            justify-content: center;
        
    </style>
</head>
<body>
    <div>
        <img src="sun.jpg" >
    </div>
</body>
</html>

【讨论】:

【参考方案3】:

基于@Guffa 的回答 因为我花了 2 个多小时来居中一个非常宽的图像, 对我来说,图像尺寸为 2500x100px,视口为 1600x1200 或全高清 1900x1200 像这样居中工作:

 .imageContainer 
  height: 100px;
  overflow: hidden;
  position: relative;
 
 .imageCenter 
  width: auto;
  position: absolute;
  left: -10%;
  top: 0;
  margin-left: -500px;
 
.imageCenter img 
 display: block;
 margin: 0 auto;
 

我希望这有助于其他人更快地完成任务:)

【讨论】:

【参考方案4】:

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

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

这里是这样一个背景图片的完美 CSS(在&lt;img&gt; 标签上使用它):

/* 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;

【讨论】:

【参考方案5】:

您可以使用的一个选项是object-fit: cover,它的行为有点像background-size: cover。更多关于object-fit。

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

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

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

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

object-fit 的唯一缺点是它在 IE11 上是 doesn't work。

// 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>

【讨论】:

【参考方案6】:

试试这样的。这应该相对于其父元素垂直和水平地将中间的任何巨大元素居中,无论它们的大小如何。

.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;


【讨论】:

太棒了:这适用于任何元素。即使是 html 5 视频...谢谢! 据我了解:它之所以有效,是因为它创建了一个(希望)大于图像(2*9999px x 2*9999px)的元素,并将图像居中在该元素内(边距:自动)。所以只要图片不超过 2*9999px 就可以了。 为什么不将-100% 用于上/右/下/左?这样,容器就可以具有字面上的 any 宽度。 是的,我也遇到过-100% 问题^^。顺便说一句:如果你添加min-widthmin-height100%,你基本上会得到带有图像标签的background-size: cover; 行为-> jsfiddle @HarrisonPowers 当然,无论是固定的还是动态的,父母都必须有一个高度。如果其他一些内容填充了 div 导致它具有高度(例如文本),它也将起作用。【参考方案7】:

游戏晚了,但我发现这种方法非常直观。 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>

【讨论】:

不错!它也可以简化。这个技巧是由父容器上的display: flex 和图像上的align-self: center 完成的。这是一个优化版本:codepen.io/anon/pen/dWKyey【参考方案8】:

在 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 是可变宽度和固定高度。 @Tom:如果我删除容器上的width设置,它将是父级的宽度,并且即使页面比图像窄,图像也会居中,即一样多左边缘的右边缘将被隐藏:jsfiddle.net/Guffa/L9BnL/2 感谢您的启发。我使用位置:相对于 .imageCenter。这样我就不需要 position: relative 的父容器。 这个问题有很多巧妙的技巧,它们都有自己的缺点。有些工作“更好”,但一点也不容易理解。这个解决方案非常有意义,图像通常在被裁剪的更宽的 div 中居中。感觉不对,但它绝对可以在不违反网络物理定律的情况下工作。我选择了这个选项而不是其他几个非常难以理解的技巧,即使它确实感觉有点脏。【参考方案9】:

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

.wrapper 
    overflow: hidden;

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

【讨论】:

【参考方案10】:

不要对图像标签使用固定或明确的宽度或高度。相反,编码:

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

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

【讨论】:

这会在图像周围留下空间,我相信这是他们试图避免的。【参考方案11】:

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

【讨论】:

这不是一种使用图像的可访问方式。它可能适用于装饰性图像,但任何信息丰富的图像都需要替代文本。 另外,每当你使用背景图片时,它会烦人地闪烁默认背景颜色,直到背景图片完全加载,并且无法预加载。【参考方案12】:

宽高仅为举例:

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 上。 如果图像小于容器,此技术有效。

以上是关于在 Div 中居中超大图像的主要内容,如果未能解决你的问题,请参考以下文章

在 div 中居中浮动图像

如何在div中居中图像?

使用 CSS 在 <DIV> 中居中 <IMG/>

需要在 CSS 中居中对齐图像

在 Bootstrap 中居中图像

如何在轮播中居中图像