屏霸秘籍:一招锁定完美宽高比,告别带鱼屏乱码时代!

发布于:2024-05-10 ⋅ 阅读:(28) ⋅ 点赞:(0)

前几天做了一个大屏项目。既然是大屏,就不可避免的需要考虑到自适应问题。常见的基于 rem 的布局方式有一个天然的缺陷。那就是 rem 基于屏幕宽度变化而非高度。这就带来一个问题,那就是在一些奇葩的屏幕,比如带鱼屏上展示的时候样式可能会乱掉。

为此,我们必须保证长宽比是固定的,而不是简单的将高度方向上的尺寸也处理成 rem 单位。那么如何能够保证 div 元素的长宽比呢?本文就介绍两个方法,一个是传统做法,一个是使用比较新的 CSS 属性。喜欢的朋友们快收藏起来吧~

1. 传统方式

使用传统的方式保证 div 的长宽比的原理在于:padding-top 或者 padding-bottom 的计算基准是父元素的宽度而不是高度;因此可以采用这样的策略:

  1. 给父元素宽度值,然后让其子元素的宽度值为 100% ,并让其竖直方向上的 padding 为 60% 。
  2. 注意这个子元素的作用是将父元素撑起来,并不是在这一层写具有意义的内容,因此给其高度为 0 并且将 position 设置成 relative。
  3. 而孙子元素才是真正写内容的容器,为了让孙子元素有一个预设的尺寸,因此设置其 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样式

  1. .item:

    • background:red; 设置了外层容器的背景颜色为红色。
    • width:50%; 使外层容器的宽度为父容器宽度的50%,这意味着它可以适应父容器的大小。
    • margin:0 auto; 使外层容器水平居中。
  2. .inner:

    • width:100%; 使内层容器的宽度填满其父容器(即 .item)的宽度。
    • height:0; 设置内层容器的高度为0,这是关键,因为实际的“高度”将由 padding-bottom 决定。
    • padding-bottom: 60%; 这是保持长宽比的关键。padding-bottom 的百分比是相对于其父容器的宽度。因此,如果父容器宽度为100%,那么 padding-bottom 将会是宽度的60%,这样就形成了一个宽高比为 100:60 (或简化为 5:3) 的矩形区域。
    • position: relative; 设置了内层容器的定位为相对定位,这样其子元素可以相对于它进行定位。
  3. .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 容器的宽度如何变化,.innerpadding-bottom 都会按照设定的百分比来调整其高度,从而保持长宽比不变。

在这个例子中,长宽比是5:3,因为 padding-bottom 设置为60%,意味着高度是宽度的60%,可以通过以下比例计算得出:

长宽比 = 宽度 高度 = 1 1 ÷ 0.60 = 1 1 ÷ 60 100 = 1 1 ÷ 3 5 = 1 5 3 = 3 5 \text{长宽比} = \frac{\text{宽度}}{\text{高度}} = \frac{1}{1 \div 0.60} = \frac{1}{1 \div \frac{60}{100}} = \frac{1}{1 \div \frac{3}{5}} = \frac{1}{\frac{5}{3}} = \frac{3}{5}

这种方法的优点是兼容性好,哪个浏览器不支持 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 浏览器上运行出了大囧,到现在还记忆犹新,因此贴图一张,以稳定心态。

image.png

为了让大家避坑,这里明确一下,IE 不支持此属性!


网站公告

今日签到

点亮在社区的每一天
去签到