Kích thước hình ảnh CSS, làm thế nào để điền, không kéo dài?


415

Tôi có một hình ảnh và tôi muốn đặt chiều rộng và chiều cao cụ thể (tính bằng pixel)

Nhưng nếu tôi đặt chiều rộng và chiều cao bằng css ( width:150px; height:100px), hình ảnh sẽ bị kéo dài và nó có thể xấu.

Làm cách nào để lấp đầy hình ảnh đến một kích thước cụ thể bằng CSS và không kéo dài nó?

Ví dụ về hình ảnh điền và kéo dài:

Ảnh gốc:

Nguyên

Hình ảnh kéo dài:

Kéo dài

Hình ảnh đầy:

Đầy

Xin lưu ý rằng trong ví dụ về hình ảnh đã điền ở trên: đầu tiên, hình ảnh được thay đổi kích thước thành 150x255 (tỷ lệ khung hình được duy trì), và sau đó, nó được cắt thành 150x100.


Hãy thử chỉ thiết lập widthheightnên điều chỉnh cho phù hợp
NewInTheBusiness

3
kéo dài hình ảnh. xem cái này: jsfiddle.net/D7E3E
Mahdi Ghiasi

Nó có một phần của hình ảnh không thay đổi kích thước!
Ali Ben Messaoud

3
Chris Coyier cũng có một số giải pháp tốt để này: css-tricks.com/perfect-full-page-background-image
ambiguousmouse

1
RẤT QUAN TRỌNG: đây là một thực tế cực kỳ tồi tệ cho mục đích SEO. Nếu bạn đang sử dụng nó làm hình nền thì nó hoạt động tốt, nhưng nếu bạn muốn Google tìm thấy hình ảnh thì nó sẽ KHÔNG được lập chỉ mục nếu nó chỉ là hình nền.
Alex Banman

Câu trả lời:


395

Nếu bạn muốn sử dụng hình ảnh làm nền CSS, có một giải pháp tao nhã. Chỉ cần sử dụng coverhoặc containtrong thuộc tính background-sizeCSS3.

.container {
  width: 150px;
  height: 100px;
  background-image: url("http://i.stack.imgur.com/2OrtT.jpg");
  background-size: cover;
  background-repeat: no-repeat;
  background-position: 50% 50%;
}
<div class="container"></div>

Trong khi coversẽ cung cấp cho bạn một hình ảnh thu nhỏ, containsẽ cung cấp cho bạn một hình ảnh thu nhỏ. Cả hai sẽ duy trì tỷ lệ khung hình pixel.

http://jsfiddle.net/uTHqs/ (sử dụng bìa)

http://jsfiddle.net/HZ2FT/ (sử dụng chứa)

Cách tiếp cận này có lợi thế là thân thiện với màn hình Retina theo hướng dẫn nhanh của Thomas Fuchs.

Điều đáng nói là trình duyệt hỗ trợ cho cả hai thuộc tính loại trừ IE6-8.


1
Vì bạn có thể thay đổi kích thước hình ảnh hoàn toàn trong CSS, điều này cho phép bạn sử dụng một hình ảnh lớn và sau đó thu nhỏ hình ảnh theo mật độ pixel của từng thiết bị bằng cách sử dụng truy vấn phương tiện.
Marcelo De Polli

1
Bạn có thể giải thích tại sao trong trường hợp này, vị trí nền dường như chỉ ra vị trí trung tâm của hình ảnh chứ không phải là góc trên cùng bên trái? Đó có phải là hậu quả của kích thước nền: bìa?
matteo

1
Của tôi chỉ bao gồm toàn bộ DIV mở rộng hình ảnh. Tôi không thấy đường cong kết thúc.
SearchForKnowledge

3
Để làm gì background-repeat: no-repeat;? Nếu hình ảnh bao phủ nó, nó sẽ không lặp lại.
lurkit

3
'vị trí nền' cũng có thể được đặt thành 'trung tâm trung tâm'. ví dụ: .container {... nền-vị trí: trung tâm trung tâm; }
Leo Ribeiro

