屏霸秘籍:一招锁定完美宽高比,告别带鱼屏乱码时代!
前几天做了一个大屏项目。既然是大屏,就不可避免的需要考虑到自适应问题。常见的基于 rem 的布局方式有一个天然的缺陷。那就是 rem 基于屏幕宽度变化而非高度。这就带来一个问题,那就是在一些奇葩的屏幕,比如带鱼屏上展示的时候样式可能会乱掉。
为此,我们必须保证长宽比是固定的,而不是简单的将高度方向上的尺寸也处理成 rem 单位。那么如何能够保证 div 元素的长宽比呢?本文就介绍两个方法,一个是传统做法,一个是使用比较新的 CSS 属性。喜欢的朋友们快收藏起来吧~
1. 传统方式
使用传统的方式保证 div 的长宽比的原理在于:padding-top 或者 padding-bottom 的计算基准是父元素的宽度而不是高度;因此可以采用这样的策略:
- 给父元素宽度值,然后让其子元素的宽度值为 100% ,并让其竖直方向上的 padding 为 60% 。
- 注意这个子元素的作用是将父元素撑起来,并不是在这一层写具有意义的内容,因此给其高度为 0 并且将 position 设置成 relative。
- 而孙子元素才是真正写内容的容器,为了让孙子元素有一个预设的尺寸,因此设置其 position 值为 absolute 并设置 inset 的值为 0。
简单记一下就是,一共是三层:最外层提供宽度;中间层撑开最外层并保证长宽比;最内层占据整个撑开空间并作为内容的容器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.item{
background:red;
width:50%;
margin:0 auto;
}
.inner{
width:100%;
height:0;
padding-bottom: 60%;
position: relative;
}
.container{
position: absolute;
inset:0;
background: grey;
}
</style>
</head>
<body>
<div class="item">
<div class="inner">
<di class="container"></di>
</div>
</div>
</body>
</html>
上面这段代码通过CSS创建了一个保持特定长宽比的容器。以下是代码中各个部分的作用和保持长宽比的原理:
HTML结构
.item
类的<div>
是外层容器。.inner
类的<div>
是用于保持长宽比的内层容器。.container
类的<di>
(这里应该是一个打字错误,正确的是<div>
)是实际的内容容器。
CSS样式
-
.item
:background:red;
设置了外层容器的背景颜色为红色。width:50%;
使外层容器的宽度为父容器宽度的50%,这意味着它可以适应父容器的大小。margin:0 auto;
使外层容器水平居中。
-
.inner
:width:100%;
使内层容器的宽度填满其父容器(即.item
)的宽度。height:0;
设置内层容器的高度为0,这是关键,因为实际的“高度”将由padding-bottom
决定。padding-bottom: 60%;
这是保持长宽比的关键。padding-bottom
的百分比是相对于其父容器的宽度。因此,如果父容器宽度为100%,那么padding-bottom
将会是宽度的60%,这样就形成了一个宽高比为 100:60 (或简化为 5:3) 的矩形区域。position: relative;
设置了内层容器的定位为相对定位,这样其子元素可以相对于它进行定位。
-
.container
:position: absolute;
使内容容器脱离文档流,并可以相对于其最近的相对定位的祖先元素(即.inner
)进行定位。inset:0;
是一个CSS函数,将元素的top
,right
,bottom
,left
属性都设置为0,使.container
完全填充其父容器.inner
的边界。background: grey;
设置了内容容器的背景颜色为灰色。
注意!上述代码中的 inset:0;
等价于:top: 0; right: 0; bottom: 0; left: 0;
长宽比保持原理
长宽比的保持依赖于 .inner
容器的 padding-bottom
百分比。这个百分比是基于父容器宽度的,因此无论 .item
容器的宽度如何变化,.inner
的 padding-bottom
都会按照设定的百分比来调整其高度,从而保持长宽比不变。
在这个例子中,长宽比是5:3,因为 padding-bottom
设置为60%,意味着高度是宽度的60%,可以通过以下比例计算得出:
这种方法的优点是兼容性好,哪个浏览器不支持 padding 呢?缺点就是需要用到多层 div。
2. 使用 CSS 新属性
可以看出来,使用传统的方式实现固定的长宽比是比较繁琐的。好在 CSS 提供了一个名为 aspect-radio 的属性,可以让我们只使用一层 div 完成固定的长宽比。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.aspect-ratio-box-aspect-ratio {
width: 50%; /* 可以根据需要设置宽度 */
aspect-ratio: 16 / 9; /* 设置宽高比为16:9 */
background: lightcoral;
overflow: hidden;
}
.aspect-ratio-box-aspect-ratio .content {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
</style>
</head>
<body>
<div class="aspect-ratio-box-aspect-ratio">
<div class="content">
内容可以是图片、视频或其他元素
</div>
</div>
</body>
</html>
原理:aspect-ratio
属性是CSS的一个新特性,它允许你直接指定元素的宽高比。当你设置这个属性时,浏览器会自动调整元素的尺寸以保持这个比例,这使得创建保持长宽比的容器变得非常简单直接。
兼容性:既然是新特性,那不可避免的就有兼容性问题。笔者在这件事上比较有发言权。曾几何时做原型开发给客户展示的时候,在 IE 浏览器上运行出了大囧,到现在还记忆犹新,因此贴图一张,以稳定心态。
为了让大家避坑,这里明确一下,IE 不支持此属性!
转载自:https://juejin.cn/post/7366187632571744290