【问题标题】:Flexbox image scale to height and keep aspect ratioFlexbox 图像缩放到高度并保持纵横比
【发布时间】:2015-07-31 14:08:37
【问题描述】:

我有一个使用 CSS flexbox 缩放到可用高度的 DIV。在这个 DIV 中是一个图像,我想在两个维度上与 DIV 一起缩放。这意味着它应该在保持其纵横比的情况下进行缩放,并且小于相应 DIV 尺寸的尺寸应该居中。

我可以使图像跟随 DIV 的宽度,但不能跟随高度。因此,肖像图像会脱离 DIV 界限。

这是一个jsFiddle 来演示问题。

html, body {
  height: 100%;
  margin: 0;
}
.container {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.box {
  flex: 1 1 auto;
  display: flex;
  justify-content: center;
  align-items: center;
}
.box img {
  width: auto;
  height: auto;
  max-width: 90%;
  max-height: 90%;
}
<div class="container">
  <div class="box"></div>
  <div class="box" style="background: pink;">
    <img src="//dummyimage.com/300" />
  </div>
  <div class="box"></div>
</div>

【问题讨论】:

  • 你想让图像适合高度,即使它自然更小? (您在示例中使用了相当大的图片,所以我不确定)
  • 我想实现的第一件事是它可以根据需要缩小。
  • 不,抱歉,图像应保留其原始纵横比。如果这个与容器的不同,则图像应在调整大小后沿小于容器之一的轴居中。
  • 谢谢。改写。使用背景图片可能是最后的手段,因为图片是网站的主要内容,通常应该通过 HTML 来表示,而不是作为样式。但如果没有其他办法......
  • flexbox 布局是因为图像缩放问题而实现的,还是其他原因? (即:是否可以选择更改为阻止 DIV?)

标签: html css flexbox


【解决方案1】:

基于@darrylyeo 的回答。

.container {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: stretch;

  width: 100%;
  height: 100%;

  border-radius: 4px;
  background-color: hsl(0, 0%, 96%);
}

.box {
  border-radius: 4px;
  display: flex;
}

.box img {
  width: 100%;
  object-fit: contain;
  border-radius: 4px;
}

【讨论】:

    【解决方案2】:

    当您将高度指定为百分比值时,即相对于父元素高度的百分比。 &lt;img&gt; 标签也是如此。

    在这个未知高度的 flexbox 布局中,您可以使用 position 技巧使图像同时适合 flex 项的宽度和高度,并使用 transform 技巧进行居中。

    jsFiddle

    html, body {
      height: 100%;
      margin: 0;
    }
    .container {
      height: 100%;
      display: flex;
      flex-direction: column;
    }
    .box {
      flex: 1 1 auto;
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
    }
    .box:nth-child(2) {
      background: pink;
    }
    .box img {
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      width: auto;
      height: auto;
      max-width: 100%;
      max-height: 100%;
    }
    <div class="container">
      <div class="box"></div>
      <div class="box">
        <img src="//dummyimage.com/300" />
      </div>
      <div class="box"></div>
    </div>

    你也可以使用background图片,这样会方便很多,关键是使用contain这个值。请参阅下面的简化演示。

    jsFiddle

    html, body {
      height: 100%;
      margin: 0;
    }
    .container {
      height: 100%;
      display: flex;
      flex-direction: column;
    }
    .box {
      flex: 1 1 auto;
    }
    .box:nth-child(2) {
      background: pink url(//dummyimage.com/300) no-repeat center center / contain;
    }
    <div class="container">
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
    </div>

    【讨论】:

      【解决方案3】:

      删除图片标签并将其设置为.box div的背景background-size:cover;
      jsfiddle 1

      或者,如果您想避免裁剪:

      删除图片标签并将其设置为.box div的背景background-size:contain;
      jsfiddle 2

      【讨论】:

      • 两种情况都会导致图像裁剪。
      • 您没有显示与图像高度匹配的弹性容器。这不符合 OP 的要求。
      【解决方案4】:

      使用 flexbox! (JSFiddle)

      body, html {
          height: 100%;
          margin: 0;
          padding: 0;
      }
      
      .container {
          display: flex;
          flex-flow: column;
          width: 100%;
          height: 100%;
      }
      
      .box {
          flex: 1 1 auto;
          background: yellow;
          display: flex;
          justify-content: center;
          align-items: stretch;
      }
      
      .box img {
          width: 100%;
          object-fit: contain;
      }
      

      关键是用object-fit: contain;保持纵横比,align-items: stretch;保证图像左右不被截断(可能是bug?)。

      【讨论】:

      【解决方案5】:

      如果你可以从 flex 改为 block

      https://jsfiddle.net/svArtist/ug6eoxfs/

      正如@janfoeh 指出的那样,使用 object-fit: contains 使之成为可能:

      body, html {
          height: 100%;
          margin: 0;
          padding: 0;
          overflow:hidden;
          position:relative;
      }
      
      .container {
          width: 100%;
          max-width: 100%;
          height: 100%;
          max-height: 100%;
      }
      
      .box {
          background: yellow;
          width: 100%;
          padding: 0 5%;
          box-sizing:border-box;
          max-width: 100%;
          height: 100%;
          max-height:100%;
          position:relative;
      }
      
      .box img {
          height:100%;
          max-height: 100%;
          width: auto;
          max-width: 100%;
          margin: auto;
          position:absolute;
          top:0%;
          bottom:0%;
          left:0%;
          right:0%;
          display:block;
          object-fit: contain;
      }
      

      如果需要 Flex 布局,作为最后的手段,您可以考虑使用背景图像,这让整个事情变得非常简单:https://jsfiddle.net/svArtist/e1c2tLme/

          background: url(http://placehold.it/300) no-repeat center center;
          background-size: contain;
      

      除此之外,我找不到不涉及脚本的方法。

      【讨论】:

      • 对不起,但这正是我在小提琴中所拥有的,它不起作用?
      • 感谢您的解决方案。我会尝试一下,看看我是否可以重新排列布局或切换到背景图像。我不确定我是否可以接受这是对特定 flexbox 问题的回答。
      • 是的,这并不理想。所以 JavaScript 不是一个选项?
      • 我通常会在浏览器中阻止 javascript。所以将它用于我自己的网站是一个坏习惯;)
      • @languitar 阻止 javascript?该死的,丹尼尔
      猜你喜欢
      • 2016-05-18
      • 2010-11-25
      • 2013-08-07
      • 1970-01-01
      • 2013-03-04
      • 2011-08-24
      • 2013-02-26
      • 2013-07-07
      相关资源
      最近更新 更多