556

Bạn có thể sử dụng thuộc tính css object-fit.

.cover {
  object-fit: cover;
  width: 50px;
  height: 100px;
}
<img src="http://i.stack.imgur.com/2OrtT.jpg" class="cover" width="242" height="363" />

Xem ví dụ ở đây

Có một polyfill cho IE: https://github.com/anselmh/object-fit


11
Thật thú vị khi thấy rằng điều này cũng có thể được thực hiện với imgcác thẻ (không chỉ background-imagephương pháp như được mô tả trong câu trả lời ở trên). Cảm ơn bạn :)
Mahdi Ghiasi

44
Khi coi đây là một tùy chọn, hãy nhớ rằng object-fit không được hỗ trợ trong rất nhiều trình duyệt .
joshreesjones

2
Thật không may, background-sizehiếm khi là một giải pháp khả thi trong các dự án của tôi. Bạn ít có khả năng nhận được bất kỳ lợi ích SEO nào và không thể cung cấp thẻ ALT, chú thích, v.v. để đi kèm với hình ảnh mà bạn có thể muốn cung cấp ngữ cảnh bổ sung cho trình đọc màn hình.
Markus

3
Điều này thật tuyệt, nhưng không có hỗ trợ IE. Không có polyfill nào hoạt động nữa.
Jake

3
Chỉ cần sử dụng object-fit: cover;nó. Cảm ơn rất nhiều
Luka

67

Enhancement trên câu trả lời ở trên bởi @afonsoduarte ( KHÔNG một trong những được chấp nhận) .
trong trường hợp bạn đang sử dụng bootstrap


Có ba điểm khác biệt:

  1. Cung cấp width:100%về phong cách.
    Điều này rất hữu ích nếu bạn đang sử dụng bootstrap và muốn hình ảnh kéo dài tất cả chiều rộng có sẵn.

  2. Chỉ định thuộc heighttính là tùy chọn, Bạn có thể xóa / giữ nó khi bạn cần

    .cover {
       object-fit: cover;
       width: 100%;
       /*height: 300px;  optional, you can remove it, but in my case it was good */
    }
  3. Nhân tiện, KHÔNG cần phải cung cấp các thuộc tính heightwidththuộc tính trên imagephần tử bởi vì chúng sẽ bị ghi đè bởi kiểu.
    Vì vậy, nó là đủ để viết một cái gì đó như thế này.

    <img class="cover" src="url to img ..."  />

1
Chính xác những gì tôi đang tìm kiếm.
francis lanthier

1
Bạn cần một nụ hôn!
Tần Vương

đối tượng không phù hợp với IE?
bgcode

1
Đó là năm 2020, tôi nghĩ rằng đây là thời điểm tốt để từ bỏ IE
Hakan Fıstık

56

Cách thực sự duy nhất là có một thùng chứa xung quanh hình ảnh của bạn và sử dụng overflow:hidden:

HTML

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

CSS

.container {
    width: 300px;
    height: 200px;
    display: block;
    position: relative;
    overflow: hidden;
}

.container img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
}

CSS rất khó để làm những gì bạn muốn và căn giữa hình ảnh, có một cách khắc phục nhanh trong jquery như:

var conHeight = $(".container").height();
var imgHeight = $(".container img").height();
var gap = (imgHeight - conHeight) / 2;
$(".container img").css("margin-top", -gap);

http://jsfiddle.net/x86Q7/2/


1
Cảm ơn. Nó đã làm việc, nhưng nó cắt hình ảnh từ đầu . (xem phần này: jsfiddle.net/x86Q7 ) Không có cách nào để cắt ảnh từ trung tâm ?
Mahdi Ghiasi

1
@MahdiGhiasi: Thay đổi thuộc tính trên cùng và bên trái trong .container img css !!
Ali Ben Messaoud

Tôi có thể thiết lập margin-tophình ảnh bằng ví dụ 50px(xem điều này: jsfiddle.net/x86Q7/1 ), nhưng Làm thế nào để cắt nó từ trung tâm thực ? (Không có jQuery?)
Mahdi Ghiasi

