Рассчитать высоту div на основе ширины и сохранить пропорции
Я ищу чистое решение CSS для того, что я здесь сделал, используя jQuery, чтобы помочь.
В основном у меня есть 3 div, которые равномерно распределены по ширине в контейнере. Они поддерживают соотношение 3/4 с высотой, вычисляемой по ширине. Кроме того, у каждого div есть фоновое изображение, которое остается пропорциональным, и некоторый текст, который центрируется по горизонтали и вертикали.
$(document).ready(function() {
function setw() {
var footdivwidth = $('footer div').width();
var footdivheight = footdivwidth * .75;
$('footer div').css({
'height': footdivheight + 'px'
});
$('footer div span').html('w: ' + footdivwidth + '<br>h: ' + footdivheight);
}
setw();
$(window).resize(function() {
setw();
})
});
FOOTER {
max-width: 1000px;
margin: 0 auto;
background-color: rgba(0, 0, 0, 0.171);
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
FOOTER DIV {
background-image: url('https://learnwebdesign.online/img/bg.jpg');
background-position: center;
background-size: cover;
background-repeat: no-repeat;
flex: 1;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
FOOTER DIV SPAN {
display: inline-block;
text-align: center;
background-color: rgba(165, 165, 165, 0.282);
padding: 7px 15px;
border-radius: 3px;
color: #FFFFFF;
text-transform: uppercase;
font-weight: bold;
letter-spacing: 2px;
font-size: 21px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<footer>
<div><span>left photo</span></div>
<div><span>center photo</span></div>
<div><span>right photo and more text</span></div>
</footer>
Ответы
Ответ 1
Поддержание определенного соотношения высоты: ширины в CSS обычно выполняется с использованием того факта, что процент заполнения всегда вычисляется на основе ширины элемента.
Например, предположим, что у вас есть элемент с width: 500px
, height: 300px
и height: 300px
padding: 10%
. Теперь вы можете ожидать, что верхний и нижний отступы будут на 10% height
, а левый и правый отступы - на 10% width
. Однако это дало бы неравные вертикальные и горизонтальные отступы, что противоречит тому, что предполагается - равные отступы в 10%. Чтобы понять это, нам нужно основать процент заполнения на измерении сохранения, и этот размер был выбран в качестве ширины.
Таким образом, чтобы всегда иметь элемент с отношением высоты: ширины 3: 4, мы можем установить высоту равной 0, а нижний (или верхний) отступ - 3/4 ширины.
В вашем примере Flex получает ширину 33%. При соотношении 3: 4 нижнее заполнение должно составлять 33% * 3/4 или 24,74%. Ваш CSS может выглядеть так:
width: 33%;
height: 0;
padding-bottom: 24.75%;
Обратите внимание, что, поскольку высота равна 0, элемент должен быть относительно позиционирован с абсолютно позиционированной оберткой внутри. Если вы попытаетесь поместить контент прямо в div, это нарушит соотношение. Ваш код выше может быть изменен таким образом:
footer {
max-width: 1000px;
margin: 0 auto;
background-color: rgba(0, 0, 0, 0.171);
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
footer div {
background-image: url('https://learnwebdesign.online/img/bg.jpg');
background-position: center;
background-size: cover;
background-repeat: no-repeat;
position: relative;
width: 33%;
height: 0;
padding-bottom: 24.75%;
}
footer div span {
/* Used as content wrapper, with flex to centre content */
position: absolute;
top: 0; bottom: 0;
left: 0; right: 0;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
background-color: rgba(165, 165, 165, 0.282);
padding: 7px 15px;
border-radius: 3px;
color: #FFFFFF;
text-transform: uppercase;
font-weight: bold;
letter-spacing: 2px;
font-size: 21px;
}
<footer>
<div><span>left photo</span></div>
<div><span>center photo</span></div>
<div><span>right photo and more text</span></div>
</footer>
Ответ 2
Вы пробовали с
footer div {
height: 20vw;
}
есть также свойство calc для css, которое может быть полезным
https://developer.mozilla.org/en-US/docs/Web/CSS/calc
Ответ 3
Вы можете просто рассмотреть основной прием для сохранения соотношения сторон с помощью отступов .
Вот пример, где я сохранил оба примера, чтобы вы могли сравнить, один с использованием jQuery, а другой с использованием чистого CSS.
$(document).ready(function() {
function setw() {
var footdivwidth = $('footer div').width();
var footdivheight = footdivwidth * .75;
$('footer.no-padd div').css({
'height': footdivheight + 'px'
});
$('footer div span').html('w: ' + footdivwidth + '<br>h: ' + footdivheight);
}
setw();
$(window).resize(function() {
setw();
})
});
FOOTER {
max-width: 1000px;
margin: 0 auto;
background-color: rgba(0, 0, 0, 0.171);
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
FOOTER DIV {
background-image: url('https://learnwebdesign.online/img/bg.jpg');
background-position: center;
background-size: cover;
background-repeat: no-repeat;
flex: 1;
text-align: center;
display: flex
}
FOOTER:not(.no-padd) DIV:before {
content:"";
padding-top: 75%;
}
FOOTER DIV SPAN {
margin:auto;
text-align: center;
background-color: rgba(165, 165, 165, 0.282);
padding: 7px 15px;
border-radius: 3px;
color: #FFFFFF;
text-transform: uppercase;
font-weight: bold;
letter-spacing: 2px;
font-size: 21px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<footer class="no-padd">
<div><span>left photo</span></div>
<div><span>center photo</span></div>
<div><span>right photo and more text</span></div>
</footer>
<footer >
<div><span>left photo</span></div>
<div><span>center photo</span></div>
<div><span>right photo and more text</span></div>
</footer>
Ответ 4
Быстрое чистое CSS
решение потребует добавления в FOOTER DIV
max-width: 333px;
width: calc(100vw/3);
height: calc(100vw*0.75/3);
max-height: calc(333px*0.75);
и добавить в FOOTER
width: 100vw;
// Javascript is only used in order to check the width/height ratio in console live.
$(document).ready(function() {
$(window).resize(function() {
console.log('width: ' + $('footer div').width() + ', height: ' + $('footer div').height());
});
});
FOOTER {
max-width: 1000px;
width: 100vw;
margin: 0 auto;
background-color: rgba(0, 0, 0, 0.171);
display: flex;
flex-wrap: wrap;
/*justify-content: space-between;*/
}
FOOTER DIV {
background-image: url('https://learnwebdesign.online/img/bg.jpg');
background-position: center;
background-size: cover;
background-repeat: no-repeat;
flex: 1;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
max-width: 333px;
width: calc(100vw/3);
height: calc(100vw*0.75/3);
max-height: calc(333px*0.75);
}
FOOTER DIV SPAN {
display: inline-block;
text-align: center;
background-color: rgba(165, 165, 165, 0.282);
padding: 7px 15px;
border-radius: 3px;
color: #FFFFFF;
text-transform: uppercase;
font-weight: bold;
letter-spacing: 2px;
font-size: 21px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<footer>
<div><span>left photo</span></div>
<div><span>center photo</span></div>
<div><span>right photo and more text</span></div>
</footer>
Ответ 5
Возможно, немного поздно, но добавлю и мое решение.
Я подумал, что это общее решение, поэтому я решил не использовать ваши классы нижнего колонтитула. Но я уверен, что вы получите хитрость.
На мой взгляд, самый простой способ - использовать вычисление заполнения, чтобы получить фиксированное соотношение и некоторые деления.
- Контейнер Flex
- Элементы Flex (с отступом на нем): этот контейнер используется для поддержания разрешения. Количество отступов для него зависит от ширины предмета. Например: ширина элемента = 100% → заполнение = (100/4) * 3 → 75% заполнения
- Контейнер для содержимого внутри Flex-Item, куда вы можете положить свои вещи
- Background-Div внутри контейнера содержимого
- Положите все, что вам нужно, как брат в фоновом режиме
Здесь можно поиграться, некоторые комментарии в коде: https://jsfiddle.net/Hoargarth/Lry5gbsq/Не стесняйтесь спрашивать, если вам что-то нужно
Просто краткое замечание по всем этим контейнерам: вы можете сделать это только с помощью flex-item и еще одного контейнера. Но, на мой взгляд, с дополнительным контейнером он становится более гибким, если вам нужны какие-либо события при наведении курсора, анимация или другие экзотические вещи. Для простого решения см. Эту скрипку: https://jsfiddle.net/Hoargarth/m57b9jcw/
.container {
width: 100%;
display: flex;
flex-wrap: wrap;
}
/* padding bottom gives the height of the container, 33.33% padding would be a quadratic box. 100% would be the same height as the container width. Therefore simple trignomometry, (100/4) * 3 = 75%; or for screen width > 500px: (33.33 / 4) * 3 for a 4/3 resolution. You'll find the media query at the end of the css. It just to demonstrate that it working with media queries as well. */
.item {
position: relative;
width: 100%;
padding-bottom: 75%;
}
/* Overflow hidden so nothing can overlap to the other items */
.content-wrapper {
position: absolute;
overflow: hidden;
width: 100%;
height: 100%;
}
.image-holder {
position: relative;
height: 100%;
background-image: url("https://previews.123rf.com/images/happydancing/happydancing1706/happydancing170600014/80282512-flat-lay-photo-of-workspace-desk-with-laptop-smartphone-blank-notebook-and-green-plant-with-copy-spa.jpg");
background-size: cover;
background-position: 50%;
background-repeat: no-repeat;
}
/* Absolute positioned by 50% top, left; To completely center it, you have to translate the holder back by it own half width and height transform: translate(-50%, -50%) */
.text-holder {
position: absolute;
top: 50%;
left: 50%;
padding: 10px;
width: 70%;
background-color: rgba(255, 255, 255, 0.5);
transform: translate(-50%, -50%);
text-align: center;
}
/* Simple media Query to test it. Be aware: If the item width is changing, the padding has to change as well */
@media (min-width: 500px) {
.item {
width: 33.33%;
padding-bottom: 24.75%;
}
}
<div class="container">
<div class="item">
<div class="content-wrapper">
<div class="image-holder"></div>
<div class="text-holder">
<p>
Some Centered Text
</p>
</div>
</div>
</div>
<div class="item">
<div class="content-wrapper">
<div class="image-holder"></div>
<div class="text-holder">
<p>
Some Centered Text but larger and longer so we see a difference
</p>
</div>
</div>
</div>
<div class="item">
<div class="content-wrapper">
<div class="image-holder"></div>
<div class="text-holder">
<p>
Groot
</p>
</div>
</div>
</div>
</div>
Ответ 6
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
FOOTER {
max-width: 1000px;
margin: 0 auto;
background-color: rgba(0, 0, 0, 0.171);
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
FOOTER DIV {
position: relative;
width: calc(100vw / 3);
height: calc(100vw / 3 * 0.75 );
max-height: calc(1000px / 3 * 0.75 );
background-image: url('https://learnwebdesign.online/img/bg.jpg');
background-position: center;
background-size: cover;
background-repeat: no-repeat;
flex: 1;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
FOOTER DIV SPAN {
position: absolute;
top:50%;
left: 50%;
transform: translate(-50%, -50%);
display: inline-block;
text-align: center;
background-color: rgba(165, 165, 165, 0.282);
padding: 7px 15px;
border-radius: 3px;
color: #FFFFFF;
text-transform: uppercase;
font-weight: bold;
letter-spacing: 2px;
font-size: 21px;
}
</style>
</head>
<body>
<footer>
<div><span>left photo</span></div>
<div><span>center photo</span></div>
<div><span>right photo and more text</span></div>
</footer>
</body>
</html>
Вы можете напрямую использовать данный код, для создания предполагаемой высоты ширины, у вас есть 2 различных способа, один из которых приведен ниже, вы можете использовать ширину в процентах и высоту с calc с тем же,
другим способом задайте ширину в%, и вместо высоты вы можете задать отступ в процентах, все они в одном предложении.
Ответ 7
Вот более общий способ сделать это для тех, кто не хочет копаться в коде OP и просто нуждается в решении адаптивных элементов с фиксированным соотношением с помощью CSS.
Основная идея заключается в том, что padding
в процентах рассчитывается на основе ширины элемента. Это означает, что padding-bottom: 100%
== element.width
(в данном случае квадрат). Мы можем использовать этот трюк, вычислив соотношение и используя его для заполнения.
Пример изображения
Изображения немного странные в том, что они уже имеют соотношение сторон, так что вы можете просто установить height: auto
и быть готовым к работе.
Соотношение: 4: 3
img {
--aspectRatio: calc(3/4 * 100%);
display:block;
width: 300px; // this one needs a width to work.
height:var(--aspectRatio);
}
<img src="https://images.unsplash.com/photo-1559666126-84f389727b9a" />
Ответ 8
PURE CSS FIX
Отрегулируйте ширину и высоту соответственно
footer {
display: flex;
width: 100vw;
align-items: center;
justify-content: center;
}
.responsive-box {
width: 33vw;
border: 1px solid blue;
max-width: 333px;
min-width: 35px;
flex-flow: row;
height: 60vh;
position: relative;
}
.responsive-box span {
position: absolute;
top:40%;
bottom:0;
left:0;
right:0;
text-align: center;
}
<footer>
<div class="responsive-box left"><span>left photo</span></div>
<div class="responsive-box center"><span>center photo</span></div>
<div class="responsive-box right"><span>right photo and more text</span></div>
</footer>