Как сделать div гибким квадратом?

Я хочу, чтобы мой div изменял высоту так, чтобы она всегда была равна ширине. Ширина указана в процентах. Когда ширина родительского элемента уменьшается, поле должно уменьшаться, сохраняя свое соотношение сторон.

Как это сделать в CSS?


person danijar    schedule 28.09.2013    source источник
comment
comment
Идеальный квадрат на любом экране: jsfiddle.net/far4jqt2/2   -  person Junior    schedule 28.04.2018
comment
Вот хорошая статья с хорошим объяснением ... spin.atomicobject. ru / 2015/07/14 / css-responsive-square   -  person clayRay    schedule 12.09.2019


Ответы (6)


Работает практически во всех браузерах.

Вы можете попробовать дать padding-bottom в процентах.

<div style="height:0;width:20%;padding-bottom:20%;background-color:red">
<div>
Content goes here
</div>
</div>

Внешний div создает квадрат, а внутренний div содержит контент. Это решение сработало у меня много раз.

Вот jsfiddle

person rahulbehl    schedule 28.09.2013
comment
Это работает, но я не разбираюсь в технике. Не могли бы вы объяснить, почему это на самом деле работает? - person danijar; 28.09.2013
comment
Это очень хорошее руководство, если вы хотите использовать метод padding-bottom. [ссылка] dwuser.com/education/ content / - person rahulbehl; 28.09.2013
comment
Учебник неплохой, легко разбираюсь в технике. - person danijar; 29.09.2013
comment
Предпочтительнее выбранного ответа, потому что он работает в рамках ограничений контейнера, а НЕ в области просмотра, которая редко бывает полезной. - person Matt Saunders; 28.08.2014
comment
Это невероятно. Если бы я мог, я бы проголосовал за это 1000 раз. - person dgo; 09.12.2014
comment
Вау! Отличное решение! Мне очень жаль себя создавать обходные пути JS все эти годы. - person Luuuud; 27.03.2015
comment
Сначала мне не понравился этот, потому что он выглядит как взлом, в любом случае есть хорошее обсуждение на stackoverflow.com/questions/11003911/ - person Coded Monkey; 30.03.2015
comment
Не забудьте box-sizing: content-box;, если вы добавите границу к объекту. Иначе это может исказить соотношение 1: 1. (произошло при добавлении жирного бордюрного радиуса) - person zsitro; 10.12.2015
comment
Это действительно здорово. Откуда я этого не знал? Вы можете получить что угодно, чтобы иметь соотношение сторон, например, я просто установил для моего padding-bottom значение 120%, и теперь соотношение ширины к высоте составляет 1: 1,2 - потрясающе. - person Matt Fletcher; 07.01.2016
comment
похоже, не работает на новом, т.е. Edge, когда элемент имеет display: flex;, он действительно работает в более старых версиях - person mmln; 25.03.2016
comment
У меня это как-то не работает в Chrome. Если во внутреннем div нет содержимого, соотношение бокса равно 1: 1, но когда я добавляю содержимое во внутренний div, он занимает некоторое пространство и делает высоту больше ширины. - person C.Lee; 15.06.2016
comment
Это отличное решение! Спасибо, что поделились. - person ITWitch; 12.07.2016
comment
@ C.Lee Вы должны добавить position: absolute; на внутреннем div, чтобы он заработал. Элементы с абсолютным позиционированием игнорируются при вычислении родительских размеров. Это означает, что вы можете добавлять во внутренний элемент контент, а также отступы, границы и т. Д. :) См. эту скрипку. - person Max Truxa; 27.10.2016
comment
@MaxTruxa О, хорошо, спасибо! Позвольте мне попробовать - person C.Lee; 28.10.2016
comment
Этот метод фактически используется для отображения изображений в Google AMP. Прохладный! - person Romel Indemne; 26.11.2019
comment
Это должен быть принятый ответ, потому что он адаптивный и наследует ширину от родителя, а НЕ от окна. - person Magico; 30.03.2020
comment
Если кто-то использует гибкие контейнеры, будьте осторожны, потому что они не работают правильно во вложенных структурах. - person David Arreola; 17.12.2020

Чтобы добиться того, что вы ищете, вы можете использовать длину окна просмотра в процентах vw.

Вот небольшой пример, который я сделал на jsfiddle.

HTML:

<div class="square">
    <h1>This is a Square</h1>
</div>

CSS:

.square {
    background: #000;
    width: 50vw;
    height: 50vw;
}
.square h1 {
    color: #fff;
}

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

