Масштабирование высоты divs на чистом CSS

Мне нужно масштабировать высоту div.

Как это должно работать

  • Дивы должны масштабироваться, сохранять текущее соотношение сторон
  • Ширина всегда должна быть 100 пикселей.
  • Высота должна масштабироваться пропорционально ширине 100 пикселей.
  • Я добавил в код пример ширины и высоты
  • При необходимости добавьте еще HTML + CSS

Пример

Размер блока div изначально составляет 300 x 600 пикселей. При ширине 100 пикселей он будет 100 x 200 пикселей.

Результат

В результате получатся блоки одинаковой ширины, но разной высоты, некоторые из которых выше, чем другие.

https://jsfiddle.net/80pk066L/5/

Примечания

Если это будет изображение, оно будет содержать соотношение сторон при установке ширины на 100%, но это не изображение. Это div.

HTML

<ul>
    <li class="scale1"><div></div></li>
    <li class="scale2"><div></div></li>
    <li class="scale3"><div></div></li>
    <li class="scale4"><div></div></li>
    <li class="scale5"><div></div></li>
</ul>

CSS

ul {
    width: 300px;
}

li {
    float: left;
    background: red;
    margin: 10px;
    list-style: none;
    display: block;
    height: 100px;
    width: 100px;
    /*REMOVE HEIGHT AND WIDTH HERE, JUST DECORATION
    Width should always be 100px
    Height should be whatever, can be larger than 100px
    */
}

.scale1 div {
    width: 300px;
    height: 500px;
}

.scale2 div {
    width: 400px;
    height: 400px;
}

.scale3 div {
    width: 200px;
    height: 300px;
}

.scale4 div {
    width: 50px;
    height: 60px;
}

.scale5 div {
    width: 150px;
    height: 75px;
}

person Jens Törnell    schedule 28.04.2015    source источник
comment
Каждый li образует квадрат 100 пикселей и имеет дочерний div с определенным соотношением сторон, и вы хотите, чтобы дочерний div вписался в li?   -  person Marc Audet    schedule 28.04.2015
comment
Во-первых, вы должны удалить div в определениях шкалы - это подразумевается точкой. Я не уверен, что вы имеете в виду под масштабом ... если вам нужна высота 200 и ширина 100, почему бы не установить это?   -  person steve klein    schedule 28.04.2015
comment
@MarcAudet Нет, мне, наверное, стоит отредактировать свой вопрос. Div может иметь размер 100x200, 100x40, но НИКОГДА не используйте 200x100 или 300x500. Ширина всегда должна быть 100 пикселей. Рост может быть любым.   -  person Jens Törnell    schedule 28.04.2015
comment
Поэтому просто не устанавливайте ширину для ваших div-ов и высоту для элементов списка.   -  person Shaggy    schedule 28.04.2015
comment
тогда удаление высоты из li даст вам желаемый результат, верно?   -  person Aru    schedule 28.04.2015
comment
@steveklein div является дочерним элементом .scale1, а не тем же элементом. Секунда. Мои размеры генерируются как блоки, блоки больше 100 пикселей. Их нужно масштабировать, чтобы они соответствовали размеру. Высота должна иметь правильное соотношение сторон. Позже я тоже сделаю его отзывчивым. В то время им нужно снова масштабироваться.   -  person Jens Törnell    schedule 28.04.2015
comment
@shaggy Блок div размером 300 x 600 пикселей будет уменьшен до 100 x 200 пикселей. Поэтому я не могу просто удалить что-то. Если бы у меня было изображение, оно сохраняло бы соотношение сторон, но это div.   -  person Jens Törnell    schedule 28.04.2015
comment
@Aru Посмотри на мой ответ лохматому, тогда ты увидишь, что я не могу этого сделать.   -  person Jens Törnell    schedule 28.04.2015
comment
Думаю, я вас знаю и опубликовал ответ ниже.   -  person Shaggy    schedule 28.04.2015
comment
если div будут иметь произвольные размеры, это невозможно сделать с помощью простого css (вам нужно как-то вычислить их соотношение). Если их размеры взяты из определенного списка (предопределенные соотношения), то вы можете использовать уловку соотношения (с padding) и установить их ширину на 100% от контейнера.   -  person Gabriele Petrioli    schedule 28.04.2015


Ответы (3)


Вы можете использовать трюк с нижним отступом, чтобы обеспечить адаптивное соотношение сторон для каждого отдельного элемента. Вам нужно будет вручную рассчитать padding-bottom для каждого элемента в процентах от отношения высоты к ширине.

.scale1 div {
    padding-bottom: 166.667%;
}

.scale2 div {
    padding-bottom: 100%;
}

.scale3 div {
    padding-bottom: 150%;
}

.scale4 div {
    padding-bottom: 120%;
}

.scale5 div {
    padding-bottom: 50%;
}

См. Скрипку здесь: https://jsfiddle.net/teddyrised/80pk066L/9/

Однако, если вы хотите, чтобы содержимое каждого элемента было заключено в абсолютно позиционированный дочерний элемент - это потому, что, если они не будут удалены из потока документов, высота содержимого будет добавлена ​​к нижнему отступу, что приведет к искажению соотношение сторон:

li div {
    position: relative;
}
li div span {
    position: absolute;
    padding: 10px;
    top: 0; 
    left: 0;
    bottom: 0;
    right: 0;
}

