Ответ 1
Просто создайте обертку <div>
с процентным значением для padding-bottom
, например:
div {
width: 100%;
padding-bottom: 75%;
background: gold; /** <-- For the demo **/
}
<div></div>
Я хочу создать div
который может изменять его ширину/высоту при изменении ширины окна.
Существуют ли какие-либо правила CSS3, которые позволили бы изменить высоту в соответствии с шириной при сохранении соотношения сторон?
Я знаю, что могу сделать это с помощью JavaScript, но я бы предпочел использовать только CSS.
Просто создайте обертку <div>
с процентным значением для padding-bottom
, например:
div {
width: 100%;
padding-bottom: 75%;
background: gold; /** <-- For the demo **/
}
<div></div>
vw
единиц:Вы можете использовать единицы vw
для ширины и высоты элемента. Это позволяет сохранить соотношение сторон элемента в зависимости от ширины окна просмотра.
vw: 1/100th ширины окна просмотра. [MDN]
В качестве альтернативы вы также можете использовать vh
для высоты окна просмотра или даже vmin
/vmax
для использования меньшего/большего размера размеров окна просмотра (обсуждение здесь).
div {
width: 20vw;
height: 20vw;
background: gold;
}
<div></div>
Я нашел способ сделать это с помощью CSS, но вы должны быть осторожны, поскольку это может измениться в зависимости от потока вашего собственного веб-сайта. Я сделал это, чтобы вставлять видео с постоянным соотношением сторон в пределах ширины жидкости моего веб-сайта.
Скажем, у вас есть встроенное видео:
<object>
<param ... /><param ... />...
<embed src="..." ...</embed>
</object>
Затем вы можете разместить все это внутри div с классом "видео". Этот видеокласс, вероятно, будет жидким элементом вашего сайта, который сам по себе не имеет прямых ограничений по высоте, но при изменении размера браузера он будет меняться по ширине в соответствии с потоком веб-сайта. Это будет тот элемент, который вы, вероятно, пытаетесь подключить встроенное видео, сохраняя при этом определенное соотношение сторон видео.
Чтобы сделать это, я поместил изображение перед внедренным объектом в класс div видео.
!!! Важная часть состоит в том, что изображение имеет правильное соотношение сторон, которое вы хотите сохранить. Кроме того, убедитесь, что размер изображения максимально высок, чем самый маленький, который вы ожидаете от видео (или того, что вы поддерживаете A.R.), чтобы получить на основе вашего макета. Это позволит избежать любых возможных проблем при разрешении изображения при его изменении в процентах. Например, если вы хотите сохранить соотношение сторон 3: 2, не просто используйте изображение 3px на 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% элемента видеокласса корректироваться с помощью изображения.
Довольно круто, а??
Возможно, вам придется немного поиграть с ним, чтобы заставить его работать с вашим собственным дизайном, но на самом деле это работает на удивление хорошо для меня. Существует общая концепция.
Эллиот вдохновил меня на это решение - спасибо:
aspectratio.png
- это полностью прозрачный PNG файл с размером вашего предпочтительного соотношения сторон, в моем случае 30x10 пикселей.
<div class="eyecatcher">
<img src="/img/aspectratio.png"/>
</div>
.eyecatcher img {
width: 100%;
background-repeat: no-repeat;
background-size: 100% 100%;
background-image: url(../img/autoresized-picture.jpg);
}
Обратите внимание: background-size
- это функция css3, которая может не работать с вашими целевыми браузерами. Вы можете проверить совместимость (например, caniuse.com).
Чтобы добавить к ответу на 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-запроса.
Как указано здесь на 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>
Основываясь на ваших решениях, я сделал несколько трюков:
Когда вы используете его, ваш 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
на высоту/ширину и что это.
Вы можете использовать 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>
Обратите внимание, что inline 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%;" />
Поскольку @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
75.Если вы хотите сначала обеспечить высоту, вы должны переключить ширину и высоту, например, height:100vh;width: calc(100vh * 9/16)
для портрета 9:16.
Если вы хотите адаптироваться для разных размеров экрана, вы также можете заинтересовать
@media (orientation: portrait)
/@media (orientation: landscape)
portrait
/landscape
для изменения отношения.Это является улучшением принятого ответа:
.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>
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>
html выглядит следующим образом:
<div class='container'>
<div class='element'>
</div><!-- end of element -->
скажет, что вам нужно сохранить соотношение "элемент"
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 */
}
заполнение, если указано в%, оно рассчитывается на основе ширины не высоты. .. так что в основном вам не важно, на какой основе ваша высота будет всегда рассчитываться на основе этого. который будет поддерживать соотношение.
Просто идея или взлома.
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>
В то время как большинство ответов очень классные, большинство из них требуют правильного размера изображения... Другие решения работают только по ширине и не заботятся о высоте, но иногда вы хотите поместить контент в определенная высота тоже.
Я попытался связать их вместе, чтобы принести полностью портативное и многозначное решение... Фокус в том, чтобы использовать для автоматического масштабирования изображения, но использовать встроенный элемент 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>
Я столкнулся с этой проблемой довольно часто, поэтому я сделал для нее решение JS. Это в основном регулирует высоту domElement по ширине элемента по указанному вами соотношению. Вы можете использовать его следующим образом:
<div ratio="4x3"></div>
Помните, что поскольку он устанавливает высоту элемента, элемент должен быть либо display:block
, либо display:inline-block
.
Если вы хотите поместить квадрат внутри окна просмотра на любом портретном или альбомном представлении (насколько это возможно, но ничего не торчит снаружи), переключайтесь между использованием vw
/vh
при ориентации portrait
/landscape
@media (orientation:portrait ) {
.square {
width :100vw;
height:100vw;
}
}
@media (orientation:landscape) {
.square {
width :100vh;
height:100vh;
}
}
Вы можете использовать флеш-макет (FWD).
https://en.wikipedia.org/wiki/Adaptive_web_design
Он будет масштабировать и поддерживать макет, его бит сложный, но позволяет изменять размер страницы, не нажимая на такой контент (RWD).
Он выглядит отзывчивым, но он масштабируется. https://www.youtube.com/watch?v=xRcBMLI4jbg
Формулу масштабирования CSS можно найти здесь:
Скажите, что вы поддерживаете Width: 100px и Height: 50px (т.е. 2: 1). Просто выполните эту математику:
.pb-2to1 {
padding-bottom: calc(50 / 100 * 100%); // i.e., 2:1
}
Я наткнулся на умное решение, используя <svg>
и display:grid
.
Элемент 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>
:
<svg viewBox="0 0 4 3"></svg>
<svg viewBox="0 0 16 9"></svg>
См. Работу:
.ratio {
display: grid;
}
.ratio > * {
grid-area: 1/1/1/1;
}
/* below code NOT needed for setting the ratio
* I just wanted to mark it visually
* and center contents
*/
.ratio div {
border: 1px solid red;
display: flex;
align-items: center;
justify-content: center;
}
<div class="ratio">
<svg viewBox="0 0 7 1"></svg>
<div>
Fixed ratio 7:1
</div>
</div>
Если бы вся структура контейнера была основана на процентах, это было бы поведением по умолчанию, можете ли вы предоставить более конкретный пример?
Ниже приведен пример того, что я имею в виду, если бы вся ваша родительская иерархия была% на основе, любая настройка окна браузера работала бы без каких-либо дополнительных js/css, разве это не возможно с вашим макетом?
<div style="width: 100%;">
<div style="width: 50%; margin: 0 auto;">Content</div>
</div>
Я использовал новое решение.
.squares{
width: 30vw
height: 30vw
К основному соотношению сторон
.aspect-ratio
width: 10vw
height: 10vh
Однако это касается всего окна просмотра. Итак, если вам нужен div, который составляет 30% ширины видового экрана, вы можете использовать 30vw вместо этого, и, поскольку вы знаете ширину, вы повторно используете их по высоте, используя блок calc и vw.