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

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

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


当前回答

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

.squares{
  width: 30vw
  height: 30vw

与主纵横比

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

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

其他回答

我想只是使用rem或em应该解决固定比例的问题,但不会像vw或vh那样难以绑定到屏幕上,或者像%那样痛苦地使用flexbox。好吧,没有一个答案适合我,在我的情况下,这对我来说很重要:

<div class="container">
   <div>
   </div>
</div>
.container {
   height: 100vh;
   width: 100vw;
}
.container div {
   height: 4em;
   width: 3em;
}

或者用rem,但是不管怎样,它们中的任何一个都可以。 Rem使用默认的字体大小值,而em使用最接近的字体大小。

我刚刚创建了一个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。

您可以通过使用SVG来实现这一点。

这要视情况而定,但在某些情况下它真的很有用。举个例子,你可以设置background-image而不设置固定的高度,或者用它来嵌入youtube <iframe>,比例为16:9,位置:绝对等。

对于3:2的比例设置viewBox="0 0 3 2"等等。

例子:

div { 背景颜色:红色 } svg { 宽度:100%; 显示:块; 可见性:隐藏 } .demo-1{宽度:35%} .demo-2{宽度:20%} < div class = " demo-1”> <svg viewBox="0 0 3 2"></svg> . < / div > <人力资源> < div class = " demo-2”> <svg viewBox="0 0 3 2"></svg> . < / 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());
      }
}

我们是这样解决的:

.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/