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

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

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


当前回答

Chrome 88的新特性是CSS的宽宽比属性,其他浏览器也很快会加入。

纵横比CSS属性为盒子设置了一个优先的纵横比,它将用于自动大小的计算和一些其他的布局功能。

CSS技巧文章

更多的信息

div { 背景:rebeccapurple; 身高:100 px; 保证金:1 em汽车; } .square { 纵横比:1 / 1; } < div class = "广场”> < / div >

其他回答

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

我使用了一个新的解决方案。

.squares{
  width: 30vw
  height: 30vw

与主纵横比

.aspect-ratio
  width: 10vw
  height: 10vh

然而,这是相对于整个视口而言的。所以,如果你需要一个div是视口宽度的30%,你可以使用30vw代替,因为你知道宽度,你可以使用calc和vw单位在高度上重用它们。

新的纵横比标签会很棒,但它打乱了我的divs的定位。 填充包装器div的传统解决方案是有效的,但只能根据父类或视口的宽度调整大小,当高度是限制因素时,这就产生了问题。

我发现min()函数非常有用,并调整了传统的方法,如下所示:

身体{ background-image: linear-gradient(到右上,#FFE6B5, #B3CEBF); 填充:0; 保证金:0自动; overflow-y:隐藏;/*这是为了避免在视口高度小于纵横比要求*/时滚动 } .wrapper { 位置:相对; 宽度:100大众; max-height: 100 vh; } .sixteen-by-nine。宽高比{ 衬底:56.25% /* 9:16比*/ } .content { 位置:绝对的; 上图:0;底部:0;左:0;右:0; 背景颜色:绿色 } .centered { 位置:绝对的; 左:50%; 上图:50%; 转换:翻译(-50%,-50%); 高度:100%; 宽度:min(177.8vh, 100%);/*这总是在视口中保持16:9的比例*/ 字体大小:最小(1.7 3 vh,大众);/*如果你也对缩放字体大小*/感兴趣 背景颜色:蓝色 } 身体< > < div class = "包装" > <div class=" 16x9纵横比"></div> <div class="content" > < div class = "集中" > <!——东西在这里——> < / div > < / div > < / div > 身体< / >

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

我们是这样解决的:

.square {
  width: 100%;
  max-height: 100%;
  aspect-ratio: 1;
  background: red;
  position: relative;
  margin: auto;
  top: 50%;
  transform: translateY(-50%);
}

参见https://jsfiddle.net/r1jL3oqa/1/