https://jsfiddle.net/teddyrised/80pk066L/10/

Если использование CSS для задания соотношения сторон слишком утомительно, вы можете сделать это программно с помощью JS. Я понимаю, что вы, возможно, не захотите достичь этого с помощью JS, но это может быть более эффективным, если у вас есть большое количество элементов, которые вы хотите пройти. Для удобства я использую jQuery, но любые другие библиотеки или даже необработанный JS будут работать, если применяется та же логика:

$(function() {
    $('ul li').each(function() {
        $(this).children('div').css('padding-bottom', $(this).width()/parseFloat($(this).data('aspect-ratio')));
    });
});

Я решил сохранить соотношение сторон (в форме ширины к высоте) в атрибуте HTML5 data-:

<ul>
    <li class="scale1" data-aspect-ratio="0.6"><div><span>1</span></div></li>
    <li class="scale2" data-aspect-ratio="1"><div><span>2</span></div></li>
    <li class="scale3" data-aspect-ratio="0.667"><div><span>3</span></div></li>
    <li class="scale4" data-aspect-ratio="0.833"><div><span>4</span></div></li>
    <li class="scale5" data-aspect-ratio="2"><div><span>5</span></div></li>
</ul>

См. Пример проверки концепции здесь: https://jsfiddle.net/teddyrised/80pk066L/11/ < / а>

person Terry    schedule 28.04.2015
comment
Вроде бы правильный ответ. Дополнительный плюс для JS-штуки. Отлично! - person Jens Törnell; 28.04.2015

Вместо того, чтобы указывать точную ширину и высоту для разделов, используйте комбинацию max-width и padding-bottom для достижения этой цели. Я также взял на себя смелость преобразовать ваш макет с использования float на использование flexbox, чтобы избавиться от хлопот, связанных с очисткой float.

*{box-sizing:border-box;}
ul{
    display:flex;
    flex-flow:row wrap;
    list-style:none;
    margin:0;
    padding:0;
    width:100%;
}
li{
    background:green;
	flex:1 1 calc(33.333% - 20px);
    margin:10px;
    display:block;
    max-width:calc(33.333% - 20px);
}
div{
    background:red;
}
.scale1 div{
    padding:0 0 166.667%;
    max-width:300px;
}

.scale2 div{
    padding:0 0 100%;
    max-width:400px;
}

.scale3 div{
    padding:0 0 150%;
    max-width:200px;
}
.scale4 div{
    padding:0 0 120%;
    max-width:50px;
}
.scale5 div{
    padding:0 0 50%;
    max-width:150px;
}
<ul>
    <li class="scale1"><div></div></li>
    <li class="scale2"><div></div></li>
    <li class="scale3"><div></div></li>
    <li class="scale4"><div></div></li>
    <li class="scale5"><div></div></li>
</ul>

person Shaggy    schedule 28.04.2015
comment
Похоже, все работает как положено. Flexbox может быть как красивым, так и не очень. Проголосуйте пока! - person Jens Törnell; 28.04.2015

Вы можете добиться этого, используя заполнители изображений: (скрипка, если фрагмент кода не работает)

ul {
    width: 300px;
}
li {
    float: left;
    background: red;
    margin: 10px;
    list-style: none;
    display: block;
    position:relative;
    width:100px;
}
li img {
    position: relative;
    visibility: hidden; /* make sure it's hidden */
    width: 100%;
    min-width: 100%;
}
li div {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    overflow:hidden;
}
/*.scale1 div {
    width: 300px;
    height: 500px;
}
.scale2 div {
    width: 400px;
    height: 400px;
}
.scale3 div {
    width: 200px;
    height: 300px;
}
.scale4 div {
    width: 50px;
    height: 60px;
}
.scale5 div {
    width: 150px;
    height: 75px;
}*/
<ul>
    <li class="scale1">
        <div></div>
        <img src="http://placehold.it/300x500" alt="" />
    </li>
    <li class="scale2">
        <div></div>
        <img src="http://placehold.it/400x400" alt="" />
    </li>
    <li class="scale3">
        <div></div>
        <img src="http://placehold.it/200x300" alt="" />
    </li>
    <li class="scale4">
        <div></div>
        <img src="http://placehold.it/50x60" alt="" />
    </li>
    <li class="scale5">
        <div></div>
        <img src="http://placehold.it/150x75" alt="" />
    </li>
</ul>
<!-- - The divs should scale - The width of the div should be max 100px - The height should scale to what fit max 100px width - Remove li height and width. They are just for decoration -->

person Jamie Barker    schedule 28.04.2015
comment
Вы, кажется, первый правильно поняли мой вопрос. Поздравляю! Однако в первую очередь я хотел избавиться от изображений. Я должен добавить это к своему вопросу. Размещение таких пустых изображений означает их показ для поисковых систем, а не для людей. В худшем случае это может быть прикрытие наказания со стороны Google. Кроме того, это умный ответ. - person Jens Törnell; 28.04.2015
comment
@ JensTörnell Я предполагаю, что единственная информация, которая у вас есть в начале, - это высота и ширина? - person Jamie Barker; 28.04.2015
comment
Да, у меня есть изображения, в которых я извлекаю ширину и высоту, которые устанавливаю в div. - person Jens Törnell; 28.04.2015
comment
@ JensTörnell Тогда я бы посоветовал лучше ответить Терри :) - person Jamie Barker; 28.04.2015