person Daniel Burkhart    schedule 28.09.2013
comment
Это определенно самое чистое решение. Для людей, заинтересованных в поддержке браузера, я нашел этот обзор. - person danijar; 28.09.2013
comment
Очень хорошо, но поддержка браузером на данный момент немного отрывочна, хотя не так ли - google.ie/ - person byronyasgur; 04.12.2013
comment
Это решение плохо сочетается с сеткой. Если вы смотрите на квадраты, увеличивающиеся с шириной столбцов, ответ @rahulbehl работает лучше. - person eightyfive; 11.09.2014
comment
Поддержка браузером для vw: caniuse.com/#search=vw - person Chemical Programmer; 29.01.2016
comment
Браузерная поддержка для vw довольно хороша, но, вероятно, она не сработает для вас, если ваши страницы прокручиваются. vw - это фактически ширина окна, а не области просмотра, поскольку он включает полосы прокрутки (то же самое с vh для вертикального материала). На мой взгляд, плохое решение авторов спецификации, потому что это может быть очень полезной единицей измерения, но если ваши страницы прокручиваются, вам лучше использовать решение @ rahulbehl. Я не могу придумать вариант использования, когда было бы удобно иметь ширину, включая полосы прокрутки ... но это то, что есть. - person Tom Walker; 19.05.2016
comment
это деформирует изображение, и лучше, если вы сможете его исправить, поэтому: / - person Alberto Acuña; 04.01.2017
comment
Совет: если вы хотите разместить квадрат внутри области просмотра в портретной или альбомной ориентации: `` `@media (Ориентация: портрет) {width: 100vw; height: 100vw;} @media (ориентация: альбомная) {width: 100vh; высота: 100vh;} `` ` - person MoonLite; 16.06.2017

HTML

<div class='square-box'>
    <div class='square-content'>
        <h3>test</h3>
    </div>
</div>

CSS

.square-box{
    position: relative;
    width: 50%;
    overflow: hidden;
    background: #4679BD;
}
.square-box:before{
    content: "";
    display: block;
    padding-top: 100%;
}
.square-content{
    position:  absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    color: white;
    text-align: center;
}

http://jsfiddle.net/38Tnx/1425/

person gidzior    schedule 11.03.2015
comment
Это чистая магия, но она работает! Спасибо! - person Mārtiņš Briedis; 15.05.2015
comment
Что это за черная магия ?! - person Jeremy Belolo; 26.08.2015
comment
Это решение действительно хорошо работает, когда ширина может быть ограничена правилом максимальной ширины. В этих случаях фактическая вычисленная ширина может быть меньше ширины, заданной в процентах, и все другие решения, которые устанавливают заполнение непосредственно на самом внешнем элементе, завершатся ошибкой. - person daniels; 18.07.2016
comment
Ой, это дерзко. 100 очков гидзиор - person Matt Fletcher; 05.09.2017
comment
Как упоминает @daniels, важно установить отступ на псевдоэлементе, чтобы он правильно ограничивался max-width - person Gidgidonihah; 17.11.2017
comment
Использование .square-box: after вместо .square-box: before ведет себя точно так же. - person petersaints; 10.02.2018
comment
Это работает, потому что заполнение элемента рассчитывается относительно ширины его родительского элемента. - person hudidit; 22.09.2019
comment
Я искал ответы, чтобы сохранить соотношение сторон div при изменении их размера с помощью гибкого блока, и это единственный, который работал отлично. Чистая магия, спасибо! - person chnging; 17.10.2019

Это так же просто, как указать нижний отступ того же размера, что и ширина в процентах. Поэтому, если у вас ширина 50%, просто используйте этот пример ниже.

id or class{
    width: 50%;
    padding-bottom: 50%;
}

Вот jsfiddle http://jsfiddle.net/kJL3u/2/

Отредактированная версия с адаптивным текстом: http://jsfiddle.net/kJL3u/394

person Chipe    schedule 29.05.2014
comment
Однако это происходит из квадратного соотношения сторон, когда вы добавляете к нему контент. - person zoul; 27.03.2015
comment
Вы можете решить эту проблему с помощью overflow:hidden или другого абсолютного позиционирования дочерних элементов внутри контейнера. Удобно точно так же, как ответ @gidzior - person mix3d; 26.10.2015

Другой способ - использовать прозрачный 1x1.png с width: 100%, height: auto в div и абсолютно позиционированным содержимым внутри него:

html:

<div>
    <img src="1x1px.png">
    <h1>FOO</h1>
</div>

css:

div {
    position: relative;
    width: 50%;
}

img {
    width: 100%;
    height: auto;
}

h1 {
    position: absolute;
    top: 10px;
    left: 10px;
}

Fidle: http://jsfiddle.net/t529bjwc/

person gskalinskii    schedule 02.02.2015
comment
Это более полезный метод, потому что у вас есть фактический размер и высота, с которыми можно работать - полезно для элементов внутри квадратного div. - person Smith; 17.08.2017
comment
Хороший совет, но он работает еще лучше с <svg viewBox='0 0 1 1'></svg> - person Nelo Mitranim; 02.06.2018

Это то, что я придумал. Вот скрипка.

Во-первых, мне нужны три элемента-оболочки как для квадратной формы, так и для центрированного текста.

<div><div><div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit,
sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat
volutpat.</div></div></div>

Это таблица стилей. В нем используются два метода: один для квадратных форм и один для текст по центру.

body > div {
    position:relative;
    height:0;
    width:50%; padding-bottom:50%;
}

body > div > div {
    position:absolute; top:0;
    height:100%; width:100%;
    display:table;
    border:1px solid #000;
    margin:1em;
}

body > div > div > div{
    display:table-cell;
    vertical-align:middle; text-align:center;
    padding:1em;
}
person danijar    schedule 28.09.2013
comment
Дополнительные элементы для простого квадрата, юк, но, думаю, работает. Примечание; display:table-cell не поддерживается в IE7 и старше. - person TheCarver; 23.02.2014