CSS3 Flexbox поддерживает соотношение сторон изображения
С помощью гибкой блочной модели CSS, как заставить изображение сохранить его пропорции?
JS Fiddle http://jsfiddle.net/xLc2Le0k/2/
Обратите внимание, что изображения растягиваются или сжимаются, чтобы заполнить ширину контейнера. Это нормально, но можем ли мы также растянуть или уменьшить высоту, чтобы сохранить пропорции изображения?
HTML
<div class="slider">
<img src="http://www.placebacon.net/400/300" alt="Bacn">
<img src="http://www.placebacon.net/400/300" alt="Bacn">
<img src="http://www.placebacon.net/400/300" alt="Bacn">
<img src="http://www.placebacon.net/400/300" alt="Bacn">
</div>
CSS
.slider {
display: flex;
}
.slider img {
margin: 0 5px;
}
9 ответов
Для тегов img, если вы определяете одну сторону, размер другой стороны изменяется, чтобы сохранить соотношение сторон, и по умолчанию изображения расширяются до своего исходного размера.
Используя этот факт, если вы поместите каждый тег img в тег div и установите его ширину равной 100% родительского тега div, высота будет соответствовать желаемому соотношению сторон.
http://jsfiddle.net/xLc2Le0k/15/
* {
margin: 0;
padding: 0;
}
.slider {
display: flex;
}
.slider .slide img {
width: 100%;
}
Чтобы предотвратить растягивание изображений по любой оси внутри гибкого родителя, я нашел несколько решений.
Вы можете попробовать использовать объектную посадку на изображении, которая, например,
object-fit: contain;
Или вы можете добавить гибкие специальные правила, которые в некоторых случаях могут работать лучше.
align-self: center;
flex: 0 0 auto;
Не нужно добавлять содержащий div.
По умолчанию для свойства css "align-items" установлено значение "stretch", из-за которого ваши изображения растягиваются до полной первоначальной высоты. Установка свойства css "align-items" в значение "flex-start" решает вашу проблему.
.slider {
display: flex;
align-items: flex-start; /* ADD THIS! */
}
Большинство изображений с собственными размерами, то есть натурального размера, как
jpeg
образ. Если указанный размер определяет как ширину, так и высоту, пропущенное значение определяется с использованием внутреннего отношения... - см. MDN.
Но это работает не так, как ожидалось, если изображения, которые задаются как прямые изгибаемые элементы с текущим модулем раскладки гибких блоков уровня 1, насколько я знаю.
Смотрите эти обсуждения и сообщения об ошибках могут быть связаны:
- Flexbugs # 14 - Внутренние размеры Chrome/Flexbox не реализованы правильно.
- Firefox Bug 972595 - Flex-контейнеры должны использовать "flex- based " вместо "width" для вычисления собственной ширины flex-элементов
- Chromium Issue 249112 - В Flexbox разрешите собственные пропорции для расчета расчета основного размера.
В качестве обходного пути вы можете обернуть каждый <img>
с <div>
или <span>
, или так.
.slider {
display: flex;
}
.slider>div {
min-width: 0; /* why? see below. */
}
.slider>div>img {
max-width: 100%;
height: auto;
}
<div class="slider">
<div><img src="https://picsum.photos/400/300?image=0" /></div>
<div><img src="https://picsum.photos/400/300?image=1" /></div>
<div><img src="https://picsum.photos/400/300?image=2" /></div>
<div><img src="https://picsum.photos/400/300?image=3" /></div>
</div>
4.5 Предполагаемый минимальный размер гибких элементов
Чтобы обеспечить более разумный минимальный размер по умолчанию для гибких элементов, эта спецификация вводит новое автоматическое значение в качестве начального значения свойств min-width и min-height, определенных в CSS 2.1.
Кроме того, вы можете использовать CSS table
вместо макета, который вы получите аналогичные результаты, как flexbox
, он будет работать на большем количестве браузеров, даже для IE8.
.slider {
display: table;
width: 100%;
table-layout: fixed;
border-collapse: collapse;
}
.slider>div {
display: table-cell;
vertical-align: top;
}
.slider>div>img {
max-width: 100%;
height: auto;
}
<div class="slider">
<div><img src="https://picsum.photos/400/300?image=0" /></div>
<div><img src="https://picsum.photos/400/300?image=1" /></div>
<div><img src="https://picsum.photos/400/300?image=2" /></div>
<div><img src="https://picsum.photos/400/300?image=3" /></div>
</div>
В последнее время я играл в flexbox, и я нашел решение для этого путем экспериментов и следующих рассуждений. Однако на самом деле я не уверен, что именно так и происходит.
Если реальная ширина зависит от гибкой системы. Поэтому после того, как ширина элементов достигает максимальной ширины родительского элемента, дополнительная ширина, заданная в css, игнорируется. Тогда можно безопасно установить ширину на 100%.
Так как высота тега img является производной от самого изображения, то установка высоты в 0% может что-то сделать. (это то, где мне неясно, что... но для меня имело смысл это исправить)
DEMO
(помните, сначала увидел это здесь!)
.slider {
display: flex;
}
.slider img {
height: 0%;
width: 100%;
margin: 0 5px;
}
Пока работает только в хроме
This behavior is expected. flex container will stretch all its children by default. Image have no exception. (ie, parent will have align-items: stretch
property)
To keep the aspect ratio we've two solutions:
- Either replace default
align-items: stretch
property toalign-items: flex-start
oralign-self: center
etc,http://jsfiddle.net/e394Lqnt/3/
or
- Set align property exclusively to the child itself: like,
align-self: center
oralign-self: flex-start
etc.http://jsfiddle.net/e394Lqnt/2/
Объявите, где
display: flex;
был дан Элемент.
align-items: center;
На самом деле я обнаружил, что контейнер тега изображения должен иметь высоту, чтобы сохранить соотношение изображения. например>
.container{display:flex; height:100%;} img{width:100%;height:auto;}
тогда в вашем HTML ваш контейнер обернет изображение тега
<div class="container"><img src="image.jpg" alt="image" /></div>
эта работа для IE и других браузеров
У меня просто была такая же проблема. Используйте гибкое выравнивание, чтобы центрировать ваши элементы. Вам нужно использовать align-items: center
вместо align-content: center
, Это будет поддерживать соотношение сторон, в то время как align-content не будет сохранять соотношение сторон.