【问题标题】:CSS force image resize and keep aspect ratioCSS强制图像调整大小并保持纵横比
【发布时间】:2012-10-11 01:51:38
【问题描述】:

我正在处理图像,但遇到了纵横比问题。

<img src="big_image.jpg" width="900" height="600" alt="" />

如您所见,height 和 width 已指定。我为图片添加了 CSS 规则:

img {
  max-width: 500px;
}

但是对于big_image.jpg,我收到width=500 和height=600。如何设置要调整大小的图像,同时保持它们的纵横比。

【问题讨论】:

    标签: css image aspect-ratio


    【解决方案1】:

    只需将height 属性替换为aspect-ratio 属性即可。

    img {
      max-width: 500px;
      aspect-ratio: 900 / 600;
    }
    &lt;img src="big_image.png" width="900"/&gt;

    aspect-ratio 属性不是必需的,但可以防止图像布局偏移。

    【讨论】:

    • height 和 width 属性不仅用于显示目的,还用于性能:它们告诉浏览器原始图像的大小。出于这个原因,我投了反对票:删除其中一个属性不应该是一个合适的解决方案。
    【解决方案2】:

    您可以使用:-

    transform: scaleX(1.2);
    

    改变宽度而不改变高度。

    和

    transform: scaleY(1.2);
    

    改变高度而不改变宽度

    您可以在 html 和 css 中的图像和视频标签上使用它。这也不会改变纵横比。

    【讨论】:

      【解决方案3】:

      Firefox 71+ (2019-12-03) 和 Chrome 79+ (2019-12-10) 支持 width 和 height 元素的内部 mapping 到新的@ 987654324@ CSS 属性(属性本身还不能直接使用)。

      计算出的纵横比用于为图片预留空间,直到加载完毕,只要计算出的纵横比与图片的实际纵横比相等,就可以防止加载图片后页面“跳转”。

      为此,必须通过 CSS 将两个图像尺寸之一覆盖为 auto 值:

      IMG {max-width: 100%; height: auto; }
      
      <img src="example.png" width="1280" height="720" alt="Example" />
      

      在示例中,即使图像尚未加载且有效图像宽度小于 1280(max-width: 100% 的结果),也会保持 16:9 (1280:720) 的宽高比。

      另请参阅相关的 Firefox bug 392261。

      【讨论】:

        【解决方案4】:

        如果应用程序可以拥有任何宽高比或分辨率的图像,那么您可以在此链接中管理高度和宽度。

        这使用 Javascript 和 HTML

        https://stackoverflow.com/a/65090175/13338731

        【讨论】:

          【解决方案5】:

          您可以将容器设置为display: flex 和align-items: center(其他align-items 值也可以)。除了align-items,您还可以在图像本身上设置align-self。

          【讨论】:

            【解决方案6】:

            这是心理问题。使用 scale-down 属性 - 它会自我解释。

            内联样式:

            <img src='/nic-cage.png' style={{ maxWidth: '50%', objectFit: 'scale-down' }} />
            

            这将阻止 flex 拉伸它。在这种情况下,图像将变为其父容器宽度的 50%,并且高度将缩小以匹配。

            保持简单。

            【讨论】:

              【解决方案7】:

              我一直在努力解决这个问题,最终得出了这个简单的解决方案:

              object-fit: cover;
              width: 100%;
              height: 250px;
              

              您可以根据需要调整宽度和高度,object-fit 属性会为您进行裁剪。

              有关object-fit 属性的可能值和兼容性表的更多信息,请参见此处:https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit

              干杯。

              【讨论】:

              • object-fit 太棒了,很棒的提示!如果有人想知道 IE 的兼容性,有一些很好的 polyfill 库。
              • 可爱,记住这个does not work for IE虽然
              • 您也可以使用object-fit: contain并指定宽度或高度!
              • 目前为止我能找到的最佳解决方案。尝试了许多排列和组合。发现使用style="object-fit: cover; max-width:100%; height:60px;",当要求在表&lt;td&gt; 中显示它们时,图像就像手套一样合适。 height 值仅用于演示。关键是,无论图像的原始尺寸如何,使用它我的行高都保持不变。
              • 天啊,这是我十多年来一直面临的一个反复出现的问题,没有任何解决方案像 object-fit: contain 这样优雅。非常感谢!!!!!!!!!!!!!!!
              【解决方案8】:

              这是一个解决方案:

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

              这将确保图像始终覆盖整个父级(缩小和放大)并保持相同的纵横比。

              【讨论】:

                【解决方案9】:

                我建议采用响应式方法,最佳做法是使用 Viewport units 和 min/max 属性,如下所示:

                img{
                  display: block;
                  width: 12vw;
                  height:12vw;
                  max-width:100%;
                  min-width:100px;
                  min-height:100px;
                  object-fit:contain;
                }
                

                【讨论】:

                  【解决方案10】:

                  全屏演示:

                  img[data-attribute] {height: 100vh;}
                  

                  请记住,如果视口高度大于图像,则图像会相对于差异自然降级。

                  【讨论】:

                    【解决方案11】:

                    以下解决方案将允许放大和缩小图像,具体取决于父框的宽度。

                    所有图像都有一个固定宽度的父容器仅用于演示目的。在生产中,这将是父框的宽度。

                    最佳实践(2018 年):

                    此解决方案告诉浏览器以最大可用宽度呈现图像,并将高度调整为该宽度的百分比。

                    .parent {
                      width: 100px;
                    }
                    
                    img {
                      display: block;
                      width: 100%;
                      height: auto;
                    }
                    <p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
                    <div class="parent">
                      <img width="400" height="400" src="https://placehold.it/400x400">
                    </div>

                    更高级的解决方案:

                    使用更高级的解决方案,您将能够裁剪图像而不管其大小,并添加背景颜色以补偿裁剪。

                    .parent {
                      width: 100px;
                    }
                    
                    .container {
                      display: block;
                      width: 100%;
                      height: auto;
                      position: relative;
                      overflow: hidden;
                      padding: 34.37% 0 0 0; /* 34.37% = 100 / (w / h) = 100 / (640 / 220) */
                    }
                    
                    .container img {
                      display: block;
                      max-width: 100%;
                      max-height: 100%;
                      position: absolute;
                      top: 0;
                      bottom: 0;
                      left: 0;
                      right: 0;
                    }
                    <p>This image is originally 640x220, but should get resized by the CSS:</p>
                    <div class="parent">
                      <div class="container">
                        <img width="640" height="220" src="https://placehold.it/640x220">
                      </div>
                    </div>

                    对于指定padding的行,需要计算图片的纵横比,例如:

                    640px (w) = 100%
                    220px (h) = ?
                    
                    640/220 = 2.909
                    100/2.909 = 34.37%
                    

                    所以,顶部填充 = 34.37%。

                    【讨论】:

                    • 它可以工作,但在大多数情况下应该是 max-width:100% 而不是宽度。
                    • 我认为这里不需要!important。
                    • 父级设置为 100px。这将如何响应?
                    • @Remi 用于演示目的。我在答案的顶部添加了一个说明。
                    • @Flimm 以前用于兼容性问题,2016 年不再需要。
                    【解决方案12】:

                    https://jsfiddle.net/sot2qgj6/3/

                    如果您想放置具有固定宽度百分比但不固定宽度像素的图像,这就是答案。

                    这在处理不同尺寸的屏幕时会很有用。

                    技巧是

                    1. 使用padding-top 设置宽度的高度。
                    2. 使用position: absolute 将图像放入填充空间。
                    3. 使用max-height and max-width 确保图像不会超过父元素。
                    4. 使用display:block and margin: auto 使图像居中。

                    我还评论了小提琴中的大部分技巧。


                    我还找到了一些其他方法来实现这一点。 html中不会有真实的图像,所以当我需要html中的“img”元素时,我个人更喜欢最佳答案。

                    使用背景的简单 css http://jsfiddle.net/4660s79h/2/

                    顶部有文字的背景图片 http://jsfiddle.net/4660s79h/1/

                    使用绝对位置的概念来自这里 http://www.w3schools.com/howto/howto_css_aspect_ratio.asp

                    【讨论】:

                    • 如果原始问题提到的“高度和宽度已经指定”,则此方法不起作用。有时您想强制宽度和高度,然后根据纵横比放大/缩小图像。
                    【解决方案13】:

                    与此处的一些答案非常相似,但就我而言,我的图像有时更高,有时更大。

                    这种风格就像一种魅力,可以确保所有图像都使用所有可用空间,保持比例而不是剪切:

                    .img {
                       object-fit: contain;
                       max-width: 100%;
                       max-height: 100%;
                       width: auto;
                       height: auto;
                    }
                    

                    【讨论】:

                    • object-fit 为我工作它是否适用于所有浏览器?
                    • .img 是父类还是图像上的类?你可以为纵向和横向图像制作一个 jsfiddle 示例吗?
                    【解决方案14】:

                    使用伪元素进行垂直对齐怎么样?这个更少的代码适用于轮播,但我想它适用于每个固定大小的容器。它将保持纵横比并在顶部/底部或左侧/写入上插入@gray-dark 条以获取最短尺寸。同时,图像通过 text-align 水平居中,通过伪元素垂直居中。

                        > li {
                          float: left;
                          overflow: hidden;
                          background-color: @gray-dark;
                          text-align: center;
                    
                          > a img,
                          > img {
                            display: inline-block;
                            max-height: 100%;
                            max-width: 100%;
                            width: auto;
                            height: auto;
                            margin: auto;
                            text-align: center;
                          }
                    
                          // Add pseudo element for vertical alignment of inline (img)
                          &:before {
                            content: "";
                            height: 100%;
                            display: inline-block;
                            vertical-align: middle;
                          }
                        }
                    

                    【讨论】:

                      【解决方案15】:

                      要强制适合精确尺寸的图像,您不需要编写太多代码。就是这么简单

                      img{
                          width: 200px;
                          height: auto;
                          object-fit: contain; /* Fit logo in the image size */
                              -o-object-fit: contain; /* Fit logo fro opera browser */
                          object-position: top; /* Set logo position */
                              -o-object-position: top; /* Logo position for opera browser */
                          }
                      &lt;img src="http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png" alt="Logo"&gt;

                      【讨论】:

                        【解决方案16】:

                        你可以用这个:

                        img { 
                            width: 500px; 
                            height: 600px; 
                            object-fit: contain; 
                            position: relative; 
                            top: 50%; 
                            transform: translateY(-50%); 
                        }
                        

                        【讨论】:

                          【解决方案17】:

                          要保持响应式图像,同时仍强制图像具有特定纵横比,您可以执行以下操作:

                          HTML:

                          <div class="ratio2-1">
                             <img src="../image.png" alt="image">
                          </div>
                          

                          和 SCSS:

                          .ratio2-1 {
                            overflow: hidden;
                            position: relative;
                          
                            &:before {
                              content: '';
                              display: block;
                              padding-top: 50%; // ratio 2:1
                            }
                          
                            img {
                              position: absolute;
                              top: 0;
                              left: 0;
                              bottom: 0;
                              right: 0;
                            }
                          }
                          

                          无论作者上传的图片大小如何,这都可用于强制实现特定的纵横比。

                          感谢@Kseso http://codepen.io/Kseso/pen/bfdhg。查看此 URL 了解更多比率和工作示例。

                          【讨论】:

                          • 我喜欢这个,因为它适用于圈子/border-radius。但不幸的是,它会裁剪图像,并且在我尝试过的 div 中为图像制作边框时效果不佳。
                          【解决方案18】:

                          img {
                            max-width: 80px; /* Also works with percentage value like 100% */
                            height: auto;
                          }
                          <p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
                          <img width="400" height="400" src="https://i.stack.imgur.com/aEEkn.png">
                          
                          <p>Let's say the author of the HTML deliberately wants
                            the height to be half the value of the width,
                            this CSS will ignore the HTML author's wishes, which may or may not be what you want:
                          </p>
                          <img width="400" height="200" src="https://i.stack.imgur.com/aEEkn.png">

                          【讨论】:

                            【解决方案19】:

                            img {
                              display: block;
                              max-width:230px;
                              max-height:95px;
                              width: auto;
                              height: auto;
                            }
                            <p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
                            <img width="400" height="400" src="http://i.stack.imgur.com/aEEkn.png">

                            如果图像对于指定区域太大,这会使图像缩小(缺点,它不会放大图像)。

                            【讨论】:

                            • 是否有这样的版本可以放大图像以适应其容器?我已经尝试将最大宽度/最大高度作为数字,宽度/高度为自动,但正如 setec 上面所说,它不会放大图像。我也尝试过使用最小宽度/最小高度。我只是无法正确组合。我只是希望无论我必须放入此容器中的任何图像,它都可以在不改变纵横比的情况下以最大尺寸显示,无论这是否涉及缩小或扩大图像来实现这一点。
                            • 似乎不再需要 display: block 了。
                            • 请注意,问题是关于&lt;img&gt;,它本身包含宽度和高度,我认为这意味着您需要使用!important 来规避标签宽度/高度信息。
                            • @AlexisWilke CSS 规则覆盖 html 属性。不需要!important。
                            • 在 Chrome 上使用它,对我不起作用,即使使用 !important
                            【解决方案20】:

                            只需将它添加到您的 css 中,它会自动收缩和扩展并保持原始比例。

                            img {
                                display: block;
                                max-width: 100%;
                                max-height: 100%;
                                width: auto;
                                height: auto;
                            }
                            

                            【讨论】:

                            • 这与setec's answer 的答案相同,但使用100% 而不是特定的像素值。
                            • display: block; 是不必要的。
                            • 完美,适用于任何大小和比例的图像
                            【解决方案21】:

                            如果图像对于指定区域太大,这会使图像缩小(缺点,它不会放大图像)。

                            setec 的解决方案适用于自动模式下的“Shrink to Fit”。 但是,为了优化 EXPAND 以适应“自动”模式,您需要首先将接收到的图像放入临时 ID, 检查它是否可以在高度或宽度上扩展(取决于它的纵横比与显示块的纵横比),

                            $(".temp_image").attr("src","str.jpg" ).load(function() { 
                                // callback to get actual size of received image 
                            
                                // define to expand image in Height 
                                if(($(".temp_image").height() / $(".temp_image").width()) > display_aspect_ratio ) {
                                    $(".image").css('height', max_height_of_box);
                                    $(".image").css('width',' auto');
                                } else { 
                                    // define to expand image in Width
                                    $(".image").css('width' ,max_width_of_box);
                                    $(".image").css('height','auto');
                                }
                                //Finally put the image to Completely Fill the display area while maintaining aspect ratio.
                                $(".image").attr("src","str.jpg");
                            });
                            

                            当接收到的图像小于显示框时,这种方法很有用。您必须将它们以原始小尺寸而不是它们的扩展版本保存在您的服务器上,以填充您的更大显示框以节省大小和带宽。

                            【讨论】:

                            • 虽然问题帖子没有说明,但我认为 OP 强烈暗示他/她正在寻找纯 CSS 的解决方案。
                            【解决方案22】:

                            你可以像这样创建一个 div:

                            <div class="image" style="background-image:url('/to/your/image')"></div>
                            

                            并使用这个 css 来设置样式:

                            height: 100%;
                            width: 100%;
                            background-position: center center;
                            background-repeat: no-repeat;
                            background-size: contain; // this can also be cover
                            

                            【讨论】:

                            • 这会将 div 拉伸到其父级的 100% 宽度,但不会保持图像的纵横比。
                            • 你试过了吗?我搞定了jsfiddle.net/zuysj22w。你能展示你的情况吗? @大卫球
                            • 这是与Hoffmann's answer类似的解决方案。
                            【解决方案23】:

                            将图片容器标签的 CSS 类设置为 image-class:

                            <div class="image-full"></div>
                            

                            并将其添加到您的 CSS 样式表中。

                            .image-full {
                                background: url(...some image...) no-repeat;
                                background-size: cover;
                                background-position: center center;
                            }
                            

                            【讨论】:

                              【解决方案24】:

                              background-size 属性仅为 ie>=9,但如果您觉得这没问题,您可以使用带有 background-image 的 div 并设置 background-size: contain:

                              div.image{
                                  background-image: url("your/url/here");
                                  background-size: contain;
                                  background-repeat: no-repeat;
                                  background-position: center;
                              }
                              

                              现在您可以将您的 div 大小设置为您想要的任何大小,并且图像不仅会保持其纵横比,而且还会在 div 中垂直和水平集中。只是不要忘记在 css 上设置大小,因为 div 在标签本身上没有宽度/高度属性。

                              这种方法与 setecs 答案不同,使用此方法,图像区域将保持不变并由您定义(根据 div 大小和图像纵横比,水平或垂直留出空白区域),而 setecs 答案将为您提供一个框正好是缩放图像的大小(没有空格)。

                              编辑: 根据MDN background-size documentation,您可以使用专有过滤器声明模拟 IE8 中的 background-size 属性:

                              虽然 Internet Explorer 8 不支持 background-size 属性,但可以使用非标准的 -ms-filter 函数来模拟它的一些功能:

                              -ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='path_relative_to_the_HTML_file', sizingMethod='scale')";
                              

                              【讨论】:

                              • 终于有了一个纯 CSS 的解决方案,可以在保持宽高比的同时最大化图像,谢谢。幸运的是,9 之前的 IE 越来越不重要了。
                              • 很好的解决方案,谢谢!另请注意,如果您想完全填充 div 并裁剪不符合比例的额外像素,则可以将 'contain' 替换为 'cover'
                              • 这应该是正确的答案。我喜欢这个解决方案。它可以保持您的比例并且易于理解。
                              • 虽然这是以编程方式的正确答案,但如果图像以这种方式“重要”,则您没有 img 属性,因此您正在扼杀 SEO。
                              • 太棒了!这是这些解决方案中唯一适用于纵向和横向图像以及图像的纵向和横向容器(例如根据窗口大小而变化)在所有 4 种组合中以及另外在 IE11 中的解决方案,这似乎相当要求。谢谢!
                              【解决方案25】:

                              删除“高度”属性。

                              <img src="big_image.jpg" width="900" alt=""/>
                              

                              通过指定两者,您正在更改图像的纵横比。只需设置一个即可调整大小但保留纵横比。

                              (可选)限制尺寸过大:

                              <img src="big_image.jpg" width="900" alt="" style="max-width:500px; height:auto; max-height:600px;"/>
                              

                              【讨论】:

                              • 我不能对所有图像都这样做 - 许多图像已经放置在许多 html 文件中
                              • 好的。试试 img {max-width:500px;高度:自动;最大高度:600px;}
                              • 应将评论等有用信息添加到您的帖子中。这样我们就可以立即看到您的想法。
                              • 在img标签中省略height属性的缺点是浏览器在下载图片之前无法计算图片会占用多少空间。这会使页面渲染速度变慢,并可能导致更多“跳跃”。
                              猜你喜欢
                              • 2012-11-15
                              • 2013-06-26
                              • 2012-04-15
                              • 2019-08-10
                              • 2012-05-01
                              相关资源
                              最近更新 更多