当前位置: 首页 > news >正文

请列举四种「等比例自适应矩形」实现方案?

引言

本文是由一次面试引发的探讨, 在一次面试过程中被问起「如何实现一个自适应等比例矩形?」, 对于实现方案我依稀记得是有看到过的, 但是一时也想不起来, 所以在面试的时候自然就没有回答出来!!!

面试结束回来也简单 google 了下, 找到实现方案其实基本都大差不差, 无非就是通过 vw 或者 padding 来实现, 所以也就没有怎么总结输出, 直到后面我找到了另外两种方案, 所以就有了这篇文章!!!

下面开始进入主题…

一、相对长度单位「vw」

vw: CSS 中的一个相对长度单位, 1vw 等于视口宽度的 1%

第一个方法, 就是使用 vw 来实现, 这个比较好理解, 当宽度、高度都基于同一个参考标准的一个相对长度, 那么自然就能够实现等比例矩形了

.box {width: 50vw; height: 25vw;
}

这里有个比较大的缺点就是, 宽度、长度只能相对于视口进行自适应; 无法相对于父元素进行自适应

二、使用「padding」属性

第二个方案, 也是早期比较推荐的一种做法; 该方法主要依据是: CSS 在默认情况下 marginpadding 属性的 垂直方向百分比值 都是 相对于父元素的宽度 来计算的

有代码如下: .container 宽度设置为 500px, .container::before 通过 padding-top: 50%; 把父元素撑开, 实现 2:1 的矩形

