CSS实现宽高等比例自适应矩形

20,663 阅读2分钟

更新

现在可以直接使用aspect-ratio来设置元素的宽高比,不需要在使用padding来进行模拟实现了。

兼容性如下 image.png

桌面端和安卓目前的兼容性还是比较不错的,不过ios上使用仍需要注意。

可以使用渐进增强的策略来使用他:

.responsive-box {
  width: 50%;
  padding-top: 25%; /* 16:9 */
  background-color: lightblue;
  position: relative;
}

/* 在支持的浏览器上使用aspect-ratio */
@supports (aspect-ratio: 16 / 9) {
  .responsive-box {
    padding-top: 0;
    aspect-ratio: 16 / 9;
  }
}

虽然@supports的支持度也只比aspect-ratio好一丢丢,不过这并不影响我们的渐进增强的策略。

image.png


以下为原内容

概述

今天遇到一个很有趣的问题:「如何实现一个宽度自适应,高度为宽度的一半的矩形」

经过搜索引擎的筛选和自己的反复试验,发现使用padding-bottom是最完美的解决方案。

解决方案

首先我们要明白,padding-top/bottommargin-top/bottom都是相对于父元素的宽度来计算的,我们可以利用这一属性来实现我们的需求。

代码如下:

<div class="scale"></div>

解释
.scale {
  width: 100%;
  height: 0;
  padding-bottom: 50%;
}

解释

这其中的关键点就是height: 0;padding-bottom: 50%;

我们将元素的高度由padding撑开,由于padding是根据父元素宽度计算的,所以高度也就变成了相对父元素宽度,同时要将height设置为 0,这是为了将元素高度完全交给padding负责。

最后padding-bottom的值设为width的值一半,就可以实现高度是宽度的一半且自适应啦。

改进

光是这样写还是不够的,因为元素的height为 0,导致该元素里面再有子元素的时候,就无法正常设置高度。所以我们需要用到position: absolute;。代码如下:

<div class="scale">
    <div class="item">
        这里是所有子元素的容器
    </div>
</div>

解释
.scale {
  width: 100%;
  padding-bottom: 56.25%;
  height: 0;
  position: relative; //
}

.item {
  width: 100%;
  height: 100%;
  background-color: aquamarine;
  position: absolute; //
}

解释

继续改进

解决了子元素的问题,那么我们再来看看元素本身。由于我们一开始的需求是宽高比 2:1,这种比较好实现,但是后来需求又想要 16:9 的宽高比,而且宽度不是 100%,那这样计算 padding-bottom的时候就很麻烦了。如何解决呢?

这时候我们需要在外层再套一个父元素,将宽度的控制交给这个父元素来做。

代码如下:

<body>
    <div class="box">
        <div class="scale">
            <div class="item">
                item
            </div>
        </div>
    </div>
</body>

解释
/* box 用来控制宽度 */
.box {
  width: 80%;
}
/* scale 用来实现宽高等比例 */
.scale {
  width: 100%;
  padding-bottom: 56.25%;
  height: 0;
  position: relative;
}
/* item 用来放置全部的子元素 */
.item {
  width: 100%;
  height: 100%;
  background-color: aquamarine;
  position: absolute;
}

如此,就可以完美解决。