Как «обрезать» прямоугольное изображение в квадрат с помощью CSS?

170

Я знаю, что на самом деле невозможно изменить изображение с помощью CSS, поэтому я помещаю кадрирование в кавычки.

То, что я хотел бы сделать, это взять прямоугольные изображения и использовать CSS, чтобы они выглядели квадратными, не искажая изображение вообще.

Я бы хотел включить это:

введите описание изображения здесь

В это:

введите описание изображения здесь

novicePrgrmr
источник
4
Являются ли эти изображения фоновыми изображениями div или для SEO важно, чтобы они оставались в тегах <img>?
Майкл
2
Вы уже пробовали что-нибудь? Это довольно просто с помощью CSS3 background-positionили старой оболочки div с overflow:hiddenизображением и относительным позиционированием.
Фабрисио Мате
Они могут быть фоновые изображения наверняка
novicePrgrmr
Смотрите мой ответ, я думаю, что это ваш лучший вариант. Избегает позиционирования элементов.
Майкл

Ответы:

78

Предполагая, что они не должны быть в тегах 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 }

РЕДАКТИРОВАТЬ: Если div нужно связать где-нибудь, просто настройте HTML и стили следующим образом:

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 }

Обратите внимание, что это также может быть изменено, чтобы быть отзывчивым, например,% ширина и высота и т. Д.

Майкл
источник
1
Это хороший способ позиционирования и обрезки с помощью одного тега.
rlemon
8
Также обратите внимание, что при печати мачтовые браузеры отключают фоновые изображения, чтобы они не отображались.
j08691
Он может обрабатывать: состояния при наведении. Если div нужно связать где-нибудь, просто добавьте тег. Что касается печати, это можно исправить с помощью print.css? Поправьте меня если я ошибаюсь?
Майкл
На самом деле, если честно, в этом случае с тегом A печать будет иметь откат, и в любом случае вы захотите добавить стили CSS, чтобы исправить это для печати в любом случае.
Майкл
1
Неважно, я изменил его, height: 460px; width: 100%;и он работает как шарм
novicePrgrmr
418

Чистое решение CSS без обертки divили другого бесполезного кода:

img {
  object-fit: cover;
  width:230px;
  height:230px;
}
Видение Улей
источник
12
Обратите внимание, что это, к сожалению, не работает в IE и Edge atm. Подробнее об этом см. Здесь: stackoverflow.com/a/37792830/1398056
baoutch
2
что мы не знаем высоту мы хотим сделать его квадрат с автоматической шириной
Аравинд Редди
3
По состоянию на июнь 2018 года, похоже, только IE11 (2,71%) не поддерживает подгонку объектов, что достаточно для меня.
Рэй
1
В 2019 году поддержка довольно хороша сейчас. Только 2,3% все еще используют IE 11. Это решение настолько простое, что я не могу не использовать его, потому что другие - такая боль, я потратил часы, пытаясь заставить его работать с внутренним кодом.
Пол Моррис
3
Пора всем забыть об IE
iji
55
  1. Поместите свое изображение в div.
  2. Дайте вашему div явные квадратные размеры.
  3. Установите свойство переполнения CSS в div на hidden ( overflow:hidden).
  4. Поместите свое воображение в div.
  5. Прибыль.

Например:

<div style="width:200px;height:200px;overflow:hidden">
    <img src="foo.png" />
</div>
j08691
источник
5
Необходимо обеспечить центрирование или, по крайней мере, играть с позиционированием изображения внутри. Образец OP выглядит по центру (хотя я только упоминаю об этом и не ожидаю, что вы вообще измените свой ответ: P).
rlemon
1
@rlemon - тогда OP может установить относительное положение div и положение изображения абсолютное, а также настроить атрибуты top и left.
j08691
6
Я просто упоминаю это, прежде чем кто-то все; "Но теперь все выровнено!" -: P
rlemon
1
Да, было бы важно, чтобы он был в центре
novicePrgrmr
32

Используя background-size: cover - 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;
}  

Разметка:

<div class="image-container"></div>
Филипп Нужный
источник
1
Сочетая центрирующую способность ответа mtronics, он хорошо работает даже на IE9.
Факер
14

Я на самом деле недавно столкнулся с этой же проблемой и в результате получил немного другой подход (я не мог использовать фоновые изображения). Однако для определения ориентации изображений требуется немного jQuery (я уверен, что вместо этого вы можете использовать обычный JS).

Я написал сообщение в блоге об этом, если вам интересно больше объяснений, но код довольно прост:

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
источник
Я думаю, что это лучше, чем фоновая альтернатива CSS, потому что изображения являются содержимым, а не «стилем», поэтому они должны храниться на слое HTML. Кроме того, наличие их на CSS вместо HTML повлияет на SEO вашей веб-страницы. Спасибо!
Хосе Флоридо
Хорошей идеей для улучшения этого является добавление $(this).load(function(){...внутри каждого цикла, поэтому jQuery немного ждет, пока изображение загрузится, и получит реальные размеры изображения.
Хосе Флоридо
14

Если изображение находится в контейнере с отзывчивым шириной:

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
источник
Это действительно мило. Он также невероятно гибкий, так как после того, как изображение возведено в квадрат, вы можете сделать его обведенным и делать другие интересные вещи.
Рокки Кев
3

У меня была похожая проблема, и я не мог «пойти на компромисс» с фоновыми изображениями. Я придумал это.

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

Надеюсь это поможет!

Пример: https://jsfiddle.net/cfbuwxmr/1/

Зак Боттерман
источник
2

Использовать CSS: переполнение:

.thumb {
   width:230px;
   height:230px;
   overflow:hidden
}
Диодей - Джеймс Макфарлейн
источник
3
Эти размеры не очень квадратные. :-)
Ишервуд
2
Нет, ты прав. Duh. Я просто поднимал существующую высоту с размера изображения ОП, как какой-то сгоревший в пятницу робот.
Диодей - Джеймс Макфарлейн
Хех. Я с тобой там. :-)
Ишервуд
1

Либо используйте div с квадратными размерами с изображением внутри с классом .testimg:

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

.testimg {
    margin-left: -76px

}

или квадратный div с фоном изображения.

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

Вот несколько примеров: http://jsfiddle.net/QqCLC/1/

ОБНОВЛЕНО ТАМ ИЗОБРАЖЕНИЯ

.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
источник
0

object-fit: cover будет делать именно то, что вам нужно.

Но это может не работать на IE / Edge. Выполните действия, показанные ниже, чтобы исправить это с помощью всего лишь CSS для работы во всех браузерах .

Подход, который я выбрал, состоял в том, чтобы расположить изображение внутри контейнера с абсолютным, а затем поместить его прямо в центр, используя комбинацию:

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

Как только он в центре, я даю изображение,

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

Это заставляет изображение получить эффект Object-fit: cover.


Вот демонстрация вышеуказанной логики.

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

Эта логика работает во всех браузерах.


Исходное изображение
Исходное изображение

Вертикально обрезанный
Вертикально обрезанное изображение

Горизонтально подрезанный
Горизонтально обрезанное изображение


Фуркан Рахамат
источник