在日常开发过程中,有一些前端业务场景可能需要让元素在尺寸变化的同时,保证宽高比不变,所以在此记录一下具体的实现方法和应用场景。
其实关于实现元素的固定宽高比,思路很简单,就是在于找到设置宽高的一个固定基准。关于这个基准是什么,我们其实可以很容易的找到。
其实,最先能够联想到的是图片元素它本身的等比缩放特性,通过固定一边,讲另一边设置为auto
,就能轻易的实现,但是这种方式有很多局限性,运用到实际复杂的业务布局会有很多短板,所以不推荐,文中也不再赘述。
主要介绍的是下面两种思路
相对于视口的宽度,视口被均分为100单位的vw
vw,vh是css3新加的属性,目前兼容性还是不错的, 是基于视口的长度单位,即使父元素没有设定高度,也依然能够获取到。
通过这个基准,我们在进行布局的时候,将宽高都基于这个单位来设置,就能很容易的实现宽高等比缩放的效果。
代码如下:
<!--假设我们盒子的宽高比固定是2:1-->
.box1{
width: 20vw;
height: 10vw;
background-color:aquamarine;
}
但由于我们实际开发的应用场景大多都不是基于整个视口来布局,会有侧边栏,或是一些其他的元素,使得实际我们的布局的盒子只是占整个视口的一部分,所以在将设计师给到的设计图转换成vw布局时,需要进行一些计算,虽然都是一些简单的计算,但也是增加了开发成本。所以相比来说,我更推荐下面一种方法。
根据这个特性也能够很容易的实现效果
margin 和 padding 的百分比设置都是基于父元素的百分比,可以举一反三,根据实际情况,灵活的使用
.box2{
width: 20%;
height: 0;
padding-top: 10%;
background-color: brown;
}
以上两种可以实现同样的效果,如下:
掌握了基本原理后,就到了应用阶段,可以通过下面一个示例,来检验一下实际应用的效果
如下图:一个常规的页面,头+侧边导航栏+内容区域(自适应宽度),现在的需求是:右侧列表一行固定排列三个,依次往下排,每个item可以随右侧宽度的变化而等比缩放。
这里再将item细分成两种布局形式,分别是下面的方案一和方案二
这种方案相对较简单,主要就是设置item的固定宽高,再在盒子里增加其他元素即可,直接代码:
<!--这里的盒子宽高比我们假设为3:1-->
// css
.item{
width: 33%;//因为每行显示三个,所以设置宽度为33%,剩下的1%作为间距
height: 0;
padding-top: 11%;//比例为3:1,根据宽度可以计算出高度为11%
margin-right: 0.5%;
margin-bottom: 0.5%;
box-sizing: border-box;
border: 1px solid #999999;
position: relative;
}
.item:nth-child(3n){
margin-right: 0;
}
// 因为item的高度是被padding撑起来的,所以内部的布局需要通过绝对定位,增加一个盒子来盛放
.itemInner{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: url('./images/testpic01.jpg') center center no-repeat;
background-size: cover;
display: flex;
flex-direction: column-reverse;
}
.innerTxt{
margin: 0;
padding: 0 20px;
font-size: 14px;
line-height: 2;
color: #333;
background-color: rgba(255, 255, 255, 0.8);
}
// html
<div class="testMain">
<div class="item">
<div class="itemInner">
<p class="innerTxt">这是一段测试标题</p>
</div>
</div>
<div class="item">
<div class="itemInner">
<p class="innerTxt">这是一段测试标题</p>
</div>
</div>
...
</div>
效果如下:
这种方案就是需要稍微做一些变通
方案说明:盒子本身是宽度自适应的,但高度需要根据内部的图片变化来响应,假设图片的宽高比是4:3
代码如下:
// css
.item2{//这一部分不需要设置宽高比,只要设置好宽度,高度可以让其根据内部图片高度自适应
width: 33%;
margin-right: 0.5%;
margin-bottom: 0.5%;
box-sizing: border-box;
border: 1px solid #999999;
position: relative;
}
.item2:nth-child(3n){
margin-right: 0;
}
.item2Inner{
padding: 12px;
display: flex;
}
// 图片元素再根据上面的方法进行固定宽高比设置
.item2Inner-pic{
width: 40%;
height: 0;
padding-top: 30%;
background: url('./images/testpic01.jpg') center center no-repeat;
background-size: cover;
flex-shrink: 0;
}
.item2Inner-main{
flex: 1;
margin-left: 10px;
}
.item2Inner-main-title{
font-size: 14px;
color: #333;
line-height: 2;
}
.item2Inner-main-txt{
font-size: 12px;
color: #666;
line-height: 2;
}
// html
<div class="testMain">
<div class="item2">
<div class="item2Inner">
<div class="item2Inner-pic"></div>
<div class="item2Inner-main">
<p class="item2Inner-main-title">标题</p>
<p class="item2Inner-main-txt">这是一段测试文字</p>
</div>
</div>
</div>
<div class="item2">
<div class="item2Inner">
<div class="item2Inner-pic"></div>
<div class="item2Inner-main">
<p class="item2Inner-main-title">标题</p>
<p class="item2Inner-main-txt">这是一段测试文字</p>
</div>
</div>
</div>
...
</div>
效果如下:
以上两种方案完整代码可点击 ☞ 这里 查看
以上就是关于CSS实现固定宽高比响应式布局的全部内容了,如果还有其他方案,或是文中有分析不正确的地方,可以评论跟我交流哦~