Підтримуйте співвідношення сторін у розділі за допомогою CSS


1058

Я хочу створити таке, divяке може змінювати його ширину / висоту, оскільки змінюється ширина вікна.

Чи є правила CSS3, які дозволяли б змінювати висоту відповідно до ширини, зберігаючи її співвідношення сторін ?

Я знаю, що можу це зробити через JavaScript, але я вважаю за краще використовувати лише CSS.

div збереження співвідношення сторін відповідно до ширини вікна


2
Про різні підходи до цього я писав у своїй статті CSS-Tricks про масштабування чутливої ​​анімації
Zach Saucier

2
Я прийшов до цього запитання дуже пізно, але мушу прокоментувати. Хоча це дуже дисципліновано і в рамках правил ПС кожен, хто відповідає, намагається зробити все можливе, щоб задовольнити вимогу "лише CSS", але це дивно, що за винятком відповіді користувача user7 на низькій сторінці, один згадав очевидне: не існує надійного рішення лише для CSS, для цієї проблеми потрібен Javascript. Новачок, який заходить на цю сторінку, може витратити цінний час на перехід від одного набору плюсів / мінусів до іншого, перш ніж лампочка не згасне: CSS-функція не буде робити.
Тео д'Ор

1
Я написав невеликий інструмент, який полегшує попередній перегляд та обчислення співвідношення сторін, аспект сторінок . Він також генерує відповідний код CSS / Sass / Less, який ви можете скопіювати та вставити у свої проекти. Сподіваюсь, люди вважають це корисним.
Райан Гефнер

дивись цей приклад: w3schools.com/howto/howto_css_aspect_ratio.asp ..... що працював у мене
Крістіан Агудело

1
Це питання стосується встановлення висоти на основі ширини . Якщо вам потрібно навпаки, перевірте Налаштування ширини елемента на основі висоти через CSS .
Джон Меллор

Відповіді:


1352

Просто створіть обгортку <div>із відсотковим значенням для padding-bottom, наприклад, цього:

div {
  width: 100%;
  padding-bottom: 75%;
  background: gold; /** <-- For the demo **/
}

/* demonstration purposed only : non-essential */
.demoWrapper {
  padding: 10px;
  background: white;
  box-sizing: border-box;
  resize: horizontal;
  border: 1px dashed;
  overflow: auto;
  max-width: 100%;
  height: calc(100vh - 16px);
}
<div class="demoWrapper">
  <div></div>
</div>

Це призведе <div>до висоти, що дорівнює 75% ширини контейнера (співвідношення сторін 4: 3).

Це спирається на те, що для підкладки:

Відсоток обчислюється по відношенню до ширини створеного блоку, що містить блок [...] (джерело: w3.org , акцент міни)

Значення нижнього розміру для інших співвідношень сторін та 100% ширини:

aspect ratio  | padding-bottom value
--------------|----------------------
    16:9      |       56.25%
    4:3       |       75%
    3:2       |       66.66%
    8:5       |       62.5%

Розміщення вмісту у діві:

Щоб зберегти співвідношення сторін Div і не допустити розтягування його вмісту, вам потрібно додати абсолютно розташоване дочірнє зображення і розтягнути його до країв обгортки за допомогою:

div.stretchy-wrapper {
  position: relative;
}

div.stretchy-wrapper > div {
  position: absolute;
  top: 0; bottom: 0; left: 0; right: 0;
}

Ось демонстрація та ще одна більш глибока демонстрація


29
@schellmax, це тому, що оббивка% обчислюється відносно ширини поточного елемента, де як висота% обчислюється відносно висоти батьківського елемента. Крім того, абсолютні положення обчислюються відносно зовнішньої ємності елемента, що включає площу прокладки. Для отримання додаткової інформації Google "CSS Box Model"
Anson Kao

11
Схоже, це не працює вкладеним способом. Це працює на першому рівні, але, намагаючись зробити те саме, що знаходиться у співвідношенні сторін Div, підтримуючий, нижній відсоток, здається, застосовується до ширини батьків. ось приклад, коли .stretchy-wrap.onethird накладка-дно 25% - це фактично 25% батьківської ширини. Хтось може це пояснити?
Містерпаркер

