我想创建一个div,它可以随着窗口宽度的变化而改变宽度/高度。

是否有任何CSS3规则允许高度根据宽度变化,同时保持其纵横比?

我知道我可以通过JavaScript做到这一点,但我更喜欢只使用CSS。


当前回答

根据你的解决方案,我做了一些技巧:

当您使用它时,您的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;
}

jQuery和jQuery

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

有了这个,你只需要设置attr data-keep-ratio到高/宽,就这样。

其他回答

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;
    }

我偶然发现了这个问题的聪明解决方案,使用<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)处理各种比率的容器(而不是为我可能需要的每个比率使用一个类)。

正如w3schools.com网站上所述,并在这个公认的答案中有所重申,填充值为百分比(重点是我的):

以包含元素宽度的百分比指定填充

因此,一个保持16:9纵横比的响应式DIV的正确示例如下:

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上演示

艾略特启发我想出了这个解决方案——谢谢:

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特性,可能不适用于你的目标浏览器。你可以检查互操作性(f.e.在caniuse.com)。

保持纵横比的一个简单方法,使用canvas元素。

尝试调整下面的div的大小,看看它的作用。

对我来说,这种方法效果最好,所以我把它分享给其他人,这样他们也能从中受益。

.cont { 边框:5px纯蓝色; 位置:相对; 宽度:300 px; 填充:0; 保证金:5 px; 调整:水平; 溢出:隐藏; } .ratio { 宽度:100%; 保证金:0; 显示:块; } .content { Background-color: rgba(255, 0,0, 0.5); 位置:绝对的; 上图:0; 左:0; 宽度:100%; 高度:100%; 保证金:0; } < div class = "跟" > <canvas class="ratio" width="16" height="9"></canvas> <div class="content">我是16:9</div> < / div >

也适用于动态高度!

.cont { 边框:5px纯蓝色; 位置:相对; 身高:170 px; 填充:0; 保证金:5 px; 调整:垂直; 溢出:隐藏; 显示:inline-block;/*所以div不会自动扩展到最大宽度*/ } .ratio { 高度:100%; 保证金:0; 显示:块; } .content { Background-color: rgba(255, 0,0, 0.5); 位置:绝对的; 上图:0; 左:0; 宽度:100%; 高度:100%; 保证金:0; } < div class = "跟" > <canvas class="ratio" width="16" height="9"></canvas> <div class="content">我是16:9</div> < / div >