我想创建一个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());
      }
}

其他回答

艾略特启发我想出了这个解决方案——谢谢:

png是一个完全透明的png文件,大小和你喜欢的纵横比一样,在我的例子中是30x10像素。

HTML

<div class="eyecatcher">
  <img src="/img/aspectratio.png"/>
</div>

CSS3

.eyecatcher img {
  width: 100%;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  background-image: url(../img/autoresized-picture.jpg);
}

请注意:background-size是css3特性,可能不适用于你的目标浏览器。你可以检查互操作性(f.e.在caniuse.com)。

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

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

2020解决方案-使用网格和填充伪元素

我找到了一些更新颖的方法来破案。该解决方案是any填充底部方法的后代,但没有任何位置:绝对子方法,只使用display: grid;和伪元素。

这里我们有。ratio::before,填充底部:XX%,网格区域:1 / 1 / 1 / 1;,这迫使伪元素保持在网格中的位置。虽然这里我们有width: 0;为了防止主元素被这个索引溢出(我们在这里冷地使用z-index,但是这个索引更短)。

我们的主元素。ratio > *:first-child与。ratio::之前的位置相同,即grid-area: 1 / 1 / 1 / 1;,因此它们共享相同的网格单元格位置。现在我们可以在div中放入任何内容,而pseudo元素是决定宽高比的元素。更多关于网格区域。

.ratio { 显示:网格; grid-template-columns: 1 fr; max-width: 200 px;例如,/*可以是100%,取决于父*/ } {前.ratio:: 内容:”; 宽度:0; 填充底:calc(100% / (16/9));/*在这里你可以放置任何比例*/ 网格面积:1 / 1 / 1 / 1; } .ratio > *:第一个孩子{ 网格面积:1 / 1 / 1 / 1;/*与*/前的::相同 背景:rgba(0,0,0,0.1);例如*/ } < div class = "比" > 16/9 < div > < / div > < / div >


虽然你可以使用cssval并使用样式属性将比值放在HTML中。工作与显示:内联网格以及。

.ratio { 显示:inline-grid; grid-template-columns: 1 fr; 宽度:200 px;例如,/*可以是100%,取决于父*/ margin-right: 10 px;例如*/ } {前.ratio:: 内容:”; 宽度:0; 填充底部:calc(100% / (var(—r)));/*在这里你可以放置任何比例*/ 网格面积:1 / 1 / 1 / 1; } .ratio > *:第一个孩子{ 网格面积:1 / 1 / 1 / 1;/*与*/前的::相同 背景:rgba(0,0,0,0.1);例如*/ } <div class="ratio" style="——r: 4/3;"> < div > 4/3 < / div > < / div > <div class="ratio" style="——r: 16/9;"> 16/9 < div > < / div > < / div >

我想分享我的解决方案,其中我有一个img-tag填充一定的纵横比。我不能使用背景,因为缺乏对CMS的支持,我不喜欢使用这样的样式标签:<img style="background:url(…)"/ >。此外,宽度为100%,因此不需要像某些解决方案那样设置为固定大小。它将响应伸缩!

.wrapper { 宽度:50%; } .image-container { 位置:相对; 宽度:100%; } {前.image-container:: 内容:“”; 显示:块; } .image-container img { 位置:绝对的; 上图:0; 左:0; 宽度:100%; 高度:100%; object-fit:封面; } {前.ratio-4-3:: padding-top: 75%; } {前.ratio-3-1:: 填充顶:calc(100% / 3); } {前.ratio-2-1:: padding-top: 50%; } <div class="wrapper"> <!——让事情变得小一点——> < p > 一个4:3宽高比的例子,由一个1:1比例的图像填充。 < / p > <div class="image-container ratio-4-3"> <!——让我们用4:3的长宽比——> <img src="https://placekitten.com/1000/1000/" alt="小猫!"/> < / div > < p > 只需在它周围放置其他块元素;它会工作得很好。 < / p > < / div >