【问题标题】:Scale image to fit a bounding box缩放图像以适合边界框
【发布时间】:2012-04-17 04:18:42
【问题描述】:

是否有仅使用 css 的解决方案将图像缩放到边界框(保持纵横比)?如果图像大于容器,则此方法有效:

img {
  max-width: 100%;
  max-height: 100%;
}

例子:

但我想放大图像直到尺寸为容器的 100%。

【问题讨论】:

  • 你的意思是像 height: 100% 和 width: 100% 吗?你有想要达到的维度吗?否则你也可以拉伸图像并强制它达到这些尺寸。
  • @mikevoermans 看看我的前两个例子:我想拉伸图像直到一个尺寸为 100%,另一个为
  • @jacktheripper 当然要保持纵横比...
  • @gryzzly 例子不言自明!如果他们看过这些例子,那是显而易见的。
  • @Artimuz 我完全不同意。您的问题的三个答案(包括我的)表明这并不明显。

标签: html css image resize autoresize


【解决方案1】:

这符合我的需要,在设置高度限制时不会使图像变平,而是溢出。

.top-container{
       width:50%;
    }
.img-container {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 40vh;
        width: 100%;
        overflow: hidden;
    }
    
    .img-container img {
        max-width: 10%;
        max-height: auto;
        transform: scale(10);
    }
<div class='top-container'>
 <div class='img-container'>
  <img src='image.jpg'>
 </div>
</div>

