【CSS in Depth 2 精译】2.4 视口的相对单位

news2024/10/7 19:29:13

当前内容所在位置

  • 第一章 层叠、优先级与继承
  • 第二章 相对单位
    • 2.1 相对单位的威力
    • 2.2 em 与 rem
    • 2.3 告别像素思维
    • 2.4 视口的相对单位 ✔️
    • 2.5 无单位的数值与行高
    • 2.6 自定义属性
    • 2.7 本章小结

2.4 视口的相对单位

前面介绍过的 emrem 是相对于 font-size 定义的,但相对单位并非只有这一类情况;还有一类 视口相对单位(viewport-relative units,用于定义相对于浏览器视口的长度。

视口的定义

视口(viewport) 是浏览器窗口中网页可见部分的边框区域。它不包括浏览器的地址栏、工具栏和(可能显示的)状态栏。

最近 CSS 语言对于视口相对单位又增加了一些新内容。目前 CSS 中总共有 24 个视口相对单元。这听起来可能让人难以接受(overwhelming),但它们都是由一些相对简单的概念通过多种方式的混搭而衍生出来的。本节将从最基本的知识点开始介绍。以下是最初添加到 CSS 语言中的四个基础视口相对单位:

  • vh —— 视口高度的 1%;
  • vw —— 视口宽度的 1%;
  • vmin —— 视口宽、高中较小的一方的 1%;
  • vmax —— 视口宽、高中较大的一方的 1%。

例如,50vw 等于视口宽度的一半,25vh 等于视口高度的 25%。vmin 取决于宽或高中尺寸较小的一方。这样就保证了元素始终都能适应屏幕尺寸,而与设备方向无关:横屏时 vmin 取决于视口高度;竖屏时则取决于视口宽度。

图 2.10 展示了一个正方形元素在不同屏幕尺寸的视口中的显示效果。它的宽高均为 90vmin,也就是两个维度中较小一方的 90%,即横屏时高度的 90%,或竖屏时高度的 90%。

图 2.10
图 2.10 宽高均为 90vmin 的元素,无论视口大小或方向如何,都会显示成一个稍小于视口的正方形

代码清单 2.14 为该元素的样式代码。无论浏览器如何缩放,最终都能得到一个适应视口的大正方形。在页面中添加一段 <div class= "square"> 就能看到效果。

代码清单 2.14 用 vmin 定义正方形元素的尺寸

.square {
  width: 90vmin;
  height: 90vmin;
  background-color: #369;
}

视口相对长度非常适合展示一个填满屏幕的大图。也可以将图片放在一个长容器内,给定高度为 100vh,理论上就能使其与视口高度完全一致。

当这些相对单位开始用于往视口填充大图后,人们发现一个问题:在移动设备上,视口的尺寸会动态变化。为了让屏幕可用尺寸最大化,移动端浏览器设计了这样一个功能:当用户向下滑动页面时,一些与用户体验相关的控件,如屏幕顶部的地址栏以及底部的导航按钮,会滑出视窗;而当用户向上滑动页面时,这些控件又会恢复显示。

这些动态变化会导致视口大小的缩放,进而改变页面上使用 vh 作单位的元素尺寸,并最终导致下方内容在屏幕上跳动。想象一下这样的场景:在用户向下滑过多个 100vh 的方盒后,又稍微向上翻了一下。这将导致视图中的所有内容猛地上窜几百个像素,带来极度不协调的阅读体验;况且还有性能问题——因为浏览器必须重新计算页面布局(通常称之为 布局抖动(layout thrashing)。

最终,大多数移动端浏览器都根据视口能够达到的最大尺寸重新解释了 vh,并忽略地址栏对视口尺寸的影响,从而阻止了该抖动行为。但有时开发人员可能并不想这样处理,因此 CSS 规范中又补充了几个相对单位。

2.4.1 从新的视口单位遴选

为了解决布局抖动的问题,CSS 引入了大视口(large viewports)和小视口(small viewports)的概念。大视口是在浏览器隐藏所有用户体验元素时的最大视口;而小视口则恰恰相反,是这些元素都正常显示时的浏览器最小视口(如图 2.11 所示)。

图 2.11
图 2.11 移动设备大小视口对比

与普通的视口单位一样,大视口单位也可用于设置宽度、高度、最小值和最大值。使用大视口单位,需在前面加上字母 l(即 large 的首字母小写):lvwlvhlvminlvmax;同理,前面加上字母 s(即 small 的首字母小写)则表示使用小视口单位:svwsvhsvminsvmax

有了这些新单元,开发人员就能根据当前场景遴选出更重要的行为模式:满屏高度的报头(masthead)是否必须占满整个屏幕,即便超出浏览器底部一点点也无所谓吗?如果是的话,就用 height: 100lvh;还是说,整个报头保持可见更重要,就算报头下方、屏幕底部会空出一点空间也无伤大雅?如果是的话,就用 height: 100svh

此外,以下注意事项也要牢牢记住:

  • 视口单位制没有考虑滚动条:也就是说,当存在垂直滚动条时,宽度为 100svw 的元素会产生水平滚动。
  • 当存在屏幕键盘时,关于小视口单位是否应该缩小屏幕尺寸,CSS 规范尚未明确规定。目前一些安卓浏览器是这样处理的,但 iOS 浏览器不是;未来可能还会变动。
  • 在绝大多数浏览器中,原始视口单位往往表现为大视口单位,但事无绝对。

这就又留下一个悬而未决的问题:某些情况下可能需要视口单位的原始行为,即当浏览器的用户体验元素出现或隐藏时,视口单位会动态切换。对于这种行为,CSS 提供了第三类视口相对单元:动态视口(dynamic viewport。启用它们,只需在视口单位前加上字母 d(即 dynamic 的首字母小写)即可:dvwdvhdvmindvmax。当视口较小时,其行为类似小视口单位;而当视口较大时,又类似大视口单元。

使用动态视口单位时务必慎之又慎——当用户在移动设备上下滚动页面时,一旦元素高度发生动态变化,很可能会出现布局抖动。

表 2.1 列出了所有可用的视口相对单位。为了完整起见,还包括一组额外的单位类型:内联(inline)与块(block)。这两种类型被称为“逻辑属性”,其行为分别类似于宽度和高度,但对于日语等垂直书写的语言,则需要对调一下。本书第 3 章还将深入介绍逻辑属性。

表 2.1 视口相对单位一览表

未指定视口(原始单位)大视口小视口动态视口
宽 / 高vw / vhlvw / lvhsvw / svhdvw / dvh
最小 / 最大vmin / vmaxlvmin / lvmaxsvmin / svmaxdvmin / dvmax
内联 / 块vi / vblvi / lvbsvi / svbdvi / dvb

除了上面提过的报头及其他类似的全屏或半屏元素之外,应该并没有充分的理由断言某种视口单位一定优于另一种视口单位。但由于可供选择的视口相对单元如此之多,可能还会让人有些无从下手。这种情况下,我会选择小视口单位。

2.4.2 使用视口单位定义字号

视口相对单位有一个不起眼的用途,就是设置字号。但我发现它比用 vhvw 设置元素的宽度和高度还要实用。

试想,给一个元素加上 font-size: 2svw 会发生什么?在一个 1200px 的台式机显示器上,字号的计算值为 24px(即 1200 的 2%);而在一个 768px 的平板设备上,计算值则为 15px(即 768 的 2%)。这么做的好处在于,该元素在两种尺寸之间可以平滑地过渡。这意味着字号不会在某个断点发生突变,而是随着视口尺寸的变化而逐渐过渡。

唯一美中不足的是,24px 的字号对台式屏幕太大了;更有甚者换到 iPhone SE 上,字号又会一直缩到仅有 7.5px 左右。如果能让字号保留这种缩放的能力,同时又能避免走极端就好了。为此,CSS 的 calc()clamp() 函数可以助您一臂之力。

1 利用 CALC() 函数实现响应式

calc() 函数可以对两个及以上的值进行基本四则运算。当涉及不同单位的值时,calc() 特别实用。其支持的运算包括:加(+)、减(-)、乘(*)、除(/)。其中加号和减号两边必须留有空白,因此建议大家养成在每个操作符前后都加上一个空格的习惯,比如 calc(1em + 10px)

以下代码利用 calc() 函数将 emsvw 单位相结合。从样式表中删除之前的基本字号,以及相关的媒体查询。换成以下样式代码:

:root {
  font-size: calc(0.5em + 1svw);
}

现在打开页面,慢慢缩放浏览器,字体也会平滑地缩放。 0.5em 保证了最小字号,而 1svw 则引入了一个响应式的标量。这样,基础字号就可以从 iPhone SE 上的 11.75px 一直过渡到 1200px 的浏览器窗口中的 20px

警告

在使用视口单位来计算字号时,一定要确保算式中包含 emrem 单位值,以提高页面的可访问性。这样一来,最终渲染出的字号就能兼顾用户自定义的字体设置。

您可以根据自己的喜好调整这些值,但要找到一个在小视口中不会太小、并在大视口中不会太大的理想值,可能还是有点困难。

2 利用 CLAMP() 函数加以完善

上面介绍的这种响应式字号很有用,但一个更新的 CSS 函数 clamp() 可以提供更精细的控制。clamp() 接受三个参数:最小值、以表达式形式给出的首选值、以及最大值。再次按以下样式更新页面:

:root {
  font-size: clamp(0.9rem, 0.6rem + 0.5svw, 1.5rem);
}

此时指定的字号为 0.6rem + 0.5svw ,但 clamp() 函数确保了最终结果不会小于 0.9rem,也不会大于 1.5rem。这样,即便遇到非常大或非常小的视口,也不会出现字号越界的情况。

既然字号是响应式的,那么页面上使用 emrem 定义的其他尺寸也可以响应式地同步缩放。这样,无需使用任何媒体查询,就完成了响应式策略的绝大部分工作。页面上的所有内容都将根据视口进行流畅缩放,而无需设置三四个硬编码的断点。响应式设计的内容远不止这些,后续章节还会进行更深入的探讨,但掌握这些知识必将为后续的设计工作开一个好头。

提示

min()max() 这两个相关函数可能时常也会用到。min() 函数表示给定值中的最小值(如 width: min(200px, 20svw););max() 则表示给定值中的最大值(如 min-height: max(200px, 20svw);)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1891881.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

React+TS前台项目实战(二十四)-- 全局常用绘制组件Qrcode封装

文章目录 前言Qrcode组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示(pc端 / 移动端) 总结 前言 今天要封装的Qrcode 组件&#xff0c;是通过传入的信息&#xff0c;绘制在二维码上&#xff0c;可用于很多场景&#xff0c;如区块链项目中的区块显示交易地址时就可以用到…

DDOS攻击不懂?看完让你秒懂!

什么是DDOS攻击&#xff1f; DDoS攻击&#xff0c;全称分布式拒绝服务攻击&#xff08;Distributed Denial of Service attack&#xff09;&#xff0c;是一种常见的网络安全攻击方式。以下是对DDoS攻击的详细解释: DDoS攻击是指攻击者利用大量被控制的计算机或设备&#xff…

Appium+python自动化(三十九)-Appium自动化测试框架综合实践 - 代码实现(超详解)

1.简介 今天我们紧接着上一篇继续分享Appium自动化测试框架综合实践 - 代码实现。由于时间的关系&#xff0c;宏哥这里用代码给小伙伴演示两个模块&#xff1a;注册和登录。 2.业务模块封装 因为现在各种APP的层出不群&#xff0c;各式各样的。但是其大多数都有注册、登录。为…

嵌入式Linux之Uboot简介和移植

uboot简介 uboot 的全称是 Universal Boot Loader&#xff0c;uboot 是一个遵循 GPL 协议的开源软件&#xff0c;uboot是一个裸机代码&#xff0c;可以看作是一个裸机综合例程。现在的 uboot 已经支持液晶屏、网络、USB 等高级功能。 也就是说&#xff0c;可以在没有系统的情况…

vue如何实现低代码

Vue.js 本身作为一个前端框架&#xff0c;并不是专门设计用来实现低代码平台的工具。然而&#xff0c;借助 Vue.js 的灵活性和组件化特性&#xff0c;可以在其基础上构建低代码平台或低代码工具。以下是一些实现低代码平台所需的关键功能和技术&#xff0c;可以在 Vue.js 中进行…

使用ChatGPT自动生成测试用例思维导图

使用ChatGPT自动生成测试用例思维导图 引言ChatGPT在测试用例编写中的应用全面覆盖测试场景边界测试避免测试用例重复 借助ChatGPT生成测试用例思维导图准备工作步骤一&#xff1a;与ChatGPT对话步骤二&#xff1a;生成思维导图代码 结语 引言 在编写测试用例时&#xff0c;测…

Openwrt路由器部分ipv6公网地址无法访问的问题

路由器是Openwrt&#xff0c;终端访问ipv6地址经常有些能访问&#xff0c;有些不能访问&#xff0c;一开始以为是运营商问题&#xff0c;后面ssh到openwrt发现所有访问都正常。 查阅资料后才知道是MTU设置问题&#xff0c;Openwrt 默认MTU是1492&#xff0c;使用IPV6应减少60个…

AI智能音箱用2×15W立体声功放芯片NTP8918

智能音箱是近年来非常受欢迎的智能家居产品之一&#xff0c;它集成了人工智能技术和音频技术&#xff0c;能够为用户提供语音助手、音乐播放、智能家居控制等多种功能。其中&#xff0c;音频输出是智能音箱的核心功能之一&#xff0c;而功放芯片则是实现音频放大的关键组成部分…

8-Bit Retro Game SFX Pack(复古游戏音效)

大量高品质、专业制作的8位复古声音。8Bit Retro SFX Pack 1将为您的游戏带来您想要的优势。将跳跃、物品拾取和武器声音添加到经典视觉效果中。伴随着爆炸声、火灾声、通电声和断电声&#xff0c;让人回到怀旧的电子游戏黄金时代。通过包含的数百个音频文件&#xff0c;找到您…

智能视频监控如何助力体育场馆安全管理:安防监控EasyCVR视频综合管理方案

近期有新闻报道&#xff0c;6月30日&#xff0c;17岁的中国国家羽毛球运动员在亚洲青年羽毛球锦标赛中&#xff0c;突然晕倒并抽搐&#xff0c;尽管被送往医院抢救&#xff0c;该运动员仍在当晚不幸离世。运动猝死不仅发生于职业运动员身上&#xff0c;在普通健身者中也时有发生…

【JavaWeb】利用IntelliJ IDEA 2024.1.4 +Tomcat10 搭建Java Web项目开发环境(图文超详细)

1、启动IntelliJ idea 2024.1.4 在欢迎页面&#xff0c;请确认好版本。因为不同的版本&#xff0c;搭建项目过程不太一样。 点击&#xff0c;新建项目。如图&#xff1a; 2、新建项目 在新建项目界面&#xff0c;选择java&#xff0c;在右侧信息模块内&#xff0c;根据个人情…

AI+若依框架(低代码开发)

一、若依介绍 1.版本介绍 若依为满足多样化的开发需求&#xff0c;提供了多个版本 RuoYi-Vue&#xff08;SpringBootVue的单体项目&#xff09; RuoYi-Cloud&#xff08;SpringCloudVue的微服务版本项目&#xff09; RuoYi-App&#xff08;UniappVue移动版本&#xff09; Ru…

14-14 商业领域的人工智能革命

在商业技术领域&#xff0c;对话式人工智能已获得广泛认可和使用&#xff0c;产生了重大而直接的影响。GPT-2 和 GPT-3 等大型语言模型一直是该领域的基础&#xff0c;但它们的高级继任者将对话界面推向了新的高度。这些较新的模型不仅仅是处理输入&#xff1b;它们旨在完美地集…

OpenLayers使用

初学ol&#xff0c;实现了高德地图不同图层的切换、交互性地图飞行以及加载本地JSON数据。 说一下不同图层切换的想法&#xff1a; 1.对于标准地图和卫星地图&#xff1a;二者最初便挂载到map上&#xff0c;两个图层是叠加显示的&#xff1b;当点击按钮时&#xff0c;其实是使…

帮公司搭了个Nuxt3项目框架

theme: smartblue 最近公司立项了一个新项目&#xff0c;因为是to C 的&#xff0c;所以对SEO是有较高需求的&#xff0c;由于公司前端技术栈统一用的VUE&#xff0c;顺理成章的就选择了nuxt这个全栈框架。项目立项之后我就被安排了负责前端项目框架的搭建&#xff0c;从搭建过…

探寻IT的道路,从现在开始!

IT专业入门&#xff0c;高考假期预习指南 七月来临&#xff0c;各省高考分数已揭榜完成。而高考的完结并不意味着学习的结束&#xff0c;而是新旅程的开始。对于有志于踏入IT领域的高考少年们&#xff0c;这个假期是开启探索IT世界的绝佳时机。作为该领域的前行者和经验前辈&a…

Java [ 基础 ] 数组、ArrayList和LinkedList✨

目录 ✨探索Java基础 数组、ArrayList和LinkedList✨ 一、总体介绍 二、分别介绍 1. 数组&#xff08;Array&#xff09; 2. ArrayList 3. LinkedList 三、区别总结 四、常见面试题 如何选择使用数组、ArrayList和LinkedList&#xff1f; 如何实现线程安全的ArrayL…

stm32cubeide的undefined reference难解之谜

stm32cubeide 的 undefined reference 难解之谜 今天使用意法半导体公司的STM32CubeIDE 1.15.0编码器 遇到了一个熟悉&#xff0c;却令我绞尽脑汁的问题 这个问题大家应该都挺常见的 有以下几种要注意的地方 1、路径是否包含 2、函数是否在C文件定义 3、函数是否在头文件中定…

美国拟立法评估:极端网络攻击下关基设施能否切换手动操作

文章目录 前言一、评估关基设施快速切换手动操作的可行性1、评估需包括如下内容:2、政策保障关键基础设施运行二、保障关基设施安全迫不容缓前言 随着来自俄罗斯、伊朗和朝鲜等敌对国家以及国家关联团体的威胁不断增加,网络攻击对电网、水务系统和管道等关键基础设施的潜在破…

Python绘制动态树形:实现分形树动画

文章目录 引言准备工作前置条件 代码实现与解析导入必要的库初始化Turtle绘制分形树函数动态绘制函数主函数 完整代码 引言 分形树是一种通过递归生成的美丽图案&#xff0c;在数学和计算机图形学中有着重要的地位。在这篇博客中&#xff0c;我们将使用Python创建一个动态的分…