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

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

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


当前回答

您可以使用svg。使容器/包装器的位置相对,首先将svg放置为静态定位,然后放置绝对定位的内容(顶部:0;左:0;右:0;底部:0,)

比例为16:9的例子:

Image.svg:(可以内联到src中)

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 9" width="16" height="9"/>

CSS:

.container {
  position: relative;
}
.content {
  position: absolute;
  top:0; left:0; right:0; bottom:0;
}

HTML:

<div class="container">
  <img style="width: 100%" src="image.svg" />
  <div class="content"></div>
</div>

注意,内联svg似乎不起作用,但你可以urlencode svg并将其嵌入到img src属性中,就像这样:

<img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%209%22%20width%3D%2216%22%20height%3D%229%22%2F%3E" style="width: 100%;" />

其他回答

这里是我的解决方案,以保持16:9纵横比在纵向或横向的div与可选的固定边距。

它是宽度/高度和最大宽度/最大高度属性与vw单位的组合。

在这个示例中,悬停时添加了50px的上下边距。

html { 高度:100%; } 身体{ 保证金:0; 高度:100%; } .container { 显示:flex; justify-content:中心; 对齐项目:中心; 高度:100%; } .fixedRatio { max-width: 100大众; Max-height: calc(9 / 16 * 100vw); 宽度:calc(16 / 9 * 100vh); 身高:100 vh; /*调试*/ 显示:flex; justify-content:中心; 对齐项目:中心; 背景颜色:蓝色; 字体大小:2快速眼动; 字体类型:“天线”; 颜色:白色; 过渡:宽度0.5s进出,高度0.5s进出; } .fixedRatio:{徘徊 宽度:calc(16 / 9 * (100vh - 100px)); 高度:calc(100vh - 100px); } < div class =“容器”> < div class = ' fixedRatio ' > 16:9 < / div > < / div >

在JSFiddle上演示

container {
   height: 100vh;
   width: 100vw;
}
.container div {
   height: 4em;
   width: 3em;
}

我是这样做的:

[data-aspect-ratio] {
    display: block;
    max-width: 100%;
    position: relative;
}

[data-aspect-ratio]:before {
    content: '';
    display: block;
}

[data-aspect-ratio] > * {
    display: block;
    height: 100%;
    left: 0;
    position: absolute;
    top: 0;
    width: 100%;
}
[data-aspect-ratio="3:1"]:before {
    padding-top: 33.33%;
}
[data-aspect-ratio="2:1"]:before {
    padding-top: 50%;
}
[data-aspect-ratio="16:9"]:before {
    padding-top: 56.25%;
}
[data-aspect-ratio="3:2"]:before {
    padding-top: 66.66%;
}
[data-aspect-ratio="4:3"]:before {
    padding-top: 75%;
}
[data-aspect-ratio="1:1"]:before {
    padding-top: 100%;
}
[data-aspect-ratio="3:4"]:before {
    padding-top: 133.33%;
}
[data-aspect-ratio="2:3"]:before {
    padding-top: 150%;
}
[data-aspect-ratio="9:16"]:before {
    padding-top: 177.77%;
}
[data-aspect-ratio="1:2"]:before {
    padding-top: 200%;
}
[data-aspect-ratio="1:3"]:before {
    padding-top: 300%;
}

例如:

<div data-aspect-ratio="16:9"><iframe ...></iframe></div>

在Angular中,我添加了一个处理纵横比的指令。

import { AfterViewInit, Directive, ElementRef, Input, Renderer2 } from 
"@angular/core";
import { debounceTime, fromEvent, Subject, takeUntil } from "rxjs";
 
// Auto sets the height of element based on width. Also supports window resize
@Directive({
    selector: '[aspectRatio]'
})
export class AspectRatioDirective implements AfterViewInit {
    @Input() aspectRatio?: number; // example 9/16

    private readonly onDestroy$ = new Subject<void>();

    constructor(private element: ElementRef, private renderer: Renderer2) {}

    public ngAfterViewInit(): void {
        this.setDimensions();
        this.initResizeListeners();
    }

    public ngOnDestroy(): void {
        this.onDestroy$.next();
        this.onDestroy$.complete();
      }

    private setDimensions(): void {
        if (!this.aspectRatio) { return; }
        const width = this.element.nativeElement.clientWidth;
        this.renderer.setStyle(this.element.nativeElement, 'height', `${width * this.aspectRatio}px`);
    }

    private initResizeListeners(): void {
        fromEvent(window, 'resize')
          .pipe(debounceTime(100), takeUntil(this.onDestroy$))
          .subscribe(() => this.setDimensions());
      }
}

我刚刚创建了一个2:1的div,调整大小以占据全宽度,但如果它会导致顶部或底部超过,则会缩小宽度。但是请注意,这只适用于窗口的大小,而不是父窗口的大小。

#scene {
    position: relative;
    top: 50vh;
    left: 50vw;
    width: 100vw;
    height: 50vw;
    max-height: 100vh;
    max-width: calc(100vh * 2);
    transform: translate(-50%, -50%);
}

我相信你可以计算出正确的%,用于4:3而不是2:1。