Làm thế nào để cắt xén hình ảnh hình chữ nhật thành hình vuông bằng CSS?


170

Tôi biết rằng thực sự không thể sửa đổi một hình ảnh bằng CSS, đó là lý do tại sao tôi đặt crop trong dấu ngoặc kép.

Những gì tôi muốn làm là chụp ảnh hình chữ nhật và sử dụng CSS để làm cho chúng trông vuông mà không làm biến dạng hình ảnh.

Về cơ bản tôi muốn bật cái này:

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

Vào đây:

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


4
Những hình ảnh này có phải là hình ảnh nền của div hay điều quan trọng đối với SEO là chúng vẫn nằm trong thẻ <img>?
Michael

2
Bạn đã thử gì chưa? Điều này khá đơn giản với CSS3 background-positionhoặc div trình bao bọc cũ overflow:hiddenvà hình ảnh có định vị tương đối.
Fabrício Matté

Chúng có thể là hình ảnh nền cho chắc chắn
novicePrgrmr

Xem câu trả lời của tôi, tôi nghĩ rằng đây là lựa chọn tốt nhất của bạn. Nó tránh các yếu tố định vị.
Michael

Câu trả lời:


78

Giả sử họ không phải ở trong thẻ IMG ...

HTML:

<div class="thumb1">
</div>

CSS:

.thumb1 { 
  background: url(blah.jpg) 50% 50% no-repeat; /* 50% 50% centers image in div */
  width: 250px;
  height: 250px;
}

.thumb1:hover { YOUR HOVER STYLES HERE }

EDIT: Nếu div cần liên kết ở đâu đó, chỉ cần điều chỉnh HTML và Kiểu như vậy:

HTML:

<div class="thumb1">
<a href="#">Link</a>
</div>

CSS:

.thumb1 { 
  background: url(blah.jpg) 50% 50% no-repeat; /* 50% 50% centers image in div */
  width: 250px;
  height: 250px;
}

.thumb1 a {
  display: block;
  width: 250px;
  height: 250px;
}

.thumb1 a:hover { YOUR HOVER STYLES HERE }

Lưu ý rằng điều này cũng có thể được sửa đổi để đáp ứng, ví dụ% chiều rộng và chiều cao, v.v.


1
đây là một cách hay để định vị VÀ cắt bằng một thẻ duy nhất.
rlemon

8
Cũng lưu ý rằng khi in, trình duyệt mast sẽ vô hiệu hóa hình nền để chúng không hiển thị.
j08691

Nó có thể xử lý: trạng thái di chuột cũng. Nếu div cần liên kết ở đâu đó chỉ cần thêm một thẻ. Đối với in, điều đó có thể được sửa với print.css? Chỉnh sửa nếu tôi sai?
Michael

Trên thực tế, thành thật mà nói, trong trường hợp này, với thẻ A, bản in sẽ bị thụt lùi và trong mọi trường hợp, bạn sẽ muốn thêm các kiểu CSS để sửa lỗi này cho dù sao đi nữa.
Michael

1
Không bao giờ, tôi đã thay đổi nó height: 460px; width: 100%;và nó hoạt động như một bùa mê
novicePrgrmr

417

Một giải pháp CSS thuần túy không có trình bao bọc divhoặc mã vô dụng khác:

img {
  object-fit: cover;
  width:230px;
  height:230px;
}

12
Lưu ý rằng điều này không may là không hoạt động trên IE và Edge atm. Xem tại đây để biết thêm chi tiết về điều đó: stackoverflow.com/a/37792830/1398056
baoutch

2
những gì chúng ta không biết chiều cao chúng ta muốn làm cho nó vuông với chiều rộng tự động
Aravind Reddy

3
Kể từ tháng 6 năm 2018, dường như chỉ IE11 (2,71%) không hỗ trợ phù hợp với đối tượng, đủ tốt cho tôi.
Ray