4
Цілком приголомшливий. Мене вбиває те, що ця техніка не працюватиме, коли потрібно зафіксувати висоту на 100%. @Misterparker, методика покладається на розрахунки ширини і оббивки, що виконуються на одній і тій же посиланнях; ви не можете використовувати ширину менше 100%, як у вашому прикладі.
steveluscher

2
@Misterparker Так, відсоткове накладення обчислюється пропорційно ширині батьківського елемента. Дивіться більш детальний приклад, який я розмістив у редакції своєї відповіді. Моя оновлена ​​демонстрація демонструє «вкладену моду», як ви говорили.
Web_Designer

3
той факт, що він продемонстрував, що цього твору достатньо, щоб переконати мене в тому, що це найкраща відповідь, яку я все ще бачив на SO. кричати моїй людині @Web_Designer

411

vw одиниці:

Можна використовувати vwодиниці як для ширини, так і для висоти елемента. Це дозволяє зберегти співвідношення сторін елемента на основі ширини вікна перегляду.

vw: 1/100 ширини вікна перегляду. [ MDN ]

Крім того, ви також можете використовувати vhдля висоти вікна перегляду або навіть vmin/ vmaxдля використання менших / більших розмірів вікна перегляду (обговорення тут ).

Приклад: співвідношення сторін 1: 1

div {
  width: 20vw;
  height: 20vw;
  background: gold;
}
<div></div>

Для інших співвідношень сторін ви можете використовувати наступну таблицю для обчислення значення висоти відповідно до ширини елемента:

aspect ratio  |  multiply width by
-----------------------------------
     1:1      |         1
     1:3      |         3
     4:3      |        0.75
    16:9      |       0.5625

Приклад: 4х4 сітка квадратних дівок

body {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}
div {
  width: 23vw;
  height: 23vw;
  margin: 0.5vw auto;
  background: gold;
}
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>

Ось Fiddle з цією демонстрацією, і ось рішення, щоб зробити чуйну сітку квадратів з вмістом, орієнтованим по вертикалі та горизонталі .


Підтримка браузера для vh / vw одиниць - IE9 + див. CanIuse для отримання додаткової інформації


13
Це має бути прийнятою відповіддю. Можливо, не зараз, але в майбутньому. Зараз у більшості браузерів підтримуються блоки vw .
серпня

3
@vivekmaharajh обидві методи хороші, у кожного є свої плюси і мінуси. Використання того чи іншого значною мірою залежить від ситуації.
web-tiki

11
@ web-tiki, ти маєш рацію. Я зіткнувся з однією проблемою - передбачається, що ширина елемента пропорційна ширині вікна перегляду, що не буде випадку, якщо 1) у вас є такі речі, як жолоби фіксованої ширини, або 2) у вас встановлена ​​максимальна ширина для деяких ваших елементів.
Вівек Махарадж

1
Можливо, це просто Chrome v47beta, але коли я встановив div width:50%і height:50vwвисота трохи вище ширини, тож не точно в пропорції 1: 1. Будь-які ідеї?
thoan

2
@ 10basetom це нормальна поведінка. vw одиниці містять ширину смуги прокрутки, тоді як% ширина не відповідає. Різниця між висотою та шириною буде залежати від розміру смуги прокрутки, який залежить від браузера.
web-tiki

26

Я знайшов спосіб зробити це за допомогою CSS, але ви повинні бути обережними, оскільки це може змінюватися залежно від потоку вашого власного веб-сайту. Я зробив це для того, щоб вставляти відео з постійним співвідношенням сторін у частину ширини рідини мого веб-сайту.

Скажіть, у вас є таке вбудоване відео:

<object>
     <param ... /><param ... />...
     <embed src="..." ...</embed>
</object>

Потім ви можете розмістити все це у розділі з класом "відео". Цей відео-клас, ймовірно, буде текучим елементом на вашому веб-сайті таким, що сам по собі він не має прямих обмежень по висоті, але коли ви зміните розмір браузера, він зміниться в ширину відповідно до потоку веб-сайту. Це був би елемент, в який ви, ймовірно, намагаєтеся отримати вбудоване відео, зберігаючи певне співвідношення сторін.

