开发课程 | 支付宝小程序开发中CSS中的“单位”

简介: 本文将从概念着手,辅以实例说明,将各常用单位的含义、用法进行讲解

小程序.jpg

作者简介:雪庭,来自蚂蚁金服支付宝,曾就职于 MathWorks、网易,具有丰富的软件开发、前端开发经验;从零到一打造支付宝电子发票、信用卡还款等小程序,支撑千万级PV应用;蚂蚁金服技术大学金牌讲师,所授课程均获得近乎满分评价。现推出支付宝小程序开发系列课程,将前端基础、小程序开发等知识与业务中沉淀的最佳实践相结合,深入浅出带你快速了解必要的前端基础,并掌握如何开发支付宝小程序

CSS units

单位是 css 中最基本的内容,常用的有 px,em,rem,以及和 viewport 相关的vw,vh 等,本文将从概念着手,辅以实例说明,将各常用单位的含义、用法进行讲解。

让我们开始吧!

px

绝对长度单位,非常熟悉,概念不再赘述。优点在使用简单,但是设置的属性值不会根据屏幕的大小变化而变化,也不会根据用户设置的字体大小发生改变

常用在设置固定尺寸、位置上,例如:

border: 1px solid black;
border-radius: 3px;

em

1 em  等于当前元素父元素的 font-size,例如父元素的 font-size 为 20px,则 1rem = 20px 。如果父元素未显式设置 font-size,则向上继承,直至 body 元素

基础示例

举个例子

(codepen 链接:https://codepen.io/yu-xueting/pen/byQxYZ?editors=1100#0

<div class="parent">
  parent
  <div class="child">
    child1
    <div class="child">
      child2
    </div>
  </div>
</div>
.parent {
  font-size: 15px;
}

.child {
  font-size: 2em;
}

image.png

原理分析:

  • parent 元素设置了 font-size,它的字体大小是 15px 
  • child1 元素 font-size 是 2em,即 2 倍于父元素(parent)的字体大小,为  15px * 2 = 30px 
  • child2 元素 font-size 是 2em,即 2 倍于父元素(child1)的字体大小,为 30px * 2 = 60px 

逐层递进

在 em 的定义中,有一个关键点:父元素,即 em 的值的大小与直系父元素的 font-size 息息相关,这可以很方便的做出逐层递进的效果,比如说,sidebar!

(codepen 链接:https://codepen.io/yu-xueting/pen/eaxvXN

<div class="sidebar">
  <div class="sidebar-item">foo</div>
  <div class="sidebar-item">bar
    <div class="sidebar-item">aa</div>
    <div class="sidebar-item">bb
      <div class="sidebar-item">x</div>
      <div class="sidebar-item">y</div>
    </div>
  </div>
  <div class="sidebar-item">baz</div>
</div>
.sidebar {
  font-size: 60px;
}

.sidebar-item {
  border-left: 1px solid blue;
  font-size: 0.6em;
  margin-left: 1em;
}

image.png

原理分析:

  • 每层 sidebar-item 设置的 font-size 为 0.75em,即为父元素字体大小的 0.75 倍,那么随着层级的加深,每层 sidebar-item 的字体大小会越来越小
  • 每层 sidebar-item 设置的 margin-left 为 1em,即左边距设置为父元素字体大小,随着层级的加深,margin-left 也呈递减态势(例子中利用 border-left 来辅助展示 margin-left)

屏幕自适应

em 是相对长度单位,不同于 px , em 的值是动态的,是可变的,只要调整父元素的字体大小,就可以改变 em 的值,这为不同屏幕宽度自适应布局提供了解决方案:

如果我们想在更宽的屏幕上显示更大的字体、更大的图片,只需要根据屏幕宽度设置父元素的 font-size 即可

来看如下例子,例子中使用顶部滚动条来模拟不同宽度屏幕下动态设置父元素 font-size 的过程,例子中 title 的字体大小是固定的,可借此对比 px 和 em 的区别

(codepen链接:https://codepen.io/yu-xueting/pen/zQeEmE

<div>拖动滚动条,模拟屏幕宽度变化</div>
<input type="range" id="range" min="1" max="6" step="0.1" value="2" oninput="onChange()" />
<div class="container">
  <div class="title">TITLE</div>
  <div class="content">
    <div class="logo"></div>
    <div class="text">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vitae convallis felis. Quisque egestas lorem ligula, vel facilisis velit maximus a. Pellentesque gravida vestibulum odio. Suspendisse sagittis viverra arcu vel convallis. Duis magna felis, blandit eu nisl sollicitudin, lobortis varius odio. Pellentesque rhoncus at ante et vestibulum. Pellentesque et elit eu sapien vehicula euismod id vitae velit. Donec eleifend ligula eu nulla vulputate, sed porttitor velit mattis. Fusce scelerisque volutpat cursus. Phasellus eleifend, quam nec mollis blandit, nisi felis hendrerit dui, vitae efficitur urna est vitae dui. Vivamus vel pretium tellus. Vestibulum lobortis quam ac quam lobortis, sit amet fermentum purus lobortis. Cras rutrum ultricies lacus ac faucibus.
    </div>
  </div>
</div>
.container {
  width: 600px;
  font-size: 30px;
  border: 1px solid #108EE9;
  padding: 20px;
}

.logo {
  width: 2em;
  height: 2em;
  background: #108EE9;
}

.title {
  text-align: center;
  font-size: 50px;
  color: #108EE9;
}

.text {
  font-size: 0.5em;
}
function onChange () {
  const range = document.getElementById("range").value;
  document.querySelector('.container').style.fontSize= 15 * range + 'px';
}

image.png

原理分析:

  • logo(蓝色方块)和 text(段落文字)使用 em 为单位设置宽、高、字体大小
  • 拖动滚动条,动态设置 container 的字体大小
  • 根据 em 的定义,container 元素是 logo 和 text 的父元素,改变 container 的字体大小会改变 em 的值,进而改变 logo 的大小及段落文字的字体大小

rem

1rem 等于根元素(html 元素)的字体大小,例如 html 元素的 font-size 为 20px,则 1rem = 20px 

em vs rem

em 与 rem 很相似,区别在于 rem 的值是 html 元素字体大小决定的,对于页面中各个层级的元素均相同,修改 rem 会动态更改所有以 rem 为单位的元素对应的属性值,不需要考虑层级结构

没有好坏之别,各有适用的场景

rem 适用于整体的屏幕自适应布局,只需修改 html 元素 font-size,即可全局调整页面样式
em 如上文所述,适用于写出逐层递进的效果,和部分区域自适应布局

rem 版本的屏幕自适应例子与 em 非常相似,这里不再赘述,让我们看一个更复杂的例子

固定元素在背景图片上

在不同的屏幕尺寸下,我们希望页面展示的效果是相同的,对于背景图比较好处理,通常设置背景图宽度与屏幕宽度保持一致,并保持背景图比例不变。但是除背景图外,有些元素会设置动画效果(例如呼吸的气泡),有些元素会设置操作热区供用户操作(例如刮刮卡的刮开区)。这些元素需要固定在背景图片的某个位置上,不能因为屏幕尺寸改变而移动,要如何固定呢?

举个例子,我们用图中蓝色方块来代表需要固定的元素,如何让它始终固定在 KEEP 的左上角?

image.png

其实这是一个数学问题,示意图如下(图中大矩形为背景图,小矩形为定位元素)

image.png

图中 w 代表屏幕宽度(背景图宽度),h 代表背景图高度,x 代表定位的位置距离背景图左边缘占比背景图宽度的大小,例如 20%,30%,y 代表定位的位置距离背景图上边缘占比背景图高度的大小

定位元素的位置信息为:

left: x * w;
top: y * h;

背景图随屏幕宽度变化而变化时,w,h 都会变化,也就是按照现有公式,left 和 top 需要设置的值始终在变,有没有什么办法可以让我们设置 left 和 top 的值是固定的,但是让变化自动进行呢?

有的,这个中间桥梁就是 rem 

关键的步骤是, 将 html 的 font-size 与屏幕宽度进行关联,进而使得以 rem 为单位的 left 和 top 的值随屏幕宽度变化而变化,来看看具体细节:

  1. 设置 html 的 font-size 为屏幕宽度 w 乘以某个系数,假设为 a,即为 a*w 
  2. 根据定义可得, 1rem = a*w 
  3. w = 1rem / a  => w = 1/a rem 
  4. 由于背景图始终保持原比例,假设比例为 r,则 h = w*r  => h = (1/a rem)*r => h = r/a rem 

现在,定位元素的位置信息为:

left: x * w => x * (1/a rem) => x/a rem;
top: y * h => y * (r/a rem) => y*r/a rem;

注意,在上述的公式中,x, y, r, a 都是常数,所以 x/a 和y*r/a 都是常数,进而导出结论,元素定位信息中的 left 和 top 可以使用固定值来设置

以下是示例

(codepen 链接:https://codepen.io/yu-xueting/pen/wbQmLX

<div>蓝色块表示需要固定的元素,它一直固定在图片 keep 文字的左上角</div>
<input type="range" id="range" min="1" max="6" step="0.1" value="3" oninput="onChange()" />
<div class="container">
  <div class="content">
    <div class=icon></div>
  </div>
</div>
html {
  font-size: 60px;
}
body {
  font-size: 16px;
}

.container {
  position: relative;
  width: 300px;
  height: 600px;
  border: 1px solid black;
}
.content {
  position: relative;
  width: 100%;
  height: 100%;
  background-image: url('https://cdn.shopify.com/s/files/1/1272/9011/files/1_6614eeeb-262e-4d53-99e6-b8cf6cac767e_1024x1024.png?v=1520891132');
  background-repeat: no-repeat;
  background-size: 100% auto;
  background-position: top center;
  overflow: hidden;
}

.icon {
  width: 30px;
  height: 30px;
  background-color: #108EE9;
  position: absolute;
  top: 3.5rem;
  left: 1.16rem;
  text-align: center;
}
function onChange () {
  const range = document.getElementById("range").value;
  document.querySelector('.container').style.width = 100*range + 'px';
  document.querySelector('html').style.fontSize = 20*range + 'px';
  document.querySelector('.icon').style.width = 10*range + 'px';
  document.querySelector('.icon').style.height = 10*range + 'px';
}

image.png

viewport 相关

viewport 即视窗,可以理解为无须滚动时可见的浏览器窗口范围

  • vw - 视窗宽度的 1%,如视窗宽度为 500px,则 1vw = 5px 
  • vh - 视窗高度的 1%,如视窗高度为 500px,则 1vh = 5px 
  • vmax - vw 和 vh 中较大的值
  • vmin - vw 和 vh 中较小的值

来个例子

(codepen 链接:https://codepen.io/yu-xueting/pen/byzOBL

<div class="tip">改变结果窗口的大小,观察各 viewport 相关值的变化:</div>
<div class="test-vw">test vw</div>
<div class="test-vh">test vh</div>
<div class="test-vmax">test vmax</div>
<div class="test-vmin">test vmin</div>
body {
  font-size: 30px;
}

.tip {
  font-size: 20px;
  margin-bottom: 20px;
}

.test-vw {
  width: 30vw;
  border: 1px solid #108EE9;
}

.test-vh {
  width: 30vh;
  border: 1px solid #108EE9;
}

.test-vmax {
  width: 30vmax;
  border: 1px solid #108EE9;
}

.test-vmin {
  width: 30vmin;
  border: 1px solid #108EE9;
}

image.png

Have fun! :D

Ref

生活号+钉钉群.png

目录
相关文章
预约按摩小程序开发,为什么很多上门按摩平台根本招聘不到优秀技师?
上门按摩平台面临招不到优秀技师的问题,主要原因是平台众多,技师选择多样。为解决此问题,平台可引入技师等级制度,根据订单数量和好评率划分高、低等级技师。高等级技师可享受70%-90%的高提成及首页推荐,这不仅能激励技师的积极性,还能帮助平台筛选出优质技师,提升服务质量和口碑,形成良性循环。
|
20天前
|
人工智能 小程序
【一步步开发AI运动小程序】五、帧图像人体识别
随着AI技术的发展,阿里体育等公司推出的AI运动APP,如“乐动力”和“天天跳绳”,使云上运动会、线上健身等概念广受欢迎。本文将引导您从零开始开发一个AI运动小程序,使用“云智AI运动识别小程序插件”。文章分为四部分:初始化人体识别功能、调用人体识别功能、人体识别结果处理以及识别结果旋转矫正。下篇将继续介绍人体骨骼图绘制。
|
21天前
|
人工智能 小程序 vr&ar
AI运动小程序开发常见问题集锦二
截至当前,我们的AI运动识别小程序插件已迭代至第23个版本,广泛应用于健身、体育、体测、AR互动等场景。本文针对近期用户咨询,汇总了常见问题,帮助用户减少开发成本,提高效率。主要涵盖计时与计数模式的区别、综合排行榜生成方法、全屏模式适配及无开发能力用户的解决方案。
|
21天前
|
小程序 数据挖掘 UED
开发1个上门家政小程序APP系统,都有哪些功能?
在快节奏的现代生活中,家政服务已成为许多家庭的必需品。针对传统家政服务存在的问题,如服务质量不稳定、价格不透明等,我们历时两年开发了一套全新的上门家政系统。该系统通过完善信用体系、提供奖励机制、优化复购体验、多渠道推广和多样化盈利模式,解决了私单、复购、推广和盈利四大痛点,全面提升了服务质量和用户体验,旨在成为家政行业的领导者。
|
1月前
|
存储 传感器 小程序
跳绳计数小程序开发系统
首先,我们需要明确跳绳计数小程序的核心功能:为用户提供跳绳计数的便捷方式。这意味着小程序需要能够准确地记录用户的跳绳次数,并为用户提供清晰、直观的计数展示。
|
1月前
|
人工智能 编解码 小程序
【一步步开发AI运动小程序】四、小程序如何抽帧
随着AI技术的发展,阿里体育等公司推出的“乐动力”、“天天跳绳”等APP使云上运动会、线上健身等概念备受关注。本文将引导您从零开始开发一个AI运动小程序,利用“云智AI运动识别小程序插件”。文中详细介绍了微信小程序抽帧的相关API、设置及注意事项,帮助开发者更好地实现AI运动功能。下篇将介绍人体识别技术,敬请期待。
|
1月前
|
传感器 存储 小程序
跳绳计数小程序开发
跳绳计数小程序旨在通过智能设备(如手机或智能手表)记录用户在跳绳过程中的次数、时间、速度等关键数据,为用户提供便捷的运动记录和数据分析服务
|
1月前
|
小程序 搜索推荐 前端开发
小剧场短剧影视小程序开发
小剧场短剧影视小程序旨在为用户提供一个便捷、互动的平台,让用户能够随时随地观看、分享和评论各类小剧场短剧。通过小程序,用户可以浏览热门短剧、搜索感兴趣的内容、参与社区互动,以及享受个性化的推荐服务。
|
1月前
|
小程序 搜索推荐 前端开发
短剧小程序开发案例
首先,明确你的短剧平台的目标用户群体和他们的需求。比如,年轻用户可能更倾向于轻松、幽默的短剧内容,而家庭用户则可能更偏爱教育、亲子类的短剧。了解用户需求有助于你设计更符合他们口味的功能和界面
|
1月前
|
机器学习/深度学习 人工智能 小程序
【一步步开发AI运动小程序】三、运动识别处理流程
随着人工智能技术的发展,阿里体育等公司推出的“乐动力”、“天天跳绳”等AI运动APP备受关注。本文将引导您从零开始开发一个AI运动小程序,使用“云智AI运动识别小程序插件”。文章介绍了视频帧、帧率FPS、抽帧和人体识别等基本概念,并详细说明了处理流程,包括抽帧、人体识别检测、骨骼图绘制和运动分析等步骤。下篇将介绍如何在小程序中实现抽帧。

热门文章

最新文章

下一篇
无影云桌面