1
Năm 2019 hỗ trợ là khá tốt. Chỉ 2,3% vẫn đang sử dụng IE 11. Giải pháp này rất dễ dàng Tôi không thể không sử dụng nó vì những giải pháp khác là một nỗi đau mà tôi đã lãng phí hàng giờ để cố gắng làm cho nó hoạt động với mã phụ trợ.
Paul Morris

3
Đã đến lúc quên đi IE
iji

55
  1. Đặt hình ảnh của bạn trong một div.
  2. Cung cấp cho div kích thước vuông rõ ràng của bạn.
  3. Đặt thuộc tính tràn CSS trên div thành hidden ( overflow:hidden).
  4. Đặt trí tưởng tượng của bạn bên trong div.
  5. Lợi nhuận.

Ví dụ:

<div style="width:200px;height:200px;overflow:hidden">
    <img src="foo.png" />
</div>

5
Phải đảm bảo tập trung hoặc ít nhất là chơi với vị trí của hình ảnh bên trong. Mẫu OP trông có vẻ tập trung (mặc dù tôi chỉ đề cập đến điều này và không mong đợi bạn thay đổi câu trả lời của mình: P).
rlemon

1
@rlemon - sau đó OP có thể đặt vị trí của div thành tương đối và vị trí của hình ảnh thành tuyệt đối, và điều chỉnh các thuộc tính trên cùng và bên trái.
j08691

6
Tôi chỉ đề cập đến nó trước khi ai đó là tất cả; "Nhưng bây giờ tất cả đều được căn chỉnh!" -: P
rlemon

1
Vâng, điều quan trọng là nó là trung tâm
novicePrgrmr

32

Sử dụng kích thước nền: bìa - http://codepen.io/anon/pen/RNyKzB

CSS:

.image-container {
  background-image: url('http://i.stack.imgur.com/GA6bB.png');
  background-size:cover;
  background-repeat:no-repeat;
  width:250px;
  height:250px;
}  

Đánh dấu:

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

1
Kết hợp khả năng định tâm của câu trả lời của mtICS, nó hoạt động tốt, ngay cả trên IE9.
Faker

14

Tôi thực sự đã gặp phải vấn đề tương tự gần đây và kết thúc bằng một cách tiếp cận hơi khác (tôi không thể sử dụng hình nền). Mặc dù vậy, nó đòi hỏi một chút jQuery để xác định hướng của hình ảnh (tôi chắc chắn rằng bạn có thể sử dụng JS đơn giản thay thế).

Tôi đã viết một bài đăng trên blog về nó nếu bạn muốn giải thích thêm nhưng mã này khá đơn giản:

HTML:

<ul class="cropped-images">
  <li><img src="http://fredparke.com/sites/default/files/cat-portrait.jpg" /></li>
  <li><img src="http://fredparke.com/sites/default/files/cat-landscape.jpg" /></li>
</ul>

CSS:

li {
  width: 150px; // Or whatever you want.
  height: 150px; // Or whatever you want.
  overflow: hidden;
  margin: 10px;
  display: inline-block;
  vertical-align: top;
}
li img {
  max-width: 100%;
  height: auto;
  width: auto;
}
li img.landscape {
  max-width: none;
  max-height: 100%;
}

jQuery:

$( document ).ready(function() {

    $('.cropped-images img').each(function() {
      if ($(this).width() > $(this).height()) {
        $(this).addClass('landscape');        
      }
    });

});

Tôi nghĩ rằng điều này là tốt hơn so với thay thế nền CSS bởi vì hình ảnh là nội dung, không phải là "phong cách", vì vậy chúng nên được giữ trên lớp HTML. Ngoài ra, có chúng trên CSS thay vì HTML sẽ có ảnh hưởng đến SEO trang web của bạn. Cảm ơn!
Jose Florido