<style>.container {width: 500px;background-color: #91caff;}.container::before {content: '';display: block;padding-top: 50%; /* 相对于父元素宽度 */}
</style>
<div class="container"></div>

最后效果如下:

image

该方法兼容性是没有问题的, 但是由于容器被子元素占满, 我们如果想要在容器内部放置其他内容, 就需要多一层嵌套 div, 然后通过 position 来布局, 如下代码所示: 新增 .content 元素, 然后通过 position 进行定位

<style>.container {width: 500px;position: relative;background-color: #91caff;}.container::before {content: '';display: block;padding-top: 50%; /* 相对于父元素宽度 */}.content {inset: 0;position: absolute;}
</style>
<div class="container"><div class="content">content</div>
</div>

最后效果如下:

image

补充: 你是否好奇, 为啥 marginpadding 在垂直方向上的百分百是相对父元素宽度的, 而不是高度呢? 我们都知道父元素的高度往往由子元素来决定, 试想下如果 marginpadding 垂直方向的百分百比是相对于父元素高度的, 那么当它们设置了一个百分比, 相应的, 父元素高度会进行适应性增加; 此时父元素高度增加的同时, marginpadding 若以父元素高度为基准, 则其实际数值又会发生适应性变化, 双向因果会造成循环, 所以 W3C 的规范做出了以上规定

三、使用「aspect-ratio」属性

CSS 属性 aspect-ratio 可以为盒子设置一个首选的宽高比例, 这个宽高比可以用于计算 auto 尺寸以及其他布局函数

第三个方案是通过 aspect-ratio 来实现, aspect-ratio 属性可以为元素设置 宽度和高度 的一个 默认比例, 这样的话我们就很容易实现一个任意比例的矩形了, 如下代码: 通过 aspect-ratio: 2 / 1; 约定默认情况下容器的宽度和高度比例为 2:1, 由于容器只设置了宽度, 那么在 aspect-ratio 的约束下, 高度将自适应性, 从而实现了一个 2:1 的等比例矩形

<style>.container {width: 500px;aspect-ratio: 2 / 1;background-color: #91caff;}</style>
<div class="container"></div>

最后效果如下:

image

3.1 关于「aspect-ratio」更多补充

  1. 兼容性: 到目前(2023.10)为止除了 IE, 其他浏览器基本都已支持

image

  1. 当容器内容足够多的情况下 aspect-ratio 的限制将失效, 如下代码所示: 为 .container 容器添加一段文本, 设置容器宽度为 200px, 设置 aspect-ratio 也就是默认容器宽高比为 2:1
<style>.container {width: 200px;aspect-ratio: 2 / 1;background-color: #91caff;}</style>
<div class="container">男子吊环决赛中, 东京奥运会冠亚军刘洋、尤浩为中国队上了 "双保险", 最终以15.233分和14.833分分别摘得金牌和铜牌
</div>

最终效果如下: 由于容器内容很多, 最终会发现容器的宽度为 200, 高度为 110aspect-ratio 设置的比例并不匹配

image

那么这是为什么呢? 主要原因是 aspect-ratio 对容器尺寸的影响其实是最低的, 我们都知道影响容器尺寸的属性有很多包括min-width/min-heightmax-width/max-heightwidth/height容器本身内容aspect-ratio, 那么它们对容器尺寸的影响优先级如下 min-* > max-* > width/height > 内容 > aspect-ratio, 也就是容器本身内容对容器尺寸的影响力大于 aspect-ratio 所以就出现了上面 👆🏻 这个现象

这里解决办法其实也简单, 我们只需要为容器设置一个 min-height: 0; 即可:

<style>.container {width: 200px;aspect-ratio: 2 / 1;background-color: #91caff;
+   min-height: 0;}</style>
<div class="container">男子吊环决赛中, 东京奥运会冠亚军刘洋、尤浩为中国队上了 "双保险", 最终以15.233分和14.833分分别摘得金牌和铜牌
</div>

最终效果如下: 从尺寸上来看 aspect-ratio 成功生效了, 至于文本溢出, 可以设置 overflow: auto; 来解决

image

  1. width/heightmin/max-width/height 的相互影响:
  • width/height 属性的关系:

    • widthheight 都设置了, 那么就没 aspect-ratio 任何事咯
    • widthheight 都没设置, 那么宽度自适应, 高度则按照 aspect-ratio 以及容器的宽度来计算高度
    • widthheight 设置其一, 则另一个尺寸按 aspect-ratio 来计算
  • min/max-width/height 属性的关系:

    • 实际上是 aspect-ratiowidth/height 属性关系的延伸
    • 如果设置了 min-width 或者 max-width, 并且影响到容器宽度(可以理解为设置固定的 width)
    • 如果设置了 min-height 或者 max-height, 并且影响到容器高度(可以理解为设置固定的 height)
    • 那么最后的关系还是和上文的 width/height 是一致;

个人理解: width/height 也好 min/max-width/height 也罢, 只要容器宽度和高度都被影响到(受限), 那么 aspect-ratio 将失效; 如果其中一个被影响到(受限), 那么 aspect-ratio 将按照 容器最终的尺寸 计算另一个尺寸的大小; 如果容器的宽度高度都没受到影响, 那么 aspect-ratio 将默认按照 容器的最终宽度 来计算另一个尺寸的大小

四、使用「cqw」单位

第四种, 也是文本介绍的最后一种方法!! 这里其实是使用了 CSS 容器查询的新特性, 容器查询 可以实时获取到指定容器元素的一个尺寸, 并通过媒体查询来监听容器尺寸的变化, 来做一些自适应!!! 当然本文并不需要使用到媒体查询, 但我们可以借用配套的 CSS 单位 cqw 来实现等比例矩形

我们来直接看代码, 基于代码来对 cqw 进行简单讲解, 如下代码:

  • container-type: inline-size; 定义了一个可查询容器, 个人理解就是将容器标记为可查询容器
  • cqwCSS 单位中的一种, 1cwq 它等于 最近可查询祖先容器 宽度的 1%
<style>.container {width: 200px;container-type: inline-size;background-color: #91caff;}.content {height: 50cqw; /* 最近可查询容器宽度的 50% */}</style>
<div class="container"><div class="content"></div>
</div>

最后效果如下:

image

通过 cqw 可以很容器实现任意比例的矩形, 但是它有个缺点就是您可能需要额外嵌套一层!!!

补充: 更多容器查询长度单位

  • cqw: 查询容器宽度的 1%
  • cqh: 查询容器高度的 1%
  • cqi: 查询容器行向尺寸的 1%
  • cqb: 查询容器块尺寸的 1%
  • cqmin: cqicqb 中较小的值
  • cqmax: cqicqb 中较大的值

五、参考

  • CSS实现宽高等比例自适应矩形
  • 如何使用 css + div 来实现一个等比例矩形
  • CSS高宽不等图片固定比例布局的三重进化
  • Chrome 88已经支持aspect-ratio属性了, 学起来
  • CSS百分比padding实现比例固定图片自适应布局
  • CSS 容器查询

image


http://www.mrgr.cn/news/57572.html

相关文章:

  • C 语言介绍及操作案例
  • @Autowired和@Resource的用法与区别
  • 【Linux 从基础到进阶】系统故障排查思路与实战
  • 计算机网络基础知识|网络安全基础知识
  • 华为无线路由器设置成交换机
  • iPhone图片/照片/视频复制到win10系统的简单方法 - 照片导出
  • API接口在各个领域的发挥着什么样的作用呢
  • 1024程序员日|向改变世界的程序员 致敬!
  • 字符串-04-字符串加解密
  • 最新整理:自动化测试常见面试题
  • fmql之Linux中I2C总线框架
  • 开源模型应用落地-Qwen2-VL-7B-Instruct-vLLM-OpenAI API Client调用
  • 基于RabbitMQ,Redis,Redisson,RocketMQ四种技术实现订单延时关闭功能及其相关优缺点介绍(以12306为主题)
  • Stability.AI 发布 SD3.5 模型,能否逆袭击败 FLUX?如何在ComfyUI中的使用SD3.5?
  • 使用gpt2-medium基座说明模型微调
  • anolis os 8.8 修改kube-proxy的模式为ipvs-kubeadm部署
  • arcgis pro 3.3.1安装教程
  • 重学SpringBoot3-Spring WebFlux之HttpHandler和HttpServer
  • 代码随想录算法训练营第二十五天 | 491.递增子序列 46.全排列 47.全排列Ⅱ
  • LeetCode练习-删除链表的第n个结节
  • Hot100速刷计划day04(10-12)
  • 【网页布局技术】项目六 制作表格并使用CSS美化
  • 【Linux】进程信号(下)
  • CCRC-CDO首席数据官的主要工作内容
  • 全新原生鸿蒙HarmonyOS NEXT发布,书写国产操作系统新篇章!同时,触觉智能发布OpenHarmony5.0固件
  • (一)ArkTS语言——申明与类型