Jak „przyciąć” prostokątny obrazek do kwadratu za pomocą CSS?

170

Wiem, że nie da się tak naprawdę zmodyfikować obrazu za pomocą CSS, dlatego umieszczam kadr w cudzysłowie.

Chciałbym zrobić prostokątne obrazy i użyć CSS, aby wyglądały na kwadratowe bez zniekształcania obrazu.

Zasadniczo chciałbym to zmienić:

wprowadź opis obrazu tutaj

Zaangażowany w to:

wprowadź opis obrazu tutaj

nowicjuszPrgrmr
źródło
4
Czy te obrazy są obrazami tła elementów div, czy dla SEO ważne jest, aby pozostały w tagach <img>?
Michael
2
Czy próbowałeś już czegoś? Jest to raczej proste w przypadku CSS3 background-positionlub starego wrappera div z overflow:hiddenobrazem i pozycjonowaniem względnym.
Fabrício Matté
Na pewno mogą to być obrazy tła
nowicjuszPrgrmr
Zobacz moją odpowiedź, myślę, że to ogólnie najlepsza opcja. Pozwala uniknąć pozycjonowania elementów.
Michael

Odpowiedzi:

78

Zakładając, że nie muszą znajdować się w tagach 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 }

EDYTUJ: Jeśli div musi gdzieś linkować, dostosuj HTML i style w następujący sposób:

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 }

Zauważ, że można to również zmodyfikować, aby było responsywne, na przykład% szerokości i wysokości itp.

Michael
źródło
1
to dobry sposób na pozycjonowanie ORAZ kadrowanie za pomocą jednego tagu.
rlemon
8
Zauważ też, że podczas drukowania główne przeglądarki wyłączają obrazy tła, aby się nie pojawiały.
j08691
Obsługuje również: stany po najechaniu. Jeśli div musi gdzieś linkować, po prostu dodaj tag. Jeśli chodzi o druk, to można to naprawić za pomocą print.css? Popraw mnie, jeśli się mylę?
Michael
Właściwie, szczerze mówiąc, w tym przypadku ze znacznikiem A wydruk miałby się cofnąć, a w każdym razie chciałbyś dodać style CSS, aby i tak naprawić to dla drukowania.
Michael
1
Nieważne, zmieniłem to height: 460px; width: 100%;i działa jak urok
nowicjuszPrgrmr
417

Czyste rozwiązanie CSS bez wrappera divi innego bezużytecznego kodu:

img {
  object-fit: cover;
  width:230px;
  height:230px;
}
Vision Hive
źródło
12
Zauważ, że to niestety nie działa w IE i Edge ATM. Więcej informacji na ten temat można znaleźć tutaj: stackoverflow.com/a/37792830/1398056
baoutch
2
co to jest, nie znamy wysokości, którą chcemy, aby była kwadratowa z automatyczną szerokością
Aravind Reddy,
3
Od czerwca 2018 wydaje się, że tylko IE11 (2,71%) nie obsługuje dopasowania obiektów, co jest dla mnie wystarczająco dobre.
Ray
1
W 2019 wsparcie jest teraz całkiem dobre. Tylko 2,3% nadal używa IE 11. To rozwiązanie jest tak proste, że nie mogę się powstrzymać od jego używania, ponieważ inne są tak uciążliwe, że zmarnowałem godziny, próbując zmusić je do pracy z kodem zaplecza.
Paul Morris
3
Pora
55
  1. Umieść swój obraz w div.
  2. Podaj kwadratowe wymiary elementu div.
  3. Ustaw właściwość przepełnienia CSS elementu div na hidden ( overflow:hidden).
  4. Umieść swoją wyobraźnię w div.
  5. Zysk.

Na przykład:

<div style="width:200px;height:200px;overflow:hidden">
    <img src="foo.png" />
