【问题标题】:Vertically align an image inside a div with responsive height将 div 内的图像与响应高度垂直对齐
【发布时间】:2013-09-02 04:53:45
【问题描述】:

我有以下代码设置了一个容器,该容器的高度在调整浏览器大小时随宽度变化(以保持方形纵横比)。

HTML

<div class="responsive-container">
    <div class="dummy"></div>
    <div class="img-container">
        <IMG HERE>
    </div>
</div>

CSS

.responsive-container {
    position: relative;
    width: 100%;
    border: 1px solid black;
}

.dummy {
    padding-top: 100%; /* forces 1:1 aspect ratio */
}

.img-container {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

如何垂直对齐容器内的 IMG?我所有的图像都有可变高度,容器不能有固定的高度/行高,因为它是响应式的......请帮忙!

【问题讨论】:

标签: html css responsive-design vertical-alignment


【解决方案1】:

这是一种在中同时水平和垂直对齐内联元素的技术:

垂直对齐

1) 在这种方法中,我们创建一个inline-block(伪)元素作为的第一个(或最后一个)子元素,并设置其@ 987654338@ 属性到100% 以获取其父级的所有高度。

2) 此外,添加vertical-align: middle 可将内联(-block) 元素保持在行间距的中间。因此,我们将 CSS 声明添加到 first-childour elementimage)两者中。

3) 最后,为了去除inline(-block)元素之间的空白字符,我们可以设置parent 由font-size: 0; 归零。

注意:我在下面使用了 Nicolas Gallagher 的image replacement technique

有什么好处?

  • 容器(父容器)可以有动态尺寸。
  • 无需明确指定图像元素的尺寸。

  • 我们也可以轻松地将这种方法用于align a &lt;div&gt; element vertically;它可能具有动态内容(高度和/或宽度)。但请注意,您必须重新设置divfont-size 属性才能显示内部文本。 Online Demo

<div class="container">
    <div id="element"> ... </div>
</div>
.container {
    height: 300px;
    text-align: center;  /* align the inline(-block) elements horizontally */
    font: 0/0 a;         /* remove the gap between inline(-block) elements */
}

.container:before {    /* create a full-height inline block pseudo=element */
    content: ' ';
    display: inline-block;
    vertical-align: middle;  /* vertical alignment of the inline element */
    height: 100%;
}

#element {
    display: inline-block;
    vertical-align: middle;  /* vertical alignment of the inline element */
    font: 16px/1 Arial sans-serif;        /* <-- reset the font property */
}

输出

响应式容器

本节不打算回答这个问题,因为 OP 已经知道如何创建响应式容器。不过,我会解释它是如何工作的。

为了使容器元素的 height 随其 width 变化(考虑纵横比),我们可以为 top/bottom @987654347 使用百分比值@属性。

顶部/底部填充或边距上的 percentage value 与包含块的宽度相关。

例如:

.responsive-container {
  width: 60%;

  padding-top: 60%;    /* 1:1 Height is the same as the width */
  padding-top: 100%;   /* width:height = 60:100 or 3:5        */
  padding-top: 45%;    /* = 60% * 3/4 , width:height =  4:3   */
  padding-top: 33.75%; /* = 60% * 9/16, width:height = 16:9   */
}

这里是 Online Demo。注释掉底部的行并调整面板大小以查看效果。

此外,我们可以将padding 属性应用于虚拟 子元素或:before/:after 伪元素以达到相同的结果。但注意,在这种情况下,padding 上的百分比值是相对于.responsive-container 本身的宽度

<div class="responsive-container">
  <div class="dummy"></div>
</div>
.responsive-container { width: 60%; }

.responsive-container .dummy {
  padding-top: 100%;    /*  1:1 square */
  padding-top: 75%;     /*  w:h =  4:3 */
  padding-top: 56.25%;  /*  w:h = 16:9 */
}

Demo #1
Demo #2 (使用:after伪元素)

添加内容

容器内的内容顶部或底部使用padding-top 属性causes a huge space

为了解决这个问题,我们用一个包装器元素包装了内容,使用absolute positioning从文档正常流程中删除该元素,最后展开包装器(使用topright、@987654360 @ 和 left 属性)来填充其父容器容器的整个空间。

我们开始吧:

.responsive-container {
  width: 60%;
  position: relative;
}

.responsive-container .wrapper {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
}

这里是Online Demo


齐心协力

<div class="responsive-container">
  <div class="dummy"></div>

  <div class="img-container">
    <img src="http://placehold.it/150x150" alt="">
  </div>
</div>
.img-container {
  text-align:center; /* Align center inline elements */
  font: 0/0 a;       /* Hide the characters like spaces */
}