Một ý tưởng tốt để cải thiện điều này là thêm $(this).load(function(){...vào bên trong mỗi vòng lặp, vì vậy jQuery đợi một chút cho đến khi hình ảnh được tải và có kích thước hình ảnh thực.
Jose Florido

14

Nếu hình ảnh nằm trong một thùng chứa có chiều rộng đáp ứng :

HTML

<div class="img-container">
  <img src="" alt="">
</div>

CSS

.img-container {
  position: relative;

  &::after {
    content: "";
    display: block;
    padding-bottom: 100%;
  }

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

Điều này thực sự tốt đẹp. Nó cũng cực kỳ linh hoạt, vì một khi hình ảnh được bình phương, bạn có thể làm cho nó được khoanh tròn và làm những việc hay ho khác.
Rocky Kev

3

Tôi đã có một vấn đề tương tự và không thể "thỏa hiệp" với hình ảnh nền. Tôi nghĩ ra cái này

<div class="container">
    <img src="http://lorempixel.com/800x600/nature">
</div>

.container {
    position: relative;
    width: 25%; /* whatever width you want. I was implementing this in a 4 tile grid pattern. I used javascript to set height equal to width */
    border: 2px solid #fff; /* just to separate the images */
    overflow: hidden; /* "crop" the image */
    background: #000; /* incase the image is wider than tall/taller than wide */
}

.container img {
    position: absolute;
    display: block;
    height: 100%; /* all images at least fill the height */
    top: 50%; /* top, left, transform trick to vertically and horizontally center image */
    left: 50%;
    transform: translate3d(-50%,-50%,0);
}

//assuming you're using jQuery
var h = $('.container').outerWidth();
$('.container').css({height: h + 'px'});

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

Ví dụ: https://jsfiddle.net/cfbuwxmr/1/


2

Sử dụng CSS: tràn:

.thumb {
   width:230px;
   height:230px;
   overflow:hidden
}

3
Những kích thước đó không phải là rất vuông. :-)
isherwood

2
Không, bạn đúng. Tât nhiên. Tôi vừa mới nâng chiều cao hiện tại từ kích thước hình ảnh của OP, giống như một số robot bị cháy chiều thứ sáu.
Diodeus - James MacFarlane

Heh. Tôi với bạn ở đó. :-)
isherwood

1

Sử dụng div có kích thước vuông với hình ảnh bên trong với lớp .testimg:

.test {
width: 307px;
height: 307px;
overflow:hidden
}

.testimg {
    margin-left: -76px

}

hoặc một div vuông với nền của hình ảnh.

.test2 {
width: 307px;
height: 307px;
    background: url(http://i.stack.imgur.com/GA6bB.png) 50% 50%
}

Dưới đây là một số ví dụ: http://jsfiddle.net/QqCLC/1/

CẬP NHẬT NHƯ CÁC TRUNG TÂM HÌNH ẢNH

.test {
  width: 307px;
  height: 307px;
  overflow: hidden
}

.testimg {
  margin-left: -76px
}

.test2 {
  width: 307px;
  height: 307px;
  background: url(http://i.stack.imgur.com/GA6bB.png) 50% 50%
}
<div class="test"><img src="http://i.stack.imgur.com/GA6bB.png" width="460" height="307" class="testimg" /></div>

<div class="test2"></div>


0

object-fit: cover sẽ làm chính xác những gì bạn cần.

Nhưng nó có thể không hoạt động trên IE / Edge. Thực hiện theo như hình dưới đây để sửa nó chỉ bằng CSS để hoạt động trên tất cả các trình duyệt .

Cách tiếp cận tôi thực hiện là định vị hình ảnh bên trong thùng chứa một cách tuyệt đối và sau đó đặt nó ngay tại trung tâm bằng cách sử dụng kết hợp:

position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

Khi nó ở giữa, tôi đưa ra hình ảnh,

// For vertical blocks (i.e., where height is greater than width)
height: 100%;
width: auto;

// For Horizontal blocks (i.e., where width is greater than height)
height: auto;
width: 100%;

Điều này làm cho hình ảnh có được hiệu ứng của Object-fit: cover.


Dưới đây là một minh chứng về logic trên.

https://jsfiddle.net/furqan_694/s3xLe1gp/

Logic này hoạt động trong tất cả các trình duyệt.


Ảnh gốc
Ảnh gốc

Cắt theo chiều dọc
Hình ảnh được cắt theo chiều dọc

Cắt ngang
Hình ảnh cắt ngang


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.