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

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

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


当前回答

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

.squares{
  width: 30vw
  height: 30vw

与主纵横比

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

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

其他回答

由于@web-tiki已经展示了一种使用vh/vw的方法,我还需要一种方法在屏幕中心,这里是9:16人像的代码片段。

.container {
  width: 100vw;
  height: calc(100vw * 16 / 9);
  transform: translateY(calc((100vw * 16 / 9 - 100vh) / -2));
}

translateY会保持这个中心在屏幕上。Calc (100vw * 16 / 9)预计高度为9/16。(100vw * 16 / 9 - 100vh)为溢流高度,因此,拉升溢流高度/2将使其保持在屏幕中心。

为风景,并保持16:9,你显示使用

.container {
  width: 100vw;
  height: calc(100vw * 9 / 16);
  transform: translateY(calc((100vw * 9 / 16 - 100vh) / -2));
}

9/16的比例很容易改变,不需要预定义100:56.25或100:75。如果你想先保证高度,你应该切换宽度和高度,例如:高度:100vh;宽度:calc(100vh * 9 / 16) 9:16纵向。

如果你想适应不同的屏幕尺寸,你可能也会感兴趣

background-size封面/包含 上面的样式类似于包含,取决于宽高比。 object-fit img/video标签的封面/包含 @media(朝向:纵向)/@media(朝向:横向) 媒体查询肖像/风景改变比例。

在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());
      }
}

虽然大多数答案都很酷,但大多数都要求已经正确大小的图像……其他解决方案只适用于宽度,而不关心可用的高度,但有时您也希望将内容适应于特定的高度。

我试图将它们组合在一起,以带来一个完全可移植和可调整大小的解决方案……诀窍是使用自动缩放图像,但使用内联svg元素,而不是使用预渲染的图像或任何形式的第二个HTTP请求…

div.holder { 背景颜色:红色; 显示:inline-block; 身高:100 px; 宽度:400 px; } svg img { 背景颜色:蓝色; 显示:块; 高度:汽车; 宽度:汽车; max-width: 100%; max-height: 100%; } .content_sizer { 位置:相对; 显示:inline-block; 高度:100%; } .content { 位置:绝对的; 上图:0; 底部:0; 左:0; 右:0; background - color: rgba(155255年,0,0.5); } < div class = "架" > < div class = " content_sizer”> <svg width=10000 height=5000 /> < div class = "内容" > < / div > < / div > < / div >

请注意,我在SVG的width和height属性中使用了较大的值,因为它需要大于预期的最大大小,因为它只能缩小。这个例子使div的比例为10:5

如果你想在纵向视图或横向视图的视口中放置一个正方形(尽可能大,但没有任何东西粘在外面),在纵向/横向方向上切换使用vw/vh:

@media (orientation:portrait ) {
  .square {
    width :100vw;
    height:100vw;
  }
} 
@media (orientation:landscape) {
  .square {
    width :100vh;
    height:100vh;
  }
} 

实际上,高投票的答案是一个非常好的解决方案,但有一个新的CSS功能,名字是长宽比。

它可以这样使用:

.someClass {
  width: 100%;
  aspect-ratio: 4/3;
}

自动确定高度,但请参见兼容性表:

如果浏览器支持对你的项目很重要,不要使用它。使用填充底技术。