.img-container:before {
  content: ' ';
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

.img-container img {
  vertical-align: middle;
  display: inline-block;
}

这里是WORKING DEMO

显然,为了浏览器兼容性,您可以避免使用::before 伪元素,并创建一个元素作为.img-container 的第一个子元素:

<div class="img-container">
    <div class="centerer"></div>
    <img src="http://placehold.it/150x150" alt="">
</div>
.img-container .centerer {
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

UPDATED DEMO

使用max-* 属性

为了使框内的图像保持较低的宽度,您可以在图像上设置max-heightmax-width属性:

.img-container img {
    vertical-align: middle;
    display: inline-block;
    max-height: 100%;  /* <-- Set maximum height to 100% of its parent */
    max-width: 100%;   /* <-- Set maximum width to 100% of its parent */
}

这里是UPDATED DEMO

【讨论】:

  • 嗨,Hashem 非常感谢您的回答 - 这对于桌面浏览器来说就像魔术一样,即使重新调整为更小的宽度也是如此。但不幸的是,在移动设备(Android v2.3.5)上,图像在容器 div 下方出现了不合适的位置。对此有什么解决办法吗?
  • @user1794295 我通过 browserstack.com 在三个装有 android v2.3(Galaxy S II、Galaxy Note、Motorola Droid 4)的 android 设备上测试了这个小提琴,一切正常。你可以找到结果在这里:browserstack.com/screenshots/…。请提供屏幕截图或对您的问题进行特定测试。我会尽可能提供帮助。
  • 您好,这里有一些屏幕截图:browserstack.com/screenshots/… - 正如您在较小的设备(例如 Xperia、LG Nexus 4)上看到的那样,图像出现在容器下方...这是怎么回事?!
  • @HashemQolami 这是最神奇的 CSS 东西,因为我已经开始构建网站了 :)。
  • 感谢font-size: 0;
【解决方案2】:

使用 flexbox 这很容易:

FIDDLE

只需将以下内容添加到图像容器中:

.img-container {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex; /* add */
    justify-content: center; /* add to align horizontal */
    align-items: center; /* add to align vertical */
}

【讨论】:

  • 这个解决方案有效并且在我的情况下更加优雅。 CSS3 Flex 太棒了!
  • 它在 Safari 中不起作用 :( 我猜问题是 flex
  • @yennefer for safari 使用 -webkit- 前缀,或尝试使用类似 prefixfree.js 的库 :)
  • 当容器的高度是响应式(百分比)时,这不起作用。
【解决方案3】:

使用这个 css,因为你已经有了它的标记:

.img-container {
    position: absolute;
    top: 50%;
    left: 50%;
}

.img-container > img {
  margin-top:-50%;
  margin-left:-50%;  
}

这是一个有效的 JsBin:http://jsbin.com/ihilUnI/1/edit

此解决方案仅适用于方形图像(因为百分比 margin-top 值取决于容器的宽度,而不是高度)。对于随机大小的图像,您可以执行以下操作:

.img-container {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%); /* add browser-prefixes */
}

工作 JsBin 解决方案:http://jsbin.com/ihilUnI/2/edit

【讨论】:

  • 抱歉,对我不起作用 - 这只是将图像的大小减小到容器宽度的一半。
  • 我不明白我提到的 CSS 是如何发生这种情况的。请提供我可以看到的工作示例,以便我可以改进我的答案。 PS:我还提供了另一种解决方案:)
【解决方案4】:

您可以使用margin: auto 和绝对定位将图像水平和垂直居中。另外:

  1. 可以通过使用伪元素来抛弃额外的标记。
  2. 可以通过使用负左、上、右和下值来显示 LARGE 图像的中间部分。

.responsive-container {
  margin: 1em auto;
  min-width: 200px;       /* cap container min width */
  max-width: 500px;       /* cap container max width */
  position: relative;     
  overflow: hidden;       /* crop if image is larger than container */
  background-color: #CCC; 
}
.responsive-container:before {
  content: "";            /* using pseudo element for 1:1 ratio */
  display: block;
  padding-top: 100%;
}
.responsive-container img {
  position: absolute;
  top: -999px;            /* use sufficiently large number */
  bottom: -999px;
  left: -999px;
  right: -999px;
  margin: auto;           /* center horizontally and vertically */
}
<p>Note: images are center-cropped on &lt;400px screen width.
  <br>Open full page demo and resize browser.</p>
<div class="responsive-container">
  <img src="http://lorempixel.com/400/400/sports/9/">
</div>
<div class="responsive-container">
  <img src="http://lorempixel.com/400/200/sports/8/">
</div>
<div class="responsive-container">
  <img src="http://lorempixel.com/200/400/sports/7/">
</div>
<div class="responsive-container">
  <img src="http://lorempixel.com/200/200/sports/6/">
</div>

【讨论】:

  • 谢谢!你的 .responsive-container img css 是唯一对我有用的。