2
Ahh xin lỗi đã không thấy bình luận của bạn nhưng tôi đã thêm jquery vừa mới xuất hiện :)
Dominic Green

1
Giải pháp tuyệt vời! Đối với tôi, điền dọc quan trọng hơn so với phương ngang, vì vậy tôi chỉ phải thay đổi "width: 100%" thành "height: 100%" cho lớp '.container img'. Cảm ơn bạn!
deebs

26

Giải pháp CSS không có JS và không có hình nền:

Phương pháp 1 "lề tự động" (IE8 + - KHÔNG FF!):

div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}
div img{
  position:absolute; 
  top:0; 
  bottom:0; 
  margin: auto;
  width:100%;
}
<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
  <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>

http://jsfiddle.net/5xjr05dt/

Phương pháp 2 "biến đổi" (IE9 +):

div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}

div img{
  position:absolute; 
  width:100%;
  top: 50%;
  -ms-transform: translateY(-50%);
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}
<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
  <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>

http://jsfiddle.net/5xjr05dt/1/

Phương pháp 2 có thể được sử dụng để căn giữa một hình ảnh trong một thùng chứa chiều rộng / chiều cao cố định. Cả hai đều có thể tràn - và nếu hình ảnh nhỏ hơn thùng chứa thì nó vẫn sẽ được căn giữa.

http://jsfiddle.net/5xjr05dt/3/

Phương pháp 3 "trình bao bọc kép" (IE8 + - KHÔNG FF!):

.outer{
  width:150px; 
  height:100px; 
  margin: 200px auto; /* just for example */
  border: 1px solid red; /* just for example */
  /* overflow: hidden;	*/ /* TURN THIS ON */
  position: relative;
}
.inner { 
    border: 1px solid green; /* just for example */
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto;
    display: table;
    left: 50%;
}
.inner img {
    display: block;
    border: 1px solid blue; /* just for example */
    position: relative;
    right: 50%;
    opacity: .5; /* just for example */
}
<div class="outer">
  <div class="inner">
     <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
  </div>
</div>

http://jsfiddle.net/5xjr05dt/5/

Phương pháp 4 "trình bao bọc kép và hình ảnh kép" (IE8 +):

.outer{
  width:150px; 
  height:100px; 
  margin: 200px auto; /* just for example */
  border: 1px solid red; /* just for example */
  /* overflow: hidden;	*/ /* TURN THIS ON */
  position: relative;
}
.inner { 
    border: 1px solid green; /* just for example */
    position: absolute;
    top: 50%;
    bottom: 0;
    display: table;
    left: 50%;
}
.inner .real_image {
    display: block;
    border: 1px solid blue; /* just for example */
    position: absolute;
    bottom: 50%;
    right: 50%;
    opacity: .5; /* just for example */
}

.inner .placeholder_image{
  opacity: 0.1; /* should be 0 */
}
<div class="outer">
  <div class="inner">
    <img class="real_image" src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
    <img class="placeholder_image"  src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
  </div>
</div>

http://jsfiddle.net/5xjr05dt/26/

  • Phương pháp 1 có hỗ trợ tốt hơn một chút - bạn phải đặt chiều rộng HOẶC chiều cao của hình ảnh!
  • Với tiền tố phương thức 2 cũng có hỗ trợ khá (từ eg9 trở lên) - Phương thức 2 không hỗ trợ trên Opera mini!
  • Phương pháp 3 sử dụng hai hàm bao - có thể tràn chiều rộng VÀ chiều cao.
  • Phương pháp 4 sử dụng một hình ảnh kép (một như giữ chỗ) điều này cung cấp thêm một số chi phí băng thông, nhưng thậm chí còn hỗ trợ lai tốt hơn.

Phương pháp 1 và 3 dường như không hoạt động với Firefox


Đây là cái duy nhất thực sự hoạt động (trừ các giải pháp js). Cảm ơn!
Jake

Nó được giới hạn để vượt quá chiều cao hoặc chiều rộng, nhưng là một giải pháp thú vị.
Jake

