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

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

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


当前回答

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

其他回答

CSS对此有一个新的属性:aspect-ratio。

https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio

@supports(纵横比:1 / 1){ div { 纵横比:16 / 9; 背景颜色:橙色; } } <div style="width: 200px"></div> . <人力资源/ > <div style="width: 400px"></div> . <人力资源/ > <div style="height: 50px"></div> . <人力资源/ > <div style="height: 10px"></div> .

Chrome和Edge从V88开始完全支持它,Firefox从V81开始支持它(设置layout.css.aspect-ratio。在about:config中启用为true)。

兼容性信息请访问https://caniuse.com/mdn-css_properties_aspect-ratio

保持纵横比的一个简单方法,使用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 >

只是一个想法或黑客。

div { 背景颜色:蓝色; 宽度:10%; 过渡:底色0.5s,宽度0.5s; 字体大小:0; } div:{徘徊 宽度:20%; 背景颜色:红色; } img { 宽度:100%; 高度:汽车; 可见性:隐藏; } < div > <!—使用具有目标纵横比的图像。样本是一个正方形——> <img src="http://i.imgur.com/9OPnZNk.png" /> < / div >

这里是我的解决方案,以保持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上演示

您可以使用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%;" />