我想创建一个div,它可以随着窗口宽度的变化而改变宽度/高度。
是否有任何CSS3规则允许高度根据宽度变化,同时保持其纵横比?
我知道我可以通过JavaScript做到这一点,但我更喜欢只使用CSS。
我想创建一个div,它可以随着窗口宽度的变化而改变宽度/高度。
是否有任何CSS3规则允许高度根据宽度变化,同时保持其纵横比?
我知道我可以通过JavaScript做到这一点,但我更喜欢只使用CSS。
当前回答
我偶然发现了这个问题的聪明解决方案,使用<svg>和display:grid。
一个display:grid元素允许您使用相同的网格区域,与它的两个(或更多)子元素占据相同的空间。 这意味着它们都是流内容,重叠在一起,并且高的那个设定了比例。
其中之一是负责设置比率的<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;
}
将<svg>的比率设置为您想要的任何值:
<svg viewBox="0 0 4 3"></svg> . <svg viewBox="0 0 16 9"></svg> .
.ratio { 显示:网格; } .ratio > * { 网格:1/1; } /*下面的代码不需要设置比例 我只是想在视觉上做个标记 *和中心内容 * / .ratio div { 边框:1px纯红色; 显示:flex; 对齐项目:中心; justify-content:中心; } < div class = "比" > <svg viewBox="0 0 7 1"></svg> . < div > 固定比例7:1 < / div > < / div >
如果你需要一个解决方案,其中内容元素有更多的内容,你想要限制在一个滚动区域与期望的比例,设置位置:相对的父位置:绝对;高度:100%;overflow-y:汽车;在内容上,允许流内容元素(<svg>)设置大小,因此设置比率。
.ratio { 显示:网格; 位置:相对; } .ratio > * { 网格:1/1; } .ratio > div { 高度:100%; overflow-y:汽车; 位置:绝对的; /*其余部分不需要*/ 边框:1px纯红色; 填充物:0 1rem; } < div class = "比" > <svg viewBox="0 0 7 2"></svg> . < div > <h1>固定比例7:2</h1> <p>痛苦的痛苦,神圣的解脱,痛苦的痛苦和巨大的痛苦。一个永恒的灵魂。扫描光晕直径,坐与nisl,疑,adipiscisbendum。一个永远的主人,一个生命的时刻,一个心灵的灵魂。Morbi enim nunc faucibus一个漂亮的坐遇见porttitor。Arcu odio ut sem nulla。在分娩的过程中。克拉巧合的叶状裂片,在augue eget。老爷子和老爷子坐着。我不知道你在说什么。狮子座,在生命的turpis massa, tempus element, estestas。est整数eget aliquet nibh。多洛尔与神圣的精英们会面。 <p>但aliquam purus sit meet。Eget magna fermentum iaculis eu non diam phasellus vestibulum。这是我的命运,我的命运。剥夺权利,剥夺权利,剥夺生命。移动门,非枕边边,老窝悬挂。在tellus在urna condimentum mattis pellentesque。圣歌,圣歌,圣歌。这是一种很好的方法。皮朗式的夹缝。Velit euismod in pellentesque massa placerat duis。这是我的生命。 <p>Mauris a diam maecenas sed enim ut sem。在怀孕的过程中。我的格言是我的,我的灵魂是我的。Urna porttitor rhoncus dolus purus non enim present。下丘脑大炎,下丘脑大炎。生命之箭,狮子座之箭。对车辆的不作为权,对生命的不作为权。Volutpat odio facilisis mauris sit amet massa vitae tortorcondimentum。Aliquam purus sit at the luctus venenatis lectus magna。坐下来,感受孕妇的痛苦。Enim eu turpis eggestas pretium aenean。不可预知的后果。在怀孕初期,永远没有生气。言归正传。Blandit massa enim nec dui nunc mattis enim ut。 < / div > < / div >
正如@emjay在下面的评论中指出的那样,ratio svg可以放在父元素的一个伪元素中,只要它被正确编码:
.three-squares { 显示:网格; 边框:1px纯红色; } .three-squares > *, .three-squares:before { 网格:1/1; } .three-squares:{之前 content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 3 1'%3E%3C/svg%3E"); 行高:0; } < div class = "抢走”> < div >我3:1 < / div > < / div >
当在伪元素中使用时,<svg>成为一个替换的元素,默认情况下,它位于可变高度的基线上(Chrome中为4px, Firefox中为3.5px)。基线的高度根据行高而变化,这就是为什么我们需要在pseudo上设置line-height: 0以获得准确的比率。详情请点击这里。
我个人更喜欢将<svg>放在标记中的版本,因为我可以用一个类(.ratio)处理各种比率的容器(而不是为我可能需要的每个比率使用一个类)。
其他回答
2022解决方案-使用CSS的纵横比属性
<div class='demo'></div>
.demo {
background: black;
width: 500px;
aspect-ratio: 4/3;
}
更新:现在所有常绿浏览器都支持这个解决方案
2021年更新- CSS纵横比属性
我们最近获得了在CSS中使用长宽比属性的能力。
https://twitter.com/Una/status/1260980901934137345/photo/1
注意:支持还不是最好的…
注意:支持是相当体面的!
https://caniuse.com/#search=aspect-ratio
编辑:长宽比现在可用!
https://web.dev/aspect-ratio/
如果你对如何使用它感兴趣,可以看看下面这个超级简单的例子
.yourClass {
aspect-ratio: 4/3;
}
我遇到过这个问题很多次,所以我为它做了一个JS解决方案。这基本上是根据你指定的元素宽度比例来调整domElement的高度。你可以这样使用它:
<格比=“4x3”></div>
请注意,因为它正在设置元素的高度,元素应该是一个display:block或display:inline-block。
https://github.com/JeffreyArts/html-ratio-component
为了补充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;
}
我最近使用了类似于Elliot的图像技巧,允许我使用CSS媒体查询来根据设备分辨率提供不同的logo文件,但仍然按照<img>自然会做的比例缩放(我将logo作为背景图像设置为具有正确纵横比的透明。png)。但是Web_Designer的解决方案将为我节省一个http请求。
实际上,高投票的答案是一个非常好的解决方案,但有一个新的CSS功能,名字是长宽比。
它可以这样使用:
.someClass {
width: 100%;
aspect-ratio: 4/3;
}
自动确定高度,但请参见兼容性表:
如果浏览器支持对你的项目很重要,不要使用它。使用填充底技术。