Javascript-форум (https://javascript.ru/forum/)
-   (X)HTML/CSS (https://javascript.ru/forum/xhtml-html-css/)
-   -   Запутался я с флексами... Помогите с версткой! (https://javascript.ru/forum/xhtml-html-css/83584-zaputalsya-ya-s-fleksami-pomogite-s-verstkojj.html)

voraa 17.01.2022 13:28

Запутался я с флексами... Помогите с версткой!
 
Есть контейнер определенного размера.
В нем может быть 1, 2 или 3 картинки произвольного размера, расположенные по вертикали.
Надо загнать их в контейнер так, что бы они не высовывались, ширина была по ширине контейнера, а высоты пропорционально изменялись.
Вот мучаюсь с флексами, но ничего не получается
<style>
.contv {
	margin: 40px 20px;
	border: 3px red solid;
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: space-around;
	height: 180px;
	width: 100px;
}
img {
	object-fit: contain;
	flex-shrink: 1;
}
</style>

<body>

<div class="contv">
	<img src='https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg'>
	<img src='https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-1-1-650x488.jpg'>
	<img src='https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-6-650x390.jpg'>
</div>

</body>

Aetae 17.01.2022 13:50

Т.е. высота должна пропорционально оригинальной сжиматься\растягиваться, а ширина всегда по ширине контейнера? Боюсь для произвольного размера изображения, не прописанного в коде заранее, так не сделать.

voraa 17.01.2022 13:58

Ну ширина может и меньше быть.
Главное по высоте пропорционально.
Там не известно, сколько их будет. Поэтому сразу в стилях не пропишешь высоту в 100%, 50% или 33%. Поэтому даже одинаковой высоты непросто сделать.
Верстку и флекс я не очень знаю, думал может кака то флексами можно заставить их по высоте сжиматься пропорционально.

Сергей Ракипов 21.01.2022 10:05

<style>
        .contv {
            margin: 40px 20px;
            border: 3px red solid;
            display: flex;
            flex-direction: column;
            justify-content: space-around;
            height: 180px;
            width: 100px;
        }
        img {
            object-fit: cover;
            height: 60px;
            width: 100%;
        }
</style>
    <div class="contv">
        <img src='https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg'>
        <img src='https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-1-1-650x488.jpg'>
        <img src='https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-6-650x390.jpg'>
    </div>


Если я правильно понял задачу то вот так должно работать?

рони 21.01.2022 10:22

Сергей Ракипов,
<style>...<style> добавьте

ksa 21.01.2022 15:15

Цитата:

Сообщение от Сергей Ракипов
вот так должно работать?

Если я правильно понял, ТСу нужн сохранить пропорциональную высоту картинок...
А в твоем варианте высота у них одинаковая.

voraa 21.01.2022 18:00

Ну похоже действительно нельзя там ничего выудить. Хотя странно. Если я туда вместо картинок загоняю дивы с известными размерами, то все нормально. А у картинок то тоже размер будет известен, когда она загрузится.
Фиг с ними. Выкрутился тем, что беру у них naturalHeight, суммирую, считаю пропорции и загоняю их в style.
Там правда столкнулся с другой необъяснимой штукой. Дело в том, что к моменту работы скрипта, картинки могут еще не успеть загрузится, поэтому код асинхронный. Для промиса загрузки картинки использовал .decode(). Получаю сообщение об ошибке, что картинка не может быть раскодирована! Причем сама картинка показывается!
Сделал маленький тестовый пример - все работает. Возвращаюсь в "боевой" вариант - ошибки.
Написал свой промис на onload - все работает нормально.

Malleys 03.02.2022 01:20

Цитата:

Сообщение от voraa
В нем может быть 1, 2 или 3 картинки произвольного размера, расположенные по вертикали.
Надо загнать их в контейнер так, что бы они не высовывались, ширина была по ширине контейнера, а высоты пропорционально изменялись.

Если в прямоугольник размером 180×100 попытаться вписать прямоугольник размером 800×100 так, чтобы их высоты совпадали, то «боковые части» так и так будут «высовываться» — придётся их обрезать.

Цитата:

Сообщение от Aetae
Боюсь для произвольного размера изображения, не прописанного в коде заранее, так не сделать.

В чём тогда смысл display: flex;? Или вам запрещено его использование?

Цитата:

Сообщение от voraa
Ну ширина может и меньше быть.
Главное по высоте пропорционально.

Растянуто пропорционально высоте картин (и как следствие какая-либо из картин может быть больше ширины контейнера, в данном случае вылезшие картины обрезаются, но зато сохраняются точные пропорций высот). Показано действие кода при разном кол-ве элементов.

<style>
body { display: flex; } /* только для примера */
.contv {
	margin: 40px 20px;
	border: 3px red solid;
	height: 180px;
	width: 100px;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	align-items: center;
	gap: 3px;
}
.contv > img {
	min-height: 0;
}
</style>
<div class="contv">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg">
</div>
<div class="contv">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-1-1-650x488.jpg">
</div>
<div class="contv">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-1-1-650x488.jpg">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-6-650x390.jpg">
</div>


Растянуто пропорционально высоте картин, которые были предварительно отмасштабированы до такого размера, чтобы влезать в контейнер. Пропорции высот картин не влезших в контейнер уменьшены во столько раз, во сколько раз больше картина оказалась больше контейнера. Картинки видны не полностью! Показано действие кода при разном кол-ве элементов.

<style>
body { display: flex; } /* только для примера */
.contv {
	margin: 40px 20px;
	border: 3px red solid;
	height: 180px;
	width: 100px;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	align-items: stretch;
	gap: 3px;
}
.contv > img {
	min-height: 0;
	object-fit: cover;
}
.contv > img:only-child {
	height: 100%;
}
</style>
<div class="contv">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg">
</div>
<div class="contv">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-1-1-650x488.jpg">
</div>
<div class="contv">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-1-1-650x488.jpg">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-6-650x390.jpg">
</div>



Цитата:

Сообщение от voraa
Там не известно, сколько их будет. Поэтому сразу в стилях не пропишешь высоту в 100%, 50% или 33%. Поэтому даже одинаковой высоты непросто сделать.

Равномерное распределение высот, в зависимости от кол-ва элементов.
<style>
body { display: flex; } /* только для примера */
.contv {
	margin: 40px 20px;
	border: 3px red solid;
	height: 180px;
	width: 100px;
	display: flex;
	flex-direction: column;
	gap: 3px;
}
.contv > img {
	min-height: 0;
	flex: 0 1 100%;
	object-fit: cover;
}
</style>
<div class="contv">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg">
</div>
<div class="contv">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-1-1-650x488.jpg">
</div>
<div class="contv">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-1-1-650x488.jpg">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-6-650x390.jpg">
</div>


Можно также сразу в стилях прописать высоту в 100%, 50% или 33%... (Не рекомендуется — больше элементов требует больше CSS-кода)
<style>
body { display: flex; } /* только для примера */
.contv {
	margin: 40px 20px;
	border: 3px red solid;
	height: 180px;
	width: 100px;
	display: block;
}
.contv > img {
	max-width: 100%;
	margin: auto;
	display: block;
	object-fit: cover;
}
.contv > img:only-child {
	height: 100%;
}
.contv > img:nth-last-child(2):first-child,
.contv > img:nth-last-child(2):first-child + * {
	height: 50%;
}
.contv > img:nth-last-child(3):first-child,
.contv > img:nth-last-child(3):first-child + * {
	height: 33.3333%;
}
</style>
<div class="contv">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg">
</div>
<div class="contv">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-1-1-650x488.jpg">
</div>
<div class="contv">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-1-1-650x488.jpg">
	<img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-6-650x390.jpg">
</div>

MallSerg 03.02.2022 02:38

Думаю кирпичную кладку на css он переизобретает ну т.е. используемое в ней выравнивание изображений под размеры сетки.

https://www.google.com/search?q=css+...ome &ie=UTF-8

voraa 03.02.2022 09:10

Спасибо, но не совсем то.
Цель можно было примерно описать так -
Приводим все картинки к какой то одной ширине (например ширина контейнера.) Но высоты у них будут разные. Делим контейнер на прямоугольники, пропорционально высотам картинок. В прямоугольник вписываем картинку (object-fit: contain)
Хотелось сделать это просто на CSS, без JS.
CJS результат такой
<style>
body { display: flex; } /* только для примера */
.contv {
    margin: 40px 20px;
    border: 3px red solid;
    height: 200px;
    width: 130px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    align-items: stretch;
    gap: 3px;
}
.contv > img {
    min-height: 0;
    object-fit: contain;
}
.contv > img:only-child {
    height: 100%;
}

</style>
<body>
<div class="contv">
    <img src="https://feedlife.com.ua/images/site-feedlife/news/kormlenie-krolej-min.jpg">
</div>
<div class="contv">
    <img src="https://feedlife.com.ua/images/site-feedlife/news/kormlenie-krolej-min.jpg">
    <img src="https://monolith1.izrukvruki.ru/img/catalog/i2/8a/e0/130ea9388-1050x1050-774160528-orig.jpg">
</div>
<div class="contv">
    <img src="https://feedlife.com.ua/images/site-feedlife/news/kormlenie-krolej-min.jpg">
    <img src="https://monolith1.izrukvruki.ru/img/catalog/i2/8a/e0/130ea9388-1050x1050-774160528-orig.jpg">
    <img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg">
</div>
<div class="contv">
    <img src="https://feedlife.com.ua/images/site-feedlife/news/kormlenie-krolej-min.jpg">
    <img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg">
</div>
<div class="contv">
    <img src="https://monolith1.izrukvruki.ru/img/catalog/i2/8a/e0/130ea9388-1050x1050-774160528-orig.jpg">
    <img src="https://proprikol.ru/wp-content/uploads/2019/10/kroliki-krasivye-kartinki-2.jpg">
</div>

<script>
window.addEventListener("load", () => {
	document.querySelectorAll('.contv').forEach( cont => {
		const imgs = [... cont.querySelectorAll('img')];
		const hsum = imgs.reduce((h, im) => h + im.naturalHeight, 0);
		imgs.forEach (im => im.style.height = im.naturalHeight/hsum*100 + '%');
	})
})

</script>
<body>


Часовой пояс GMT +3, время: 10:25.