根据宽度计算div的高度并保持比例[重复]
Posted
技术标签:
【中文标题】根据宽度计算div的高度并保持比例[重复]【英文标题】:Calculate height of div based off width & maintain proportion [duplicate] 【发布时间】:2019-10-11 20:24:52 【问题描述】:我正在寻找一个纯 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>
这是一支笔,展示了我拥有的东西。 https://codepen.io/nom3d/pen/arGpBV
这是一个显示调整大小时效果的 gif。请注意背景图像保持成比例,文本保持居中。
还想知道是否仅使用 CSS 是不可能的,如何使用 plain javascript 做到这一点,我需要将 id 添加到我的 div 中吗?
更新:这是一个简单的 javascript 函数来处理这个任务
function setHeight(el,val)
var box = document.querySelectorAll(el);
var i;
for(i = 0;i < box.length;i++)
var width = box[i].offsetWidth;
var height = width * val;
box[i].style.height = height + 'px';
// set your element to target and the ratio value
setHeight('footer div',.75);
window.onresize = function(event)
setHeight('footer div',.75);
;
【问题讨论】:
仅使用 css 是不可能的,您可能可以将calc
与 height: calc((1000px / 3) * .75)
之类的公式一起用于 footer
但是当您调整窗口大小时它无济于事,只有js 将能够在调整大小并将高度设置为3/4
的比例时捕获调整大小事件并计算每个像素
确实如此。没有 CSS 唯一的解决方案来解决这个问题。但是,如果您想编写更少的 JS,我相信您可以使用@Towkir 建议的公式来实现这一点,但您可以使用使用 JS 更新的 CSS 变量而不是 1000px
。
@The24thDS 一个纯粹的CSS
解决方案是通过添加 5 行代码并为您提供所需的纵横比。
@Towkir 使用calc
不会使它成为纯粹的CSS
解决方案吗?
@PeterDarmis 是的,calc
是一个纯 CSS 解决方案
【参考方案1】:
你试过了吗
footer div
height: 20vw;
还有 css 的 calc 属性可能会有所帮助
https://developer.mozilla.org/en-US/docs/Web/CSS/calc
【讨论】:
我相信如果这个浏览器高度改变,这将不会保持比例。此外,calc() 无法根据同一元素的宽度确定高度。【参考方案2】:你可以简单地考虑维护the aspect ratio using padding.的基本技巧
这是一个示例,我保留了两个示例,以便您进行比较,一个使用 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>
【讨论】:
您介意在 FOOTER:not(.no-padd) DIV:before 行添加评论吗?我相信这将有助于理解答案。谢谢! @drooh 这一行是一个简单的选择器,仅将逻辑应用于最后一个 fooer。我添加了两个页脚,一个带有 jquery(你的)和一个带有 CSS(我的)所以我只选择带有类 no-padd 的页脚来应用逻辑......我只是从我已经链接的问题中得到了答案[由于有赏金,我无法关闭重复项,因此我将其作为社区答案]【参考方案3】:在 CSS 中维护特定的高宽比通常是通过利用填充百分比总是计算based on the element's width这一事实来完成的。
例如,假设您有一个包含width: 500px
、height: 300px
和padding: 10%
的元素。现在你可能会期望顶部和底部的填充是height
的 10%,左右填充是 width
的 10%。然而,这会产生不相等的垂直和水平填充,这与预期的相反 - 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>
【讨论】:
使用 css flex 显示属性。检查此 URL 以获取更多详细信息。 developer.mozilla.org/en-US/docs/Web/CSS/flex 根据我的经验,这是最简单、最适用的解决方案。顺便说一句,它也可以应用于视频以保持 HTML5<video>
标签中内容的纵横比。【参考方案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】:可能有点晚了,但也会添加我的解决方案。
我认为我应该将其保留为通用解决方案,因此我决定不使用您的页脚类。但我相信你会成功的。
在我看来,最简单的方法是使用填充计算来获得一个固定的比率和一些 div。
-
弹性容器
Flex 项目(带有内边距):此容器用于保持分辨率。它的填充量取决于项目的宽度。
例如:项目宽度 = 100% --> 填充 = (100/4)*3 --> 75% 填充
Flex-Item 内的内容容器,您可以在其中放置您的东西
内容容器内的背景-Div
把你需要的所有东西都作为同级元素放到 background-div 中
这里有一个小玩意儿,一些 cmets 在代码中: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's 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's just to demonstrate that it's 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's 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's 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>
您可以直接使用给定的代码,用于制作proposal宽度高度,您有2种不同的方式,下面给出其中一种,您可以使用百分比宽度和高度与计算相同,
另一种方法是用 % 表示宽度,而不是高度,您可以用百分比给出 padding-bottom,所有这些都是相同的。
【讨论】:
【参考方案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" />
图片背景
但是假设您希望容器管理大小而不考虑原始内容比例?只需使用背景图片。
这个是 16:9(典型的宽屏)
.fixedAspect
--aspectRatio: calc(9/16 * 100%);
height: 0;
padding-bottom: var(--aspectRatio);
background-size: cover;
background-position: center center;
<div class="fixedAspect" style="background-image: url(https://images.unsplash.com/photo-1559662780-c3bab6f7e00b)"></div>
带有内容的 HTML 元素
使用height:0
和一堆填充向元素添加内容可能不是最好的解决方案。但是我们可以通过使用伪类来解决这个问题。强制“最小高度”。
奖励:如果您的内容大于您定义的 position: absolute;
包装器的纵横比,这不会中断。
.fixedAspect
margin: 20px;
background-color: #f6f3f0;
p
font-family: Helvetica, Arial, Sans-Serif;
padding: 10px;
.fixedAspect:before
--aspectRatio: calc(5/20 * 100%);
content: "";
height:0;
padding-top: var(--aspectRatio);
/* so you can see the element */
background-color: #F47E20;
/* get this out of the way */
float: left;
width: 1px;
margin-left:-1px;
.fixedAspect:after
/* we need to clear the float so its container respects height */
content: "";
display: table;
clear: both;
<div class="fixedAspect">
<p>My default size is a ratio of 20:5 but I'll grow if there's too much content.</p>
</div>
【讨论】:
【参考方案8】:纯 CSS 修复
相应地调整宽度和高度
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>
【讨论】:
以上是关于根据宽度计算div的高度并保持比例[重复]的主要内容,如果未能解决你的问题,请参考以下文章