Для цього я поставив зображення перед вбудованим об'єктом у розділі "video" класу div.

!!! Важлива частина полягає в тому, що зображення має правильне співвідношення сторін, яке ви хочете зберегти. Крім того, переконайтеся, що розмір зображення НАЙКРАЩИЙ, як найменший, на який ви очікуєте, що відео (або все, що ви підтримуєте AR), має базуватися на вашому макеті. Це дозволить уникнути будь-яких потенційних проблем у вирішенні зображення, коли воно буде відсотковим. Наприклад, якщо ви хочете підтримувати співвідношення сторін 3: 2, не використовуйте зображення 3xx на 2px. Це може спрацювати за певних обставин, але я цього не перевіряв, і, мабуть, було б гарною ідеєю цього уникати.

Напевно, ви вже повинні мати мінімальну ширину, як ця визначена для текучих елементів вашого веб-сайту. Якщо ні, то добре це зробити, щоб уникнути відсікання елементів або перекриття, коли вікно браузера стає занадто малим. Краще мати смугу прокрутки в якийсь момент. Найменша за шириною веб-сторінка повинна отримати десь близько 600 пікселів (включаючи стовпці з фіксованою шириною), оскільки роздільна здатність екрана не менша, якщо ви не маєте стосунків із зручними для телефону сайтами. !!!

Я використовую абсолютно прозорий png, але я не думаю, що це має значення, якщо ви зробите це правильно. Подобається це:

<div class="video">
     <img class="maintainaspectratio" src="maintainaspectratio.png" />
     <object>
          <param ... /><param ... />...
          <embed src="..." ...</embed>
     </object>
</div>

Тепер ви маєте змогу додати CSS, подібний до наступного:

div.video { ...; position: relative; }
div.video img.maintainaspectratio { width: 100%; }
div.video object { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; }
div.video embed {width: 100%; height: 100%; }

Переконайтесь, що ви також видалили будь-яку явну декларацію висоти чи ширини в межах об’єкта та вбудували теги, які зазвичай поставляються із кодом вставлення / вставлення.

Спосіб роботи залежить від позиційних властивостей елемента відеокласу та потрібного елемента підтримувати певне співвідношення сторін. Скористається тим, як зображення підтримуватиме належне співвідношення сторін при зміні розміру в елементі. Він говорить, що все, що є в елементі відеокласу, максимально використовувати переваги нерухомості, наданої динамічним зображенням, примушуючи його ширину / висоту до 100% від елементу відеокласу, що регулюється зображенням.

Досить круто, так?

Вам, можливо, доведеться трохи пограти з цим, щоб змусити його працювати з власним дизайном, але це насправді працює для мене напрочуд добре. Загальна концепція є.


17

Еліот надихнув мене на це рішення - спасибі:

aspectratio.png це абсолютно прозорий PNG-файл із розміром бажаного співвідношення сторін, в моєму випадку - 30x10 пікселів.

HTML

<div class="eyecatcher">
  <img src="/img/aspectratio.png"/>
</div>

CSS3

.eyecatcher img {
  width: 100%;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  background-image: url(../img/autoresized-picture.jpg);
}

Зверніть увагу: background-size це функція css3, яка може не працювати з вашими цільовими браузерами. Ви можете перевірити сумісність (fe на caniuse.com ).


14

Щоб додати відповідь Web_Designer, <div>висота (повністю складається з нижньої прокладки) становить 75% від ширини, що містить елемент . Ось хороший підсумок: http://mattsnider.com/css-using-percent-for-margin-and-padding/ . Я не впевнений, чому так має бути, але це так.

Якщо ви хочете, щоб ваш div був шириною, відмінною від 100%, вам потрібен інший обгортковий div, на якому потрібно встановити ширину:

div.ar-outer{
    width: 60%; /* container; whatever width you want */
    margin: 0 auto; /* centered if you like */
}
div.ar {
    width:100%; /* 100% of width of container */
    padding-bottom: 75%; /* 75% of width of container */
    position:relative;
}
div.ar-inner {
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
}

