Chia tỷ lệ hình ảnh để vừa với một khung giới hạn


117

Có một giải pháp chỉ css để chia tỷ lệ hình ảnh vào một khung giới hạn (giữ tỷ lệ khung hình) không? Điều này hoạt động nếu hình ảnh lớn hơn container:

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

Thí dụ:

Nhưng tôi muốn mở rộng hình ảnh cho đến khi kích thước là 100% của container.


Bạn có nghĩa là thích chiều cao: 100% và chiều rộng: 100%? Bạn có một kích thước mong muốn mà bạn muốn đạt được? nếu không, bạn cũng có thể kéo dài hình ảnh và buộc nó cũng đạt được các kích thước đó.
mikevoermans

@mikevoermans Hãy xem hai ví dụ đầu tiên của tôi: Tôi muốn strech hình ảnh cho đến khi một trong các kích thước là 100% và cái còn lại là <= 100%
Thomas Guillory

@jacktheripper Bảo tồn tỷ lệ khung hình của khóa học ...
Thomas Guillory

@gryzzly Các ví dụ nói cho chính họ! Nếu họ đã xem xét các ví dụ, điều đó là hiển nhiên.
Thomas Guillory

@Artimuz Tôi hoàn toàn không đồng ý. Ba trong số các câu trả lời cho câu hỏi của bạn (bao gồm cả câu hỏi của tôi) cho thấy điều đó KHÔNG rõ ràng.
Khan

Câu trả lời:


94

Lưu ý: Mặc dù đây là câu trả lời được chấp nhận, câu trả lời dưới đây chính xác hơn và hiện được hỗ trợ trong tất cả các trình duyệt nếu bạn có tùy chọn sử dụng hình nền.

Không, không có cách duy nhất CSS để làm điều này theo cả hai hướng. Bạn có thể thêm

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

Để phần tử luôn có chiều rộng 100% và tự động chia tỷ lệ chiều cao theo tỷ lệ khung hình hoặc tỷ lệ nghịch:

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

để luôn luôn tỷ lệ đến chiều cao tối đa và chiều rộng tương đối. Để làm cả hai, bạn sẽ cần xác định xem tỷ lệ khung hình cao hơn hoặc thấp hơn so với vùng chứa của nó và CSS không thể làm điều này.

Lý do là CSS không biết trang trông như thế nào. Nó đặt ra các quy tắc trước, nhưng chỉ sau đó, các phần tử sẽ được hiển thị và bạn biết chính xác kích thước và tỷ lệ bạn đang xử lý. Cách duy nhất để phát hiện đó là với JavaScript.


Mặc dù bạn không tìm kiếm một giải pháp JS nào nhưng tôi sẽ thêm một giải pháp nếu có ai đó cần nó. Cách dễ nhất để xử lý việc này với JavaScript là thêm một lớp dựa trên sự khác biệt về tỷ lệ. Nếu tỷ lệ giữa chiều rộng và chiều cao của hộp lớn hơn tỷ lệ của hình ảnh, hãy thêm lớp "băng thông", nếu không thì thêm lớp "fillheight".


7
Trên thực tế có một giải pháp: thiết lập kích thước nền CSS3 để chứa. Xem câu trả lời của tôi.
Thomas Guillory

Bạn hoàn toàn đúng. Mặc dù bây giờ là một năm rưỡi sau, tôi đã chỉnh sửa bài viết của mình.
Stephan Muller

4
Tôi cho rằng đây là câu trả lời chính xác cho câu hỏi được hỏi, đó là CSS cho thẻ img. Điều này có liên quan vì về mặt ngữ nghĩa thẻ img là nội dung, hình ảnh làm nền cho div không. Mặc dù một số trường hợp làm cho điều này không thực tế (nếu bạn không biết tỷ lệ hình ảnh so với tỷ lệ container), đối với những trường hợp khác, điều đó hoàn toàn đúng. Cảm ơn.
duncanwilcox

173

Nhờ CSS3 có một giải pháp!

Giải pháp là để đưa hình ảnh như background-imagevà sau đó đặt background-sizeđể contain.

HTML

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

CSS

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

Kiểm tra nó ở đây: http://www.w3schools.com/cssref/playit.asp?filename=playcss_background-size&preval=contain

Tương thích hoàn toàn với các trình duyệt mới nhất: http://caniuse.com/background-img-opts

Để căn chỉnh div ở trung tâm, bạn có thể sử dụng biến thể này:

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

