#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
) без его непосредственного изменения.