</div>
j08691
źródło
5
Musi zapewnić wyśrodkowanie lub przynajmniej zabawę z pozycjonowaniem obrazu w środku. Próbka OP wygląda na wyśrodkowaną (chociaż tylko o tym wspominam i nie oczekuję, że w ogóle zmienisz odpowiedź: P).
rlemon
1
@rlemon - wtedy OP mógłby ustawić położenie elementu div na względne, a położenie obrazu na bezwzględne i dostosować atrybuty górny i lewy.
j08691
6
Wspominam o tym, zanim ktoś jest wszystkim; „Ale teraz wszystko jest wyrównane do lewej!” -: P
rlemon
1
Tak, byłoby kluczowe, aby był wyśrodkowany
nowicjusz Prgrmr
32

Korzystanie z rozmiaru tła: okładka - 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;
}  

Narzut:

<div class="image-container"></div>
Philip Nuzhnyy
źródło
1
Łącząc zdolność centrowania odpowiedzi mtronics, działa dobrze, nawet na IE9.
Faker
14

Właściwie ostatnio natknąłem się na ten sam problem i skończyłem z nieco innym podejściem (nie mogłem użyć obrazów tła). Wymaga to jednak odrobiny jQuery, aby określić orientację obrazów (jestem pewien, że zamiast tego można użyć zwykłego JS).

Napisałem o tym post na blogu, jeśli interesuje cię więcej wyjaśnień, ale kod jest dość prosty:

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

});
FreddyBushBoy
źródło
Myślę, że jest to lepsze od alternatywnego tła CSS, ponieważ obrazy są treścią, a nie „stylem”, więc powinny być przechowywane w warstwie HTML. Również umieszczenie ich w CSS zamiast w HTML wpłynie na SEO Twojej strony. Dzięki!
Jose Florido
Dobrym pomysłem, aby to poprawić, jest dodanie $(this).load(function(){...wewnątrz każdej pętli, więc jQuery czeka trochę, aż obraz zostanie załadowany i uzyska rzeczywiste wymiary obrazu.
Jose Florido
14

Jeśli obraz znajduje się w kontenerze o elastycznej szerokości:

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;
  }
}
JKL
źródło
To jest naprawdę miłe. Jest też niesamowicie elastyczny, ponieważ po podniesieniu obrazu do kwadratu możesz go zakreślić i robić inne fajne rzeczy.
Rocky Kev
3

Miałem podobny problem i nie mogłem „pójść na kompromis” z obrazami tła. Wymyśliłem to.

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

Mam nadzieję że to pomoże!

Przykład: https://jsfiddle.net/cfbuwxmr/1/

Zach Botterman
źródło
2

Użyj CSS: przepełnienie:

.thumb {
   width:230px;
   height:230px;
   overflow:hidden
}
Diodeus - James MacFarlane
źródło
3
Te wymiary nie są bardzo kwadratowe. :-)
isherwood
2
Nie, masz rację. Duh. Właśnie podnosiłem istniejącą wysokość z rozmiaru obrazu OP, jak jakiś wypalony robot w piątkowe popołudnie.
Diodeus - James MacFarlane
Heh. Jestem tam z tobą. :-)
isherwood
1

Użyj elementu div o kwadratowych wymiarach z obrazem w środku z klasą .testimg:

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

.testimg {
    margin-left: -76px

}

lub kwadratowy element DIV z tłem obrazu.

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

Oto kilka przykładów: http://jsfiddle.net/QqCLC/1/

ZAKTUALIZOWANO CENTRUM OBRAZU

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

tech292
źródło
0

object-fit: cover zrobi dokładnie to, czego potrzebujesz.

Ale może nie działać w IE / Edge. Postępuj zgodnie z poniższymi instrukcjami, aby naprawić to za pomocą CSS, który działa we wszystkich przeglądarkach .

Podejście, które zastosowałem, polegało na umieszczeniu obrazu w pojemniku za pomocą wartości absolutnej, a następnie umieszczeniu go dokładnie w środku, używając kombinacji:

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

Gdy jest w centrum, daję obrazowi,

// 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%;

Dzięki temu obraz uzyskuje efekt Dopasowanie obiektu: okładka.


Oto demonstracja powyższej logiki.

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

Ta logika działa we wszystkich przeglądarkach.


Oryginalny obraz
Oryginalny obraz

Przycięte pionowo
Obraz przycięty w pionie

Przycięte w poziomie
Obraz przycięty w poziomie


Furqan Rahamath
źródło