1
Một câu hỏi hay, mặc dù câu trả lời của tôi không đúng (bạn đã hỏi cụ thể về img) đây là một giải pháp tuyệt vời và tôi nên nghĩ về điều đó. Vấn đề duy nhất là IE 8 vẫn được sử dụng rộng rãi đến mức tôi chưa muốn dựa vào điều này, nhưng dù sao thì cũng rất tuyệt.
Stephan Muller

6
Đặt nó thành "che" nếu bạn không muốn bất kỳ hộp thư nào: kích thước nền: chứa;
arxpoetica

3
Cần lưu ý rằng bạn có thể chèn URL hình ảnh bằng HTML : <div class=image style="background-image: url('/images/foo.jpg');"></div>. Tất cả các phong cách khác nên được áp dụng với CSS.
Andrey Mikhaylov - lolmaus

14
Tôi sẽ nói đây là một cách tiếp cận khủng khiếp. Bằng cách thay đổi nó thành hình nền, bạn sẽ loại bỏ ý nghĩa ngữ nghĩa của hình ảnh trong HTML.
hoạt hình

14
@animuson: Nó vẫn giúp tôi khi tôi đang sử dụng HTML / CSS cho các báo cáo được in và không thể đưa ra một câu hỏi hay về ngữ nghĩa :)
Christian Wattengård

37

Đây là một giải pháp hackish tôi phát hiện ra:

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

Điều này sẽ phóng to hình ảnh lên gấp 10 lần, nhưng giới hạn ở mức 10% kích thước cuối cùng của nó - do đó ràng buộc nó với vật chứa.

Không giống như background-imagegiải pháp, điều này cũng sẽ làm việc với <video>các yếu tố.

Ví dụ tương tác:


1
Tôi thích giải pháp này. Nó không chỉ thực sự trả lời câu hỏi (tôi biết, suy nghĩ gì), nó hoạt động rất đẹp trong tất cả các trình duyệt hiện đại mà không cần phải dùng đến Javascript!
ndm13

2
Tôi rất muốn thấy một điều thú vị về điều đó. Trong thử nghiệm của tôi về việc đặt img trong thùng chứa 400x400, img chỉ bị cắt ở góc
cyberwombat

3
Câu trả lời tốt đẹp! @Yashua Bạn cần thêm transform-origin: top leftđể dừng việc cắt xén. / Zombie
XwipeoutX

Xuất sắc. Mối quan tâm duy nhất của tôi là có thể làm giảm chất lượng hình ảnh trong một trình duyệt được mã hóa kém, nhưng trên lý thuyết nó sẽ hoạt động tốt!
Codemonkey

Thú vị, nhưng không hoạt động trên Chrome. Kết quả trong một hàng cắt của hình ảnh.
MattK

23

Hôm nay, chỉ cần nói đối tượng phù hợp: chứa. Hỗ trợ là tất cả mọi thứ trừ IE: http://caniuse.com/#feat=object-fit


3
IE chỉ có khoảng 16% thị phần tại thời điểm viết bài này (09/12/2016 10:56 sáng) và tiếp tục suy giảm, vì vậy đây là câu trả lời tốt nhất cho tôi: D
Zhang

8
Đừng chỉnh sửa câu trả lời của người khác để sửa những thứ khác ngoài lỗi chính tả hoặc liên kết bị hỏng. Tôi sẽ không nói điều gì đó trẻ con như "Có một polyfill cho các trình duyệt tào lao" trong câu trả lời SO và tôi không đánh giá cao câu trả lời của mình được chỉnh sửa để làm cho nó giống như tôi đã nói. nếu bạn muốn sử dụng từ ngữ của bạn, hãy đặt chúng vào câu trả lời của riêng bạn.
Glenn Maynard

Tôi muốn nói, không phải IE là vấn đề, mà là Edge. Theo caniuse object-fitvẫn đang được phát triển cho nó.
BairDev

Đây phải là một trong những câu trả lời được bình chọn hàng đầu năm 2017 trở đi ... Theo liên kết caniuse ở trên, 90% tất cả người dùng trên toàn cầu hiện đang sử dụng trình duyệt hỗ trợ này
fgblomqvist

Tôi vừa đăng một câu trả lời hoạt động có và không có object-fit: stackoverflow.com/a/46456673/474031
gabrielmaldi

8

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

5

Bạn có thể thực hiện điều này với CSS thuần túy và hỗ trợ trình duyệt hoàn chỉnh, cho cả hình ảnh dài và chiều ngang cùng một lúc.

Đây là một đoạn hoạt động trong Chrome, Firefox và Safari (cả sử dụng object-fit: scale-downvà không sử dụng nó):

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>


