css 实现元素固定宽高比

4,136 阅读2分钟

看了几篇关于 css 实现元素固定宽高比的文章,在这里梳理一下,并谈一些自己的想法。

要固定宽高比,说明宽高是要有一定变化的(如果宽高值固定则按需要的比例设置即可),总的来说,固定元素宽高比根据元素分为两种情况,一种是元素为可替换元素,例如 <img><video> 等,另外一种就是普通元素。

1、可替换元素

可替换元素固定宽高比比较简单,他们本身就有像素高度和宽度的概念,设置 width 或者 height 为一个具体值,另一个属性设置为 auto 即可。

html:
<div class="imgWrap">
    <img src="./bg.jpg" alt="">
</div>

css:
.imgWrap {
    width: 30vw;
    height: auto;
    border: 1px solid #000;
}
.imgWrap img {
    width: 100%;
    /* 为了消除 img 元素底部留白 */
    vertical-align: bottom;
}

效果:

动画.gif

2、普通元素

当普通元素的宽高都未知时,不用 css 的话,我们可以想到使用 js 实时获取元素的 width 或者 height,然后按照比例计算另一个值,用 css 的话就得需要一点技巧,总的来说就是使用 padding 来撑大高度,代码如下:

html:
<div class="mainWrap">
    <div class="main"></div>
</div>

css:
.mainWrap {
    width: 20vw;
}
.main {
    width: 100%;
    padding-bottom: 75%;
    background: black;
}

效果:

动画.gif

好奇的你肯定想问凭什么用 padding-bottom 就可以实现这样的效果?初次见到这个操作的我同样惊呆了,于是我就立刻去查了一下 mdn,我们来看一下 mdn 上对 padding 值设为百分比表示的含义吧:

image.png

mdn 上说的很清楚,当内边距是一个百分比的时候,这个百分比是按照包含元素的宽度显示的,所以就会呈现出跟随宽度变化而固定宽高比的效果,同时也可以发现使用这个方法只能让高度跟随宽度值变化,而不能让宽度跟随高度而变化,因为百分比不能按照包含元素的高度来设置。

使用 padding 来撑大子元素的空间后,子元素里面是不能放其他内容的,如果我们想要放其他内容,可以设置该子元素的子元素为绝对定位,代码如下:

html:
<div class="mainWrap">
    <div class="main">
        <div class="content"></div>
    </div>
</div>

css:
.mainWrap {
    width: 20vw;
}
.main {
    width: 100%;
    padding-bottom: 75%;
    background: black;
    position: relative;
}
.content {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

除此之外,我们还可以使用一个更简单的方法,就是使用 aspect-ratio,这个 css 属性是专门用来设定固定宽高比的,不过使用的时候需要注意看一下浏览器的兼容性,传送门

参考链接:CSS如何实现固定宽高比?