1
@Jake - Có thể vượt quá chiều rộng VÀ chiều cao với phương pháp 2 ở trên - xem câu trả lời được cập nhật của tôi với câu đố thêm.
JT Houtenbos

Vâng. Nó chắc chắn là một câu trả lời tuyệt vời. Tôi sẽ đánh lừa nó thêm một số. Đó là một chút kỳ quặc cho một hình ảnh rộng hơn cao hơn cần phải phản hồi, nhưng có rất nhiều ứng dụng cho việc này.
Jake

1
@Jake - Tuyệt vời - Tôi tìm thấy phương pháp thứ 3 để thực hiện định tâm ngang. Tôi mở rộng phương pháp này để hỗ trợ định tâm dọc. Tôi sẽ đăng bổ sung của tôi như là một phương pháp thứ 3 ở trên. Có vẻ như đó là bằng chứng IE7 + (thậm chí có thể thấp hơn). Đây là câu trả lời ban đầu: stackoverflow.com/questions/3300660/ trên
JT Houtenbos

10

Một giải pháp khác là đặt hình ảnh trong một thùng chứa với chiều rộng và chiều cao mong muốn. Sử dụng phương pháp này, bạn sẽ không phải đặt hình ảnh làm hình nền của một yếu tố.

Sau đó, bạn có thể làm điều này với một imgthẻ và chỉ cần đặt chiều rộng tối đa và chiều cao tối đa trên phần tử.

CSS:

.imgContainer {
    display: block;
    width: 150px; 
    height: 100px;
}

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

HTML:

<div class='imgContainer'>
    <img src='imagesrc.jpg' />
</div>

Bây giờ khi bạn thay đổi kích thước của container, hình ảnh sẽ tự động phát triển lớn nhất có thể mà không cần đi ra ngoài giới hạn hoặc bóp méo.

Nếu bạn muốn căn giữa hình ảnh theo chiều dọc và chiều ngang, bạn có thể thay đổi css container thành:

.imgContainer {
    display: table-cell;
    width: 150px; 
    height: 100px;
    text-align: center;
    vertical-align: middle;
}

Dưới đây là một Fiddle JS http://jsfiddle.net/9kUYC/2/


Nó không giống như bìa trong CSS, trong đó một trong các kích thước kết quả luôn vượt quá 100% (hoặc bằng nhau trong trường hợp cạnh)
Miroshko

Không, giải pháp này đảm bảo rằng nó không bao giờ kéo dài quá 100%, đó là phần của câu hỏi. Họ không muốn hình ảnh bị biến dạng hoặc phát triển vượt quá kích thước ban đầu.
Earl3s

3
Câu hỏi là "Làm thế nào để lấp đầy" với một ví dụ về hình ảnh đầy, rõ ràng là bị cắt.
Miroshko

Nhưng nếu bạn cần hình ảnh để được đáp ứng thì sao? Xác định chiều rộng và chiều cao cụ thể sẽ không hiệu quả
Ricardo Zea

2
Đó là những gì tôi cần. Cảm ơn!
Nico Rodsevich

5

Xây dựng câu trả lời của @Dominic Green bằng jQuery, đây là một giải pháp nên hoạt động đối với các hình ảnh rộng hơn cao hoặc cao hơn rộng.

http://jsfiddle.net/grZLR/4/

Có lẽ có một cách thanh lịch hơn để làm JavaScript, nhưng điều này không hoạt động.

function myTest() {
  var imgH = $("#my-img").height();
  var imgW = $("#my-img").width();
  if(imgW > imgH) {
    $(".container img").css("height", "100%");
    var conWidth = $(".container").width();
    var imgWidth = $(".container img").width();
    var gap = (imgWidth - conWidth)/2;
    $(".container img").css("margin-left", -gap);
  } else {
    $(".container img").css("width", "100%");
    var conHeight = $(".container").height();
    var imgHeight = $(".container img").height();
    var gap = (imgHeight - conHeight)/2;
    $(".container img").css("margin-top", -gap);
  }
}
myTest();