【讨论】:

    【解决方案2】:

    在 div 和 img 上使用 Object Fit 来缩放图像

    <div class="box"><img src="image.jpg"></div>
    
    .box {height: auto;
    object-fit: cover;} 
    
    img { height: 100%; object-fit: cover; }
    

    【讨论】:

    • 你能edit你的答案解释为什么你的帖子不同/更好吗?
    【解决方案3】:

    注意:尽管这是公认的答案,但the answer below 更准确,如果您可以选择使用背景图片,目前所有浏览器都支持。

    编辑 2:在现代,使用 object-fit 可能是更好的解决方案:https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit

    不,没有 CSS 唯一的方法可以双向执行此操作。你可以添加

    .fillwidth {
        min-width: 100%;
        height: auto;
    }
    

    对于一个元素,使其始终具有 100% 的宽度并自动将高度缩放为纵横比,相反:

    .fillheight {
        min-height: 100%; 
        width: auto;
    }
    

    始终缩放到最大高度和相对宽度。要同时做到这两点,您需要确定纵横比是高于还是低于其容器,而 CSS 无法做到这一点。

    原因是 CSS 不知道页面的样子。它预先设置规则,但只有在此之后,元素才会被渲染,并且您确切知道您正在处理的大小和比率。检测它的唯一方法是使用 JavaScript。


    虽然您不是在寻找 JS 解决方案,但如果有人可能需要,我还是会添加一个。使用 JavaScript 处理此问题的最简单方法是根据比率差异添加一个类。如果框的宽高比大于图像的宽高比,则添加“fillwidth”类,否则添加“fillheight”类。

    $('div').each(function() {
      var fillClass = ($(this).height() > $(this).width()) 
        ? 'fillheight'
        : 'fillwidth';
      $(this).find('img').addClass(fillClass);
    });
    .fillwidth { 
      width: 100%; 
      height: auto; 
    }
    .fillheight { 
      height: 100%; 
      width: auto; 
    }
    
    div {
      border: 1px solid black;
      overflow: hidden;
    }
    
    .tower {
      width: 100px;
      height: 200px;
    }
    
    .trailer {
      width: 200px;
      height: 100px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="tower">
      <img src="http://placekitten.com/150/150" />
    </div>
    <div class="trailer">
      <img src="http://placekitten.com/150/150" />
    </div>

    【讨论】:

    • 其实有一个解决办法:设置CSS3 background-size 为contain。看我的回答。
    • 你完全正确。尽管现在已经过了一年半,我还是编辑了我的帖子。
    • 我认为这是问题的正确答案,即 img 标签的 CSS 是什么。这是相关的,因为在语义上 img 标签是内容,而作为 div 背景的图像不是。虽然在某些情况下这不切实际(如果您不知道图像与容器的比例),但对于其他情况来说,这是正确的。谢谢。
    • 致所有像我一样在 Google 上找到此内容的人:您可以使用 object-fit 和纯 CSS 来做到这一点。 developer.mozilla.org/en-US/docs/Web/CSS/object-fit
    • 感谢@lxhom,也添加了该信息:)
    【解决方案4】:

    我使用表格将图像居中放置在框内。它以完全在盒子内的方式保持纵横比和缩放图像。如果图像小于框,则显示为中心。下面的代码使用 40px 宽度和 40px 高度框。 (不太确定它的效果如何,因为我将它从另一个更复杂的代码中删除并稍微简化了一点)

    .SmallThumbnailContainer {
      display: inline-block;
      position: relative;
      float: left;
      width: 40px;
      height: 40px;
      border: 1px solid #ccc;
      margin: 0px;
      padding: 0px;
    }
    
    .SmallThumbnailContainer {
      width: 40px;
      margin: 0px 10px 0px 0px;
    }
    
    .SmallThumbnailContainer tr {
      height: 40px;
      text-align: center;
    }
    
    .SmallThumbnailContainer tr td {
      vertical-align: middle;
      position: relative;
      width: 40px;
    }
    
    .SmallThumbnailContainer tr td img {
      overflow: hidden;
      max-height: 40px;
      max-width: 40px;
      vertical-align: middle;
      margin: -1px -1px 1px -1px;
    }
    <table class="SmallThumbnailContainer" cellpadding="0" cellspacing="0">
      <tr>
        <td>
          <img src="https://www.gravatar.com/avatar/bf7d39f4ed9c289feca7de38a0093250?s=32&d=identicon&r=PG" width="32" height="32" alt="OP's SO avatar image used as a sample jpg because it is hosted on SO, thus always available" />
        </td>
      </tr>
    </table>

    注意:此 sn-p 中的原生缩略图大小为 32px x 32px,小于其 40px x 40px 容器。如果容器的尺寸小于任何尺寸的缩略图,例如 40 像素 x 20 像素,则图像以小于相应图像尺寸的尺寸流出容器。容器由 1px 的灰色边框标记。

    【讨论】:

      【解决方案5】:

      这是我发现的一个骇人听闻的解决方案:

      #image {
          max-width: 10%;
          max-height: 10%;
          transform: scale(10);
      }
      

      这会将图像放大十倍,但将其限制为最终大小的 10% - 从而将其绑定到容器中。

      background-image 解决方案不同,这也适用于&lt;video&gt; 元素。

      交互示例:

       function step(timestamp) {
           var container = document.getElementById('container');
           timestamp /= 1000;
           container.style.left   = (200 + 100 * Math.sin(timestamp * 1.0)) + 'px';
           container.style.top    = (200 + 100 * Math.sin(timestamp * 1.1)) + 'px';
           container.style.width  = (500 + 500 * Math.sin(timestamp * 1.2)) + 'px';
           container.style.height = (500 + 500 * Math.sin(timestamp * 1.3)) + 'px';
           window.requestAnimationFrame(step);
       }
      
       window.requestAnimationFrame(step);
       #container {
           outline: 1px solid black;
           position: relative;
           background-color: red;
       }
       #image {
           display: block;
           max-width: 10%;
           max-height: 10%;
           transform-origin: 0 0;
           transform: scale(10);
       }
      <div id="container">
          <img id="image" src="https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png">
      </div>

      【讨论】:

      • 我喜欢这个解决方案。它不仅真正回答了这个问题(我知道,这是一个多么好的想法),它在所有现代浏览器中都能很好地工作,而无需求助于 Javascript!
      • 我很想看看这个。在我将 img 放置在 400x400 容器中的测试中,img 只是在角落里被裁剪
      • 不错的答案! @Yashua 您需要添加 transform-origin: top left 以停止裁剪。 /僵尸
      • 有趣,但不适用于 Chrome。生成图像的裁剪行。
      • @Konstantin Scaling 只有在您还想放大图像时才需要(当它小于容器的宽度或高度时)。
      【解决方案6】:

      您可以使用纯 CSS 和完整的浏览器支持来实现这一点,同时适用于垂直长和水平长的图像。

      这是一个适用于 Chrome、Firefox 和 Safari 的 sn-p(都使用 object-fit: scale-down,并且不使用它):

      figure {
        margin: 0;
      }
      
      .container {
        display: table-cell;
        vertical-align: middle;
        width: 80px;
        height: 80px;
        border: 1px solid #aaa;
      }
      
      .container_image {
        display: block;
        max-width: 100%;
        max-height: 100%;
        margin-left: auto;
        margin-right: auto;
      }
      
      .container2_image2 {
        width: 80px;
        height: 80px;
        object-fit: scale-down;
        border: 1px solid #aaa;
      }
      Without `object-fit: scale-down`:
      
      <br>
      <br>
      
      <figure class="container">
        <img class="container_image" src="https://i.imgur.com/EQgexUd.jpg">
      </figure>
      
      <br>
      
      <figure class="container">
        <img class="container_image" src="https://i.imgur.com/ptO8pGi.jpg">
      </figure>
      
      <br> Using `object-fit: scale-down`:
      
      <br>
      <br>
      
      <figure>
        <img class="container2_image2" src="https://i.imgur.com/EQgexUd.jpg">
      </figure>
      
      <br>
      
      <figure>
        <img class="container2_image2" src="https://i.imgur.com/ptO8pGi.jpg">
      </figure>

      【讨论】:

        【解决方案7】:

        html:

            <div class="container">
              <img class="flowerImg" src="flower.jpg">
            </div>
        

        css:

        .container{
          width: 100px;
          height: 100px;
        }
        
        
        .flowerImg{
          width: 100px;
          height: 100px;
          object-fit: cover;
          /*object-fit: contain;
          object-fit: scale-down;
          object-position: -10% 0;
          object-fit: none;
          object-fit: fill;*/
        }
        

        【讨论】:

          【解决方案8】:

          另一种没有背景图像且不需要容器的解决方案(尽管必须知道边界框的最大尺寸):

          img{
            max-height: 100px;
            max-width: 100px;
            width: auto;    /* These two are added only for clarity, */
            height: auto;   /* as the default is auto anyway */
          }
          


          如果需要使用容器,则可以将 max-width 和 max-height 设置为 100%:
          img {
              max-height: 100%;
              max-width: 100%;
              width: auto; /* These two are added only for clarity, */
              height: auto; /* as the default is auto anyway */
          }
          
          div.container {
              width: 100px;
              height: 100px;
          }
          

          为此,您将有类似的内容:

          <table>
              <tr>
                  <td>Lorem</td>
                  <td>Ipsum<br />dolor</td>
                  <td>
                      <div class="container"><img src="image5.png" /></div>
                  </td>
              </tr>
          </table>
          

          【讨论】:

            【解决方案9】:

            这对我有帮助:

            .img-class {
              width: <img width>;
              height: <img height>;
              content: url('/path/to/img.png');
            }
            

            然后在元素上(可以使用 javascript 或媒体查询来添加响应性):

            <div class='img-class' style='transform: scale(X);'></div>
            

            希望这会有所帮助!

            【讨论】:

              【解决方案10】:

              今天,只说object-fit:contain。除了 IE,支持就是一切:http://caniuse.com/#feat=object-fit

              【讨论】:

              • 在撰写本文时(2016 年 9 月 12 日上午 10 点 56 分),IE 现在只有大约 16% 的市场份额并且还在继续减少,所以这对我来说是最好的答案:D
              • 不要编辑其他人的答案来修复拼写错误或损坏的链接以外的问题。我不会在 SO 答案中说“有一个用于垃圾浏览器的 polyfill”之类的幼稚的话,而且我不欣赏我的答案被编辑以使其看起来像我说的那样。如果你想用你的话,把它们放在你自己的答案中。
              • 我想说,问题不是 IE,而是 Edge。根据 caniuse 的说法,object-fit 仍在开发中。
              • 这应该是 2017 年及以后投票最多的答案之一...根据上面的 caniuse 链接,全球 90% 的用户现在使用支持此功能的浏览器
              • 我刚刚发布了一个可以使用和不使用object-fit的答案:stackoverflow.com/a/46456673/474031
              【解决方案11】:

              最干净和最简单的方法:

              首先是一些 CSS:

              div.image-wrapper {
                  height: 230px; /* Suggestive number; pick your own height as desired */
                  position: relative;
                  overflow: hidden; /* This will do the magic */
                  width: 300px; /* Pick an appropriate width as desired, unless you already use a grid, in that case use 100% */
              }
              img {
                  width: 100%;
                  position: absolute;
                  left: 0;
                  top: 0;
                  height: auto;
              }
              

              HTML:

              <div class="image-wrapper">
                <img src="yourSource.jpg">
              </div>
              

              这应该可以解决问题!

              【讨论】:

                【解决方案12】:
                .boundingbox {
                    width: 400px;
                    height: 500px;
                    border: 2px solid #F63;
                }
                img{
                    width:400px;
                    max-height: 500px;
                    height:auto;
                }
                

                我正在编辑我的答案以进一步解释我的解决方案,因为我投了反对票。

                在css中设置了如上所示的样式,现在以下html div将显示图像始终适合宽度,并将调整高宽比到宽度。因此,图像将按照问题中的要求缩放以适合边界框

                <div class="boundingbox"><img src="image.jpg"/></div>
                

                【讨论】:

                • 此答案仅适用于盒子的高度大于宽度的情况。
                【解决方案13】:

                此示例按比例拉伸图像以适合整个窗口。 对上述正确代码的即兴创作是添加$( window ).resize(function(){});

                function stretchImg(){
                    $('div').each(function() {
                      ($(this).height() > $(this).find('img').height()) 
                        ? $(this).find('img').removeClass('fillwidth').addClass('fillheight')
                        : '';
                      ($(this).width() > $(this).find('img').width()) 
                        ? $(this).find('img').removeClass('fillheight').addClass('fillwidth')
                        : '';
                    });
                }
                stretchImg();
                
                $( window ).resize(function() {
                    strechImg();
                });
                

                有两个 if 条件。第一个继续检查图像高度是否小于 div 并应用 .fillheight 类,而下一个检查宽度并应用 .fillwidth 类。 在这两种情况下,使用 .removeClass() 删除另一个类

                这里是 CSS

                .fillwidth { 
                   width: 100%;
                   max-width: none;
                   height: auto; 
                }
                .fillheight { 
                   height: 100vh;
                   max-width: none;
                   width: auto; 
                }
                

                如果要在 div 中拉伸图像,可以将 100vh 替换为 100%。此示例按比例拉伸图像以适合整个窗口。

                【讨论】:

                • OP 专门要求使用纯 CSS 方法。
                【解决方案14】:

                感谢 CSS3 有一个解决方案!

                解决方法是将图片设置为background-image,然后将background-size设置为contain

                HTML

                <div class='bounding-box'>
                </div>
                

                CSS

                .bounding-box {
                  background-image: url(...);
                  background-repeat: no-repeat;
                  background-size: contain;
                }
                

                在这里测试:http://www.w3schools.com/cssref/playit.asp?filename=playcss_background-size&preval=contain

                完全兼容最新浏览器:http://caniuse.com/background-img-opts

                要将 div 居中对齐,您可以使用以下变体:

                .bounding-box {
                  background-image: url(...);
                  background-size: contain;
                  position: absolute;
                  background-position: center;
                  background-repeat: no-repeat;
                  height: 100%;
                  width: 100%;
                }
                

                【讨论】:

                • 不错,虽然我的回答并不正确(您是在专门询问 img),但这是一个很好的解决方案,我应该想到这一点。唯一的问题是 IE 8 仍然被广泛使用,我还不想依赖它,但还是不错的。
                • 如果您不想要任何信箱,请将其设置为“覆盖”:背景大小:包含;
                • 需要注意的是,您可以使用 HTML 注入图像 URL:&lt;div class=image style="background-image: url('/images/foo.jpg');"&gt;&lt;/div&gt;。所有其他样式都应使用 CSS。
                • 我会说这是一种糟糕的方法。通过将其更改为背景图像,您将删除 HTML 中图像的语义含义。
                • @animuson:它仍然对我有帮助,因为我正在使用 HTML/CSS 打印报告,并且无法对语义发表意见 :)
                【解决方案15】:

                您是否希望向上扩展而不是向下扩展?

                div {
                    border: solid 1px green;
                    width: 60px;
                    height: 70px;
                }
                
                div img {
                    width: 100%;
                    height: 100%;
                    min-height: 500px;
                    min-width: 500px;
                    outline: solid 1px red;
                }
                

                但是,这不会锁定纵横比。

                【讨论】:

                • 在否决某人的答案之前,请尝试更清楚您的期望。尤其是当他们在您通过编辑解决问题之前回答了您的问题时。
                • 另外,尽量礼貌一点。如果你这样说话,没有人会帮助你。
                • @Artimuz 如果我误导了您,我深表歉意,但我似乎不清楚您是否希望保持纵横比,这就是我特别评论的原因。此外,您会注意到我从示例中粘贴了您的代码的 sn-p。我相信保持高度:自动;如果您指定宽度,将为您执行此操作。
                猜你喜欢
                • 2021-04-07
                • 1970-01-01
                • 2013-11-15
                • 2010-10-11
                • 2018-08-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多