【解决方案5】:

试试这个

  .responsive-container{
          display:table;
  }
  .img-container{
          display:table-cell;
          vertical-align: middle;
   }

【讨论】:

  • 抱歉这不起作用,我认为因为我的.img-container 是绝对定位的——这是保持正方形纵横比/动态高度所必需的。
【解决方案6】:

这是一种技术,可让您将任何内容垂直和水平居中!

基本上,您只需要两个容器并确保您的元素符合以下条件。

外容器:

  • 应该有display: table;

内部容器:

  • 应该有display: table-cell;
  • 应该有vertical-align: middle;
  • 应该有text-align: center;

内容框:

  • 应该有display: inline-block;

如果您使用这种技术,只需将您的图片(以及您想要使用的任何其他内容)添加到内容框中。

演示:

body {
    margin : 0;
}

.outer-container {
    position : absolute;
    display: table;
    width: 100%;
    height: 100%;
    background: #ccc;
}

.inner-container {
    display: table-cell;
    vertical-align: middle;
    text-align: center;
}

.centered-content {
    display: inline-block;
    background: #fff;
    padding : 12px;
    border : 1px solid #000;
}

img {
   max-width : 120px;
}
<div class="outer-container">
   <div class="inner-container">
     <div class="centered-content">
        <img src="https://i.stack.imgur.com/mRsBv.png" />
     </div>
   </div>
</div>

另见this Fiddle

【讨论】:

    【解决方案7】:

    我在寻找解决方案时遇到了这个帖子:

    • 使用给定图像宽度的 100%
    • 保持图像纵横比
    • 保持图像与中间垂直对齐
    • 适用于不完全支持 flex 的浏览器

    测试上面发布的一些解决方案我没有找到满足所有这些标准的解决方案,所以我整理了这个简单的解决方案,它可能对其他需要这样做的人有用:

    .container {
      width: 30%;
      float: left;
      border: 1px solid turquoise;
      margin-right: 3px;
      margin-top: 3px;
    }
    
    .container:last-of-kind {
      margin-right: 0px;
    }
    
    .image-container {
      position: relative;
      overflow: hidden;
      padding-bottom: 70%;
      /* this is the desired aspect ratio */
      width: 100%;
    }
    
    .image-container img {
      position: absolute;
      /* the following 3 properties center the image on the vertical axis */
      top: 0;
      bottom: 0;
      margin: auto;
      /* uses image at 100% width (also meaning it's horizontally center) */
      width: 100%;
    }
    <div class="container">
      <div class="image-container">
        <img src="http://placehold.it/800x800" class="img-responsive">
      </div>
    </div>
    
    <div class="container">
      <div class="image-container">
        <img src="http://placehold.it/800x800" class="img-responsive">
      </div>
    </div>
    
    <div class="container">
      <div class="image-container">
        <img src="http://placehold.it/800x800" class="img-responsive">
      </div>
    </div>

    JSFiddle 上的工作示例

    【讨论】:

      【解决方案8】:

      试试

      HTML

      <div class="responsive-container">
           <div class="img-container">
               <IMG HERE>
           </div>
      </div>
      

      CSS

      .img-container {
          position: absolute;
          top: 0;
          left: 0;
      height:0;
      padding-bottom:100%;
      }
      .img-container img {
      width:100%;
      }
      

      【讨论】:

        【解决方案9】:

        html代码

        <div class="image-container"> <img src=""/> </div>

        css代码

        img
        {
          position: relative;
          top: 50%;
          transform: translateY(-50%);
         }
        

        【讨论】:

        • 虽然欢迎使用此代码 sn-p,并且可能会提供一些帮助,但它会是 greatly improved if it included an explanation of 如何解决这个问题。没有它,你的答案就没有多大的教育价值了——记住你是在为将来的读者回答这个问题,而不仅仅是现在问的人!请edit您的答案添加解释,并说明适用的限制和假设。
        【解决方案10】:

        创建另一个 div 并在 div 中添加 'dummy' 和 'img-container'

        HTML 和 CSS 如下所示

        html , body {height:100%;}
        .responsive-container { height:100%; display:table; text-align:center; width:100%;}
        .inner-container {display:table-cell; vertical-align:middle;}
        <div class="responsive-container">
            <div class="inner-container">
        		<div class="dummy">Sample</div>
        		<div class="img-container">
        			Image tag
        		</div>
        	</div>	
        </div>

        你可以给你想要的高度,而不是 100% 的“响应容器”。,

        【讨论】:

          猜你喜欢
          • 2018-12-21
          • 2013-03-06
          • 2011-07-22
          • 1970-01-01
          • 1970-01-01
          • 2014-03-02
          • 2011-05-02
          • 2014-01-02
          • 2011-07-21
          相关资源
          最近更新 更多