Масштабировать изображение в несколько раз, если только оно не попадает в контейнер — только с помощью CSS?

#html #css

#HTML #css — код

Вопрос:

Предположим, у вас есть контейнер max-width размером 1000 пикселей и img может иметь ширину 1600 пикселей или 800 пикселей или что-то среднее. Цель состоит в том, чтобы, используя только HTML и CSS, всегда масштабировать изображение с фиксированным коэффициентом, скажем, 2, и иметь его такой ширины, пока оно не достигнет стенок контейнера. Итак, в этих примерах эти изображения будут иметь ширину 800 пикселей и 400 пикселей (и автоматическую высоту, которая сохраняет соотношение сторон), и оставлять пространство по бокам, пока размер контейнера не превысит 800 пикселей или 400 пикселей соответственно. (Цифры являются гипотетическими и для простоты демонстрации.) Дополнительная разметка внутри самого img элемента нежелательна по устаревшим причинам.

Попытки до сих пор:

  • Обходите zoom свойство. Недостатки: все еще не поддерживается Firefox.
  • Ближайшая альтернатива, transform: scale() , ведет себя по-другому и сохраняет исходные размеры в структуре документа (таким образом, высота контейнера не будет уменьшена).
  • Подключите Javascript или PHP, чтобы проверить размеры изображения и произвести вычисления. Недостатки: дополнительная разметка или вычисления там, где они могут не понадобиться.
  • По-видимому, невозможно получить хакерское решение с srcset помощью (также требуется дополнительная разметка).
  • Может быть, это можно было бы сделать с object-fit помощью и комбинаций контейнеров?

Возможно ли такое масштабирование изображения для достижения кроссбраузерности на данный момент только с помощью CSS, или обработка JS / PHP является единственным решением, если я полностью не изменю свой подход?

Ответ №1:

CSS grid может приблизить это, если вы знаете ширину. Измените размер экрана для проверки:

 .container {
  max-width:1000px;
  margin:20px auto;
  outline:2px solid;
  display:grid;
  justify-content: center;
  /* we set the step to be width/8
    for 1600px we get 200px
    our image will have a width equal to N*200px:
    [200px 400px 600px 800px 1000px]
  */
  grid-template-columns:repeat(auto-fit,calc(var(--w)/8))
}

.container img {
  grid-column:1/-1;
  max-width:100%;
} 
 <div class="container" style="--w:1600px">
  <img src="https://picsum.photos/id/1014/1600/600">
</div>

<div class="container" style="--w:1200px"> 
   <!-- here will have a 150px step (150px 300px 450px 600px 750px 900px) -->
  <img src="https://picsum.photos/id/1018/1200/600">
</div> 

Комментарии:

1. Поэтапное сокращение — интересный прием, который может иметь разное применение, но он выглядит неоптимальным для конкретной задачи. Это также по-прежнему требует предварительного знания ширины (чего я не хотел требовать, чтобы автоматически подгонять большую часть контента). Но это напомнило о более простом решении для подгонки контента с помощью flex, спасибо. (Я опубликую это сообщение отдельно.)

Ответ №2:

Следующее решение по-прежнему требует предварительного вычисления максимальной ширины (width * scale-factor) для внутреннего контейнера, например, с помощью PHP-скрипта и getimagesize() , но оно позволяет избежать изменения внутреннего содержимого самого внутреннего контейнера.

CSS — код:

 #outer_container {max-width: 1000px;}
#inner_container {display: flex; margin: 0 auto;}
#inner_container > img {width: 100%;}
 

HTML в случае 1:

 <div id="outer_container">
    <div id="inner_container" style="max-width: 800px;">
        <img src="image_which_is_1600px_wide.jpg">
    </div>
</div>
 

HTML в случае 2:

 <div id="outer_container">
    <div id="inner_container" style="max-width: 400px;">
        <img src="image_which_is_800px_wide.jpg">
    </div>
</div>
 

Одним из преимуществ этого подхода является то, что он может быть расширен для гибкого размещения различного внутреннего контента (не обязательно an img ) без его непосредственного изменения.