5
  • Không sử dụng nền css
  • Chỉ có 1 div để cắt nó
  • Thay đổi kích thước thành chiều rộng tối thiểu hơn giữ tỷ lệ khung hình chính xác
  • Cắt từ trung tâm (theo chiều dọc và chiều ngang, bạn có thể điều chỉnh điều đó với đỉnh, lef & biến đổi)

Hãy cẩn thận nếu bạn đang sử dụng một chủ đề hoặc một cái gì đó, họ sẽ thường khai báo img độ rộng tối đa ở mức 100%. Bạn phải làm cho không. Hãy thử đi :)

https://jsfiddle.net/o63u8sh4/

<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
    <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>


div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}
div img{
  min-width:100%;
  min-height:100%;
  height:auto;
  position:relative;
  top:50%;
  left:50%;
  transform:translateY(-50%) translateX(-50%);
}

Đây câu trả lời tôi đang tìm kiếm.
Marcos Buarque

Đây là những gì tôi muốn làm trong một thời gian dài, cảm ơn bạn;)
Boss COTIGA

4

Tôi đã giúp xây dựng một plugin jQuery có tên Fillmore , xử lý các background-size: covertrình duyệt hỗ trợ nó và có một phần mềm cho những người không sử dụng. Hãy nhìn xem!


4

Tôi nghĩ rằng nó khá muộn cho câu trả lời này. Dù sao, hy vọng điều này sẽ giúp ai đó trong tương lai. Tôi phải đối mặt với vấn đề định vị các thẻ trong góc. Có thẻ hiển thị cho các sự kiện. Nếu chiều rộng hình ảnh của sự kiện là lớn đối với thẻ, hình ảnh phải được hiển thị bằng cách cắt từ hai bên và chiều cao 100%. Nếu chiều cao hình ảnh dài, phần dưới cùng của hình ảnh bị cắt và chiều rộng là 100%. Đây là giải pháp css thuần túy của tôi cho việc này:

nhập mô tả hình ảnh ở đây

HTML:

 <span class="block clear img-card b-b b-light text-center" [ngStyle]="{'background-image' : 'url('+event.image+')'}"></span>

CSS

.img-card {
background-repeat: no-repeat;
background-size: cover;
background-position: 50% 50%;
width: 100%;
overflow: hidden;
}

Tôi không thể hiểu làm thế nào điều này hoạt động nhưng nó làm. Bạn cần định vị nhịp hoàn toàn trên cùng: 0; phải: 0; dưới cùng: 0; trái: 0 bên trong cha mẹ tương đối được định vị để đặt kích thước của nó.
Mike

Cảm ơn bạn đã phản hồi Mike thân mến, tôi rất vui nếu điều này hữu ích. Bạn có muốn tôi cập nhật câu trả lời với bình luận của bạn?
Nodirabegimxonoyim

3

Hãy thử một cái gì đó như thế này: http://jsfiddle.net/D7E3E/4/

Sử dụng một container có tràn: ẩn

EDIT: @Dominic Green đánh bại tôi.


Cảm ơn. Nó đã làm việc, nhưng nó cắt hình ảnh từ đầu . (xem phần này: jsfiddle.net/x86Q7 ) Không có cách nào để cắt ảnh từ trung tâm ?
Mahdi Ghiasi

Có thể khá khó khăn với CSS, đây là điều tốt nhất tôi có thể đến với jsfiddle.net/D7E3E/5
woutr_be

Có, để tập trung chính xác, bạn nên sử dụng jQuery, có thể dễ dàng hơn rất nhiều.
woutr_be

3

Điều này sẽ Điền hình ảnh đến một kích thước cụ thể, mà không kéo dài nó hoặc không cắt xén nó

img{
    width:150px;  //your requirement size
    height:100px; //your requirement size

/*Scale down will take the necessary specified space that is 150px x 100px without stretching the image*/
    object-fit:scale-down;
}

2

Để phù hợp với hình ảnh trong toàn màn hình, hãy thử điều này:

lặp lại nền: tròn;


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.