Нещодавно я використав щось подібне до фокусу зображення Елліота, щоб дозволити мені використовувати медіа-запити CSS для подання іншого файлу логотипу залежно від роздільної здатності пристрою, але все одно пропорційно масштабується, як це <img>було б природно (я встановлюю логотип як фонове зображення прозорим .png з правильним співвідношенням сторін). Але рішення Web_Designer врятувало б мені запит http.


Прекрасне рішення. У моєму випадку я знаю "природний" розмір зображення при розміщенні його на DOM, і мені потрібно мати заповнювач зображення з належною висотою, щоб запобігти подальшому прокрученню, коли браузер завантажує зображення. У .ar-external у мене розмір ширини зображення в пікселях, в .ar у мене є нижнє оббиття, обчислене з реального співвідношення сторін зображення. Замість ар-внутрішнього у мене є саме зображення (<img>). Однак мені довелося встановити ширину на 100% замість того, щоб встановлювати верхній, нижній, лівий і правий. Коли я встановлюю maxWidth на ar-external, зображення добре масштабується, коли батьківський маленький, але не масштабується до більшого розміру, ніж його природний розмір.
Мі-Ла

13

Як зазначено тут на w3schools.com та дещо повторено у цій прийнятій відповіді , значення прокладки у відсотках (акцент мій):

Вказує прокладку у відсотках від ширини містить елемента

Ergo, правильний приклад чуйного DIV, який зберігає співвідношення сторін 16: 9, такий:

CSS

