Ответ 1
Я не верю, что это возможно без JS, но, может быть, кто-то может доказать, что я неправ?
CSS не позволяет использовать динамические переменные, поэтому, если высота не установлена до загрузки страницы, я не уверен, как это можно сделать.
У меня есть набор элементов и требуется, чтобы их минимальная ширина была равна их высоте, но высота явно не задана. В настоящее время я могу добиться этого, установив свойство css min-width
через jQuery:
$(document).ready
(
function()
{
$('.myClass').each
(
function() {$(this).css('min-width', $(this).css('height'));}
);
}
);
Можно ли указать это поведение непосредственно в css?
Вот пример jsfiddle, демонстрирующий, чего я пытаюсь достичь: http://jsfiddle.net/p8PeW/
Я не верю, что это возможно без JS, но, может быть, кто-то может доказать, что я неправ?
CSS не позволяет использовать динамические переменные, поэтому, если высота не установлена до загрузки страницы, я не уверен, как это можно сделать.
Это на самом деле возможно без JS!
Ключ заключается в том, чтобы использовать <img>
, который является заменяемым элементом, и, следовательно, если вы устанавливаете только высоту, его ширина будет установлена автоматически, чтобы сохранить внутренние пропорции изображения.
Следовательно, вы можете сделать следующее:
<style>
.container {
position: relative;
display: inline-block; /* shrink wrap */
height: 50vh; /* arbitrary input height; adjust this */
}
.container > img {
height: 100%; /* make the img width 100% of the height of .container */
}
.contents {
/* match size of .container, without influencing it */
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
</style>
<div class="container">
<!-- transparent image with 1:1 intrinsic aspect ratio -->
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
<div class="contents">
Put contents here.
</div>
</div>
Если вы хотите, чтобы .contents
имел соотношение сторон 4: 3, вы бы вместо этого установили высоту img .contents
133%, поэтому ширина img и, следовательно, .contents
будет равна 133% от высоты .container
.
Демонстрационная версия с соотношением сторон 1: 4: https://jsbin.com/juduheq/edit (с дополнительными комментариями к коду).
Еще одно живое демо, где высота контейнера определяется количеством текста в элементе-брате: https://jsbin.com/koyuxuh/edit
Если вам интересно, URI данных img предназначен для прозрачного gif размером 1x1 px). Если изображение не имеет соотношения сторон 1:1, вам необходимо соответствующим образом отрегулировать значения высоты, которые вы установили. Вы также можете использовать элемент <canvas>
или <svg>
вместо <img>
(спасибо Simo).
Если вместо этого вы хотите установить высоту элемента в зависимости от ширины, есть гораздо более простой трюк в поддержании соотношения сторон div с помощью CSS.
От W3C Box Model на набивке:
Процент рассчитывается относительно ширины сгенерированного блока, содержащего блок, даже для "padding-top" и "padding-bottom". Если ширина содержащего блока зависит от этого элемента, то результирующий макет не определен в CSS 2.1.
Таким образом, вы можете получить его, используя только CSS. Посмотрите этот пример из этого поста в блоге на другую тему, не менее интересную. Хитрость в создании коэффициентов заключается в использовании чего-то вроде
element::before {
content: '';
display: block;
padding-bottom: 100%;
}
Существует еще одно очень простое решение css, но только для точного случая, который OP представил в его jsfiddle:
label {
background-color: Black;
color: White;
padding: 1px;
font-family: sans-serif;
text-align: center;
vertical-align: middle;
display: inline-block;
min-width: 1em; /* set width to the glyphs height */
}
<label>A</label><br/>
<label>B</label><br/>
<label>C</label><br/>
<label>D</label><br/>
<label>E</label><br/>
<label>F</label><br/>
<label>R6a</label>
Если вы пытаетесь сделать квадраты, вам придется учитывать оба случая (W > H
и W < H
):
$('label').each(function() {
if ($(this).height() > $(this).width()) {
$(this).css('min-width', $(this).height());
} else {
$(this).css('min-height', $(this).width());
}
});
У меня было такое же требование, и я успешно использовал решение @John Melor... до тех пор, пока оно не сработало в Firefox. Я попытался воспроизвести свою конкретную проблему, протестировав различные примеры кода jsbin здесь, но не повезло. Вероятно, очень специфическая ошибка браузера, основанная на моем реальном DOM. Если у кого-то есть jsbin этой проблемы, пожалуйста, поделитесь!
Я перепробовал много комбинаций, которые не срабатывают на одном и том же: контейнер не расширяется до ширины изображения. Firefox объявляет, что у изображения есть ширина его высоты, но у родителя есть ширина 1px независимо от того, что я попробовал.
Для тех, кто оказался в такой ситуации, я использовал исправление js, которое остается локальным для элемента изображения. Если высота контейнера не указана, как в первоначальном OP-вопросе, это также может быть полезно для вас.
В JSX/ES6:
const TRANSPARENT_PIXEL = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
const setWidthToHeight = e => { e.target.style.width = e.target.height }
const force1x1Ratio = <img src={TRANSPARENT_PIXEL} onLoad={setWidthToHeight} />
С простым старым HTML
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
onLoad="javascript:function(e) { e.target.style.width = e.target.height + 'px' }" />