2

Một giải pháp khác không có ảnh nền và không cần thùng chứa (mặc dù phải biết kích thước tối đa của hộp giới hạn):

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


Nếu cần sử dụng công cụ chứa, thì chiều rộng tối đa và chiều cao tối đa có thể được đặt thành 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;
}

Đối với điều này, bạn sẽ có một cái gì đó như:

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

1

Ví dụ này để kéo dài hình ảnh theo tỷ lệ để phù hợp với toàn bộ cửa sổ. Một ngẫu hứng cho mã chính xác ở trên là thêm$( 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();
});

Có hai nếu điều kiện. Cái đầu tiên tiếp tục kiểm tra xem chiều cao hình ảnh có nhỏ hơn div hay không và áp dụng .fillheightlớp trong khi lớp tiếp theo kiểm tra độ rộng và .fillwidthlớp áp dụng . Trong cả hai trường hợp, lớp khác được loại bỏ bằng cách sử dụng.removeClass()

Đây là CSS

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

Bạn có thể thay thế 100vhbằng 100%nếu bạn muốn kéo dài hình ảnh trong một div. Ví dụ này để kéo dài hình ảnh theo tỷ lệ để phù hợp với toàn bộ cửa sổ.


OP đặc biệt yêu cầu một cách tiếp cận chỉ css.
Colt McCormack

0

Bạn đang tìm cách để tăng quy mô lên nhưng không xuống?

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

Điều này tuy nhiên, không khóa tỷ lệ khung hình.


5
Cố gắng rõ ràng hơn một chút với mong đợi của bạn trước khi bỏ phiếu trả lời của ai đó. Đặc biệt là khi họ đã trả lời câu hỏi của bạn trước khi bạn xóa câu hỏi của mình bằng các chỉnh sửa.
Khan

2
Ngoài ra, hãy cố gắng lịch sự hơn. Không ai sẽ giúp bạn nếu bạn nói như vậy.
Misha Reyzlin

@Artimuz Tôi xin lỗi nếu tôi nhớ bạn, nhưng dường như tôi không rõ là bạn muốn giữ tỷ lệ khung hình, đó là lý do tại sao tôi nhận xét cụ thể về điều đó. Ngoài ra, bạn sẽ nhận thấy rằng tôi đã dán một đoạn mã của bạn từ các ví dụ. Tôi tin rằng giữ chiều cao: tự động; sẽ làm điều đó cho bạn nếu bạn chỉ định chiều rộng.
ericosg

0

Tôi đã sử dụng bảng để trung tâm hình ảnh bên trong hộp. Nó giữ tỷ lệ khung hình và chia tỷ lệ hình ảnh theo cách hoàn toàn bên trong hộp. Nếu hình ảnh nhỏ hơn hộp thì nó được hiển thị như ở giữa. Mã bên dưới sử dụng chiều rộng 40px và hộp chiều cao 40px. (Không hoàn toàn chắc chắn nó hoạt động tốt như thế nào vì tôi đã xóa nó khỏi một mã phức tạp khác và đơn giản hóa nó một chút)

CSS:

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

HTML:

<table class="SmallThumbnailContainer" cellpadding="0" cellspacing="0">
    <tr><td>
        <img src="thumbnail.jpg" alt="alternative text"/>
    </td></tr>
    </table>

0

Cách sạch nhất và đơn giản nhất để làm điều này:

Đầu tiên một số 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>

Cái này cần phải dùng mẹo!


0

Điều này đã giúp tôi:

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

Sau đó, trên phần tử (bạn có thể sử dụng javascript hoặc truy vấn phương tiện để thêm khả năng phản hồi):

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

Hi vọng điêu nay co ich!


-3
.boundingbox {
    width: 400px;
    height: 500px;
    border: 2px solid #F63;
}
img{
    width:400px;
    max-height: 500px;
    height:auto;
}

Tôi đang chỉnh sửa câu trả lời của mình để giải thích thêm về soluton của mình khi tôi đã bỏ phiếu.

Với các kiểu được đặt như được hiển thị ở trên trong css, bây giờ div html sau sẽ hiển thị hình ảnh luôn phù hợp với chiều rộng và sẽ điều chỉnh tỷ lệ khung hình cao theo chiều rộng. Do đó, hình ảnh sẽ chia tỷ lệ để vừa với một khung giới hạn như được hỏi trong câu hỏi.

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

Câu trả lời này chỉ hoạt động khi hộp cao hơn rộng.
XwipeoutX
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.