.parent {
    position: relative;
    width: 100%;
}
.child {
    position: relative;
    padding-bottom: calc(100% * 9 / 16);
}
.child > div {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

HTML

<div class="parent">
    <div class="child">
        <div>Aspect is kept when resizing</div>
    </div>
</div>

Демо на JSFiddle


13

Оскільки @ web-tiki вже показує спосіб використання vh/ vw, мені також потрібен шлях до центру на екрані, ось фрагмент коду для портрета 9:16 .

.container {
  width: 100vw;
  height: calc(100vw * 16 / 9);
  transform: translateY(calc((100vw * 16 / 9 - 100vh) / -2));
}

translateYзбереже цей центр на екрані. calc(100vw * 16 / 9)очікувана висота 9/16. (100vw * 16 / 9 - 100vh)- це висота переливу, тому підтягування overflow height/2збереже його центр на екрані.

Для пейзажу та дотримуйтесь 16: 9 ви показуєте використання

.container {
  width: 100vw;
  height: calc(100vw * 9 / 16);
  transform: translateY(calc((100vw * 9 / 16 - 100vh) / -2));
}

Співвідношення 9/16 легко змінювати, не потрібно заздалегідь задавати 100:56.25або. 100:75Якщо ви хочете забезпечити висоту спочатку, слід переключити ширину та висоту, наприклад, height:100vh;width: calc(100vh * 9 / 16)для портрета 9:16.

Якщо ви хочете адаптуватися до різного розміру екрана, ви також можете зацікавити

  • фоновий розмір обкладинки / містити
    • Наведений стиль схожий на вміст, залежить від співвідношення ширини: висоти.
  • об'єкт-придатний
    • обкладинка / містити для тегів img / video
  • @media (orientation: portrait)/@media (orientation: landscape)
    • Медіа-запит щодо portrait/ landscapeдля зміни співвідношення.

11

Це покращення щодо прийнятої відповіді:

  • Використовує псевдоелементи замість обгортки
  • Співвідношення сторін базується на ширині поля, а не на його батьківському
  • Поле розтягнеться вертикально, коли вміст стане вище

.box {
  margin-top: 1em;
  margin-bottom: 1em;
  background-color: #CCC;
}

.fixed-ar::before {
  content: "";
  float: left;
  width: 1px;
  margin-left: -1px;
}
.fixed-ar::after {
  content: "";
  display: table;
  clear: both;
}

.fixed-ar-16-9::before {
  padding-top: 56.25%;
}
.fixed-ar-3-2::before {
  padding-top: 66.66%;
}
.fixed-ar-4-3::before {
  padding-top: 75%;
}
.fixed-ar-1-1::before {
  padding-top: 100%;
}

.width-50 {
  display: inline-block;
  width: 50%;
}
.width-20 {
  display: inline-block;
  width: 20%;
}
<div class="box fixed-ar fixed-ar-16-9">16:9 full width</div>
<hr>
<div class="box fixed-ar fixed-ar-16-9 width-50">16:9</div>
<hr>
<div class="box fixed-ar fixed-ar-16-9 width-20">16:9</div>
<div class="box fixed-ar fixed-ar-3-2 width-20">3:2</div>
<div class="box fixed-ar fixed-ar-4-3 width-20">4:3</div>
<div class="box fixed-ar fixed-ar-1-1 width-20">1:1</div>
<hr>
<div class="box fixed-ar fixed-ar-16-9 width-20">16:9</div>
<div class="box fixed-ar fixed-ar-16-9 width-50">16:9</div>


як відключити вертикальне розтягування коробки? строго кажучи, розтягуючий дів не підтримує співвідношення сторін
флоріан

Якщо вміст вище очікуваної висоти, ящик буде розтягуватися вертикально. Цю ідею найкраще використовувати із вмістом, який може розтягнутися відповідно до розмірів батьків, наприклад, відео та зображення.
Салман А

10

Я натрапив на розумне рішення, використовуючи <svg>і display:grid.

Елемент сітки дозволяє займати один і той же простір з двома (або більше) елементами, не потрібно вказувати, який з них встановлює висоту. Що означає, що поза коробкою вищий встановлює співвідношення .

Це означає, що ви можете використовувати його таким, який є, коли ви знаєте, що вміст ніколи не буде достатньо високим, щоб заповнити весь "коефіцієнт", і ви просто шукаєте спосіб позиціонування вмісту в цьому просторі (тобто, щоб центрирувати його в обох напрямках використання display:flex; align-items:center; justify-content:center).
Це майже те саме, що використовувати прозоре <img>з display:blockзаданим співвідношенням, за винятком того, що <svg>воно легше і значно простіше змінювати (щоб змінити співвідношення у відповідності, якщо вам потрібно).

<div class="ratio">
  <svg viewBox="0 0 1 1"></svg>
  <div>
    I'm square
  </div>
</div>
.ratio {
  display: grid;
}
.ratio > * {
  grid-area: 1/1/1/1;
}

Все, що вам потрібно зробити, - це змінити <svg>співвідношення s:

  • <svg viewBox="0 0 4 3"></svg>
  • <svg viewBox="0 0 16 9"></svg>

Дивіться, як це працює:


Якщо вам потрібне рішення, коли елементу вмісту заборонено встановлювати співвідношення, коли воно вище (із переповненим прихованим або автоматичним), вам потрібно встановити position:relativeна сітці та position:absolute; height:100%; overflow-y: auto;на вміст. Приклад:


9

Спираючись на ваші рішення, я зробив кілька хитрощів:

Коли ви використовуєте його, ваш HTML буде лише

<div data-keep-ratio="75%">
    <div>Main content</div>
</div>

Щоб використовувати його таким чином, зробіть: CSS:

*[data-keep-ratio] {
    display: block;
    width: 100%;
    position: relative;
}
*[data-keep-ratio] > * {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
}

і js (jQuery)

$('*[data-keep-ratio]').each(function(){ 
    var ratio = $(this).data('keep-ratio');
    $(this).css('padding-bottom', ratio);
});

І маючи це, ви просто встановите attr data-keep-ratioна висоту / ширину, і все.


3
Ви повинні використовувати data-keep-ratioНЕ keep-ratioі отримати його значення з допомогою$(this).data('keep-ratio');
Robert

ваш код працює зараз, і, можливо, він буде працювати назавжди, але це не стандартно, і браузери можуть припинити його підтримувати в будь-який час у майбутньому
Роберт,

1
Використання JS тут спричинить погані новини!
Амір Хосейн Ахмаді

8

Ви можете використовувати svg. Зробіть позицію контейнера / обгортки відносною, поставте спочатку svg як статично розміщений, а потім поставте абсолютно розміщений вміст (верх: 0; ліворуч: 0; право: 0; нижній: 0;)

Приклад з пропорціями 16: 9:

image.svg: (можна накреслити у src)

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 9" width="16" height="9"/>

CSS:

.container {
  position: relative;
}
.content {
  position: absolute;
  top:0; left:0; right:0; bottom:0;
}

HTML:

<div class="container">
  <img style="width: 100%" src="image.svg" />
  <div class="content"></div>
</div>

Зауважте, що вбудований svg, здається, не працює, але ви можете urlencode svg та вбудувати його в атрибут img src таким чином:

<img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%209%22%20width%3D%2216%22%20height%3D%229%22%2F%3E" style="width: 100%;" />

7

SCSS - найкраще рішення в моєму випадку; використовуючи атрибут даних:

[data-aspect-ratio] {
    display: block;
    max-width: 100%;
    position: relative;

    &:before {
        content: '';
        display: block;
    }

    > * {
        display: block;
        height: 100%;
        left: 0;
        position: absolute;
        top: 0;
        width: 100%;
    }
}
[data-aspect-ratio="3:1"]:before {
    padding-top: 33.33%;
}
[data-aspect-ratio="2:1"]:before {
    padding-top: 50%;
}
[data-aspect-ratio="16:9"]:before {
    padding-top: 56.25%;
}
[data-aspect-ratio="3:2"]:before {
    padding-top: 66.66%;
}
[data-aspect-ratio="4:3"]:before {
    padding-top: 75%;
}
[data-aspect-ratio="1:1"]:before {
    padding-top: 100%;
}
[data-aspect-ratio="3:4"]:before {
    padding-top: 133.33%;
}
[data-aspect-ratio="2:3"]:before {
    padding-top: 150%;
}
[data-aspect-ratio="9:16"]:before {
    padding-top: 177.77%;
}
[data-aspect-ratio="1:2"]:before {
    padding-top: 200%;
}
[data-aspect-ratio="1:3"]:before {
    padding-top: 300%;
}

Наприклад :

<div data-aspect-ratio="16:9"><iframe ...></iframe></div>

джерело


15
Просто FYI ... Ви можете зробити цю точну річ (використовуючи селектори атрибутів) у точно такій же кількості рядків, використовуючи звичайний CSS. [data-aspect-ratio]Селектор атрибуту доступний для вас у CSS.
rnevius

6

Хоча більшість відповідей дуже круті, більшість з них вимагає, щоб зображення вже було розміщене правильно ... Інші рішення працюють лише на ширину і не дбають про доступну висоту, але іноді вам хочеться вмістити вміст на певній висоті. .

Я намагався з'єднати їх разом, щоб створити повністю портативний і повторно розрізнений варіант ... Трюк полягає в автоматичному масштабуванні зображення, але використовувати вбудований SVG-елемент замість використання попередньо відредагованого зображення або будь-якої форми другий запит HTTP ...

div.holder{
  background-color:red;
  display:inline-block;
  height:100px;
  width:400px;
}
svg, img{
  background-color:blue;
  display:block;
  height:auto;
  width:auto;
  max-width:100%;
  max-height:100%;
}
.content_sizer{
  position:relative;
  display:inline-block;
  height:100%;
}
.content{
  position:absolute;
  top:0;
  bottom:0;
  left:0;
  right:0;
  background-color:rgba(155,255,0,0.5);
}
<div class="holder">
  <div class="content_sizer">
    <svg width=10000 height=5000 />
    <div class="content">
    </div>
  </div>
</div>

Зауважте, що я використовував великі значення в атрибутах ширини та висоти SVG, оскільки він повинен бути більшим за максимально очікуваний розмір, оскільки він може лише скорочуватися. Приклад складає співвідношення діва 10: 5


4

Просто ідея або хак.

div {
  background-color: blue;
  width: 10%;
  transition: background-color 0.5s, width 0.5s;
  font-size: 0;
}

div:hover {
  width: 20%;
  background-color: red;
}
  
img {
  width: 100%;
  height: auto;
  visibility: hidden;
}
<div>
  <!-- use an image with target aspect ratio. sample is a square -->
  <img src="http://i.imgur.com/9OPnZNk.png" />
</div>


Це не єдине CSS-рішення ... Тепер, якби ви використовували закодоване зображення base64 у псевдоелементі, це було б крутим рішенням.
rnevius

1
Насправді немає єдиного CSS рішення. HTML - це основний компонент Інтернету. Я вважаю, що метою питання є утриматися від використання JS, можливо, для економії ресурсів / обробки.
orlland

Я не впевнений, чи працюватиме псевдо елемент. Я використав властивість елемента img, щоб підтримувати його співвідношення сторін для роботи цього рішення.
orlland

Приємно, але висоту він обчислює лише тоді, коли ширина змінюється. Це повинно діяти в обидві сторони, тому коли я зменшу висоту, ширина також перераховується. Інакше марно ..
Ωmega

4

скажемо, у вас є 2 діви, зовнішній дів - це контейнер, а внутрішній може бути будь-яким елементом, який вам потрібно зберегти в його співвідношенні (img або youtube iframe чи будь-що інше)

html виглядає так:

<div class='container'>
  <div class='element'>
  </div><!-- end of element -->

скажемо, що вам потрібно зберегти співвідношення "елемента"

співвідношення => 4 до 1 або 2 до 1 ...

css виглядає так

.container{
  position: relative;
  height: 0
  padding-bottom : 75% /* for 4 to 3 ratio */ 25% /* for 4 to 1 ratio ..*/

}

.element{
  width : 100%;
  height: 100%;
  position: absolute; 
  top : 0 ;
  bottom : 0 ;
  background : red; /* just for illustration */
}

накладки, коли зазначено у%, вона розраховується виходячи з ширини, а не висоти. .. так що в основному ви не має значення, яка ваша ширина і висота завжди буде обчислюватися виходячи з цього. що збереже співвідношення.


4

Якщо ви хочете , щоб відповідати площі всередині видового екрану на книжковій чи пейзаж (якомога більше , але нічого не стирчить зовні), перемикатися між використанням vw/ vhвід орієнтації portrait/ landscape:

@media (orientation:portrait ) {
  .square {
    width :100vw;
    height:100vw;
  }
} 
@media (orientation:landscape) {
  .square {
    width :100vh;
    height:100vh;
  }
} 

4

Я хотів би поділитися своїм рішенням, де у мене є imgтег-заповнення певного співвідношення сторін. Я не міг використовувати backgroundз - за відсутності підтримки CMS і я не вважаю за краще використовувати тег стилю в такий спосіб: <img style="background:url(...)" />. Також ширина становить 100%, тому її не потрібно встановлювати за фіксованим розміром, як у деяких рішеннях. Він буде масштабуватися чуйно!

.wrapper {
  width: 50%;
}

.image-container {
  position: relative;
  width: 100%;
}

.image-container::before {
  content: "";
  display: block;
}

.image-container img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ratio-4-3::before {
  padding-top: 75%;
}

.ratio-3-1::before {
  padding-top: calc(100% / 3);
}

.ratio-2-1::before {
  padding-top: 50%;
}
<div class="wrapper"> <!-- Just to make things a bit smaller -->
  <p>
  Example of an 4:3 aspect ratio, filled by an image with an 1:1 ratio.
  </p>
  <div class="image-container ratio-4-3"> <!-- Lets go for a 4:3 aspect ratio -->
    <img src="https://placekitten.com/1000/1000/" alt="Kittens!" />
  </div>
  <p>
  Just place other block elements around it; it will work just fine.
  </p>
</div>


3

Я стикався з цим питанням досить багато разів, тому вирішив вирішити JS. Це в основному регулює висоту domElement відповідно до ширини елемента за співвідношенням, яке ви задаєте. Ви можете використовувати його так:

<div ratio="4x3"></div>

Зауважте, що оскільки він встановлює висоту елемента, елемент повинен бути або a, display:blockабо display:inline-block.

https://github.com/JeffreyArts/html-ratio-component


1
Хоча я не бачив і не пробував ваш код (у мене вже є свій), я відповів на вашу відповідь лише за те, що ви представляєте єдине надійне рішення, сценарій JS.
Тео д'Ор

Питання спеціально вимагало рішення, яке не потребувало Javascript.
Флейм

2

Ви можете досягти цього, використовуючи SVG.

Це залежить від конкретного випадку, але в деяких це справді корисно. В якості прикладу - ви можете встановити background-imageбез установки фіксованої висоти або використовувати його для вбудовування YouTube <iframe>зі ставленням 16:9і position:absoluteт.д.

Для 3:2встановленого співвідношення viewBox="0 0 3 2"тощо.

Приклад:

div{
    background-color:red
}
svg{
    width:100%;
    display:block;
    visibility:hidden
}

.demo-1{width:35%}
.demo-2{width:20%}
<div class="demo-1">
  <svg viewBox="0 0 3 2"></svg>
</div>

<hr>

<div class="demo-2">
  <svg viewBox="0 0 3 2"></svg>
</div>


2

Скажіть, що вам подобається підтримувати Ширину: 100 пікс. Та Висоту: 50 пікселів (тобто 2: 1). Просто виконайте це з математики:

.pb-2to1 {
  padding-bottom: calc(50 / 100 * 100%); // i.e., 2:1
}

1

Можна використовувати макет потоку (FWD).

https://en.wikipedia.org/wiki/Adaptive_web_design

Він буде масштабувати та підтримувати макет, його трохи складний, але дозволяє змінювати розмір сторінки, не натискаючи на вміст (RWD).

Це схоже на чуйність, але це масштабування. https://www.youtube.com/watch?v=xRcBMLI4jbg

Ви можете знайти формулу масштабування CSS тут:

http://plugnedit.com/pnew/928-2/


Як це відповідає на питання?
Флейм

1

Простий спосіб збереження співвідношення сторін за допомогою елемента полотна.

Спробуйте змінити розмір Div нижче, щоб побачити його в дії.

Для мене такий підхід спрацював найкраще, тому я ділюсь ним з іншими, щоб вони також могли отримати від нього користь.

.cont {
  border: 5px solid blue;
  position: relative;
  width: 300px;
  padding: 0;
  margin: 5px;
  resize: horizontal;
  overflow: hidden;
}

.ratio {
  width: 100%;
  margin: 0;
  display: block;
}

.content {
  background-color: rgba(255, 0, 0, 0.5);
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  margin: 0;
}
<div class="cont">
  <canvas class="ratio" width="16" height="9"></canvas>
  <div class="content">I am 16:9</div>
</div>

Також працює з динамічною висотою!

.cont {
  border: 5px solid blue;
  position: relative;
  height: 170px;
  padding: 0;
  margin: 5px;
  resize: vertical;
  overflow: hidden;
  display: inline-block; /* so the div doesn't automatically expand to max width */
}

.ratio {
  height: 100%;
  margin: 0;
  display: block;
}

.content {
  background-color: rgba(255, 0, 0, 0.5);
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  margin: 0;
}
<div class="cont">
  <canvas class="ratio" width="16" height="9"></canvas>
  <div class="content">I am 16:9</div>
</div>


yup допомогли мені, я тепер можу використовувати його для налаштування зображення батьківського зросту)
Alex

0

Я використав нове рішення.

.squares{
  width: 30vw
  height: 30vw

До основного співвідношення сторін

.aspect-ratio
  width: 10vw
  height: 10vh

Однак це стосується всього вікна перегляду. Отже, якщо вам потрібен div, який становить 30% від ширини огляду, ви можете використовувати замість цього 30vw, і оскільки ви знаєте ширину, ви повторно використовуєте їх у висоту, використовуючи calc та vw одиницю.


7
Це не саме те, що вже було окреслено другою найвищою оцінкою?
rnevius


-4

Якщо вся структура контейнерів була заснована на відсотках, це було б поведінкою за замовчуванням, чи можете ви навести більш конкретний приклад?

Нижче наводиться приклад того, що я маю на увазі, якби вся ваша батьківська ієрархія була заснована на%, будь-яке налаштування вікна браузера працювало б без додаткових js / css, чи не є це можливістю для вашого макета?

<div style="width: 100%;">
   <div style="width: 50%; margin: 0 auto;">Content</div>
</div>

1
Дивіться мою редакцію оригінального запитання. Я не бачу, де ця техніка зберегла б співвідношення сторін, висота не змінилася б.
jackb
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.