网页适老化

背景

最近在做的项目有老年人模式的需求——也就是动态切换字体大小、元素间距等。

解决方案

项目使用element-uisasssass-loader,在scss文件中定义变量,并利用:export导出变量,供JS使用。JS中读取变量,使用setProperty方法设置全局css变量。项目中所有需要动态改变大小的,都不直接使用px,而是使用css变量进行设置。

使用开关动态切换常规/老年人模式变量,以切换全局css变量值。

以下是代码的实现:

目录结构

1
2
3
4
5
6
src
├── styles
│ ├── index.scss
│ ├── variables.scss
│ └── variables-senior.scss
└── App.vue

关键代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/* variables.scss */

/* 无需动态改变的常量 */
$main_color: #4077f4;
// ...

/* 差异化变量 */
$variables: (
// 字号
font_size_extra_large: 20px,
font_size_large: 18px,
font_size_medium: 16px,
font_size_base: 14px,
font_size_small: 13px,
font_size_extra_small: 12px,
// checkbox
checkbox_after_left: 4px,
checkbox_after_top: 1px,
// 表单项
form_item_margin_bottom: 16px,
search_btn_width: 70px,
search_btn_detail_width: 60px
);
:export {
/* 常量部分 */
main_color: $main_color;
// ...

/* 变量自动导出 */
@each $name, $value in $variables {
#{$name}: #{$value};
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/* variables-senior.scss */

// 字体增量,可以统一控制放大倍率
$font_size_increment: 5px;

/* 差异化变量 */
$variables: (
// 字号
font_size_extra_large: 20px + $font_size_increment,
font_size_large: 18px + $font_size_increment,
font_size_medium: 16px + $font_size_increment,
font_size_base: 14px + $font_size_increment,
font_size_small: 13px + $font_size_increment,
font_size_extra_small: 12px + $font_size_increment,
// checkbox
checkbox_after_left: 6px,
checkbox_after_top: 3px,
// 表单项
form_item_margin_bottom: 24px,
search_btn_width: 80px,
search_btn_detail_width: 80px
);
:export {
/* 变量自动导出 */
@each $name, $value in $variables {
#{$name}: #{$value};
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!-- 有的元素不能仅用变量控制,这时候就需要使用class .senior-mode,调整元素在老年人模式下的表现 -->
<template>
<div id="app" :class="{ 'senior-mode': isSeniorMode }">
<el-switch v-model="isSeniorMode" @change="toggleMode">
老年人模式
</el-switch>
<router-view />
</div>
</template>
<script>
import normalVariables from "@/styles/variables.scss"
import seniorVariables from "@/styles/variables-senior.scss"
export default {
name: "app",
data() {
return {
isSeniorMode: false,
}
},
mounted() {
this.setMode()
},
methods: {
toggleMode() {
this.setMode(this.isSeniorMode)
},
setMode(isSenior = false) {
const vars = isSenior ? seniorVariables : normalVariables
for (const [key, value] of Object.entries(vars)) {
document.documentElement.style.setProperty(`--${key}`, value)
}
}
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
/* style/index.scss */
.el-button {
font-size: var(--font_size_base);
&--mini {
font-size: var(--font_size_extra_small);
}
&--small {
font-size: var(--font_size_base);
}
&--medium {
font-size: var(--font_size_medium);
}
}

结语

这个方案的效果还是比较满意的,衍生出来还可以封装成组件,实现大中小三种字号切换的模式