惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tailwind CSS Blog
大猫的无限游戏
大猫的无限游戏
L
LINUX DO - 热门话题
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
aimingoo的专栏
aimingoo的专栏
博客园_首页
MongoDB | Blog
MongoDB | Blog
V
V2EX
GbyAI
GbyAI
量子位
Microsoft Azure Blog
Microsoft Azure Blog
有赞技术团队
有赞技术团队
G
Google Developers Blog
云风的 BLOG
云风的 BLOG
B
Blog
Microsoft Security Blog
Microsoft Security Blog
S
SegmentFault 最新的问题
O
OpenAI News
N
News and Events Feed by Topic
博客园 - Franky
爱范儿
爱范儿
Forbes - Security
Forbes - Security
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V2EX - 技术
V2EX - 技术
Application and Cybersecurity Blog
Application and Cybersecurity Blog
N
News and Events Feed by Topic
N
News | PayPal Newsroom
Schneier on Security
Schneier on Security
Cloudbric
Cloudbric
Security Archives - TechRepublic
Security Archives - TechRepublic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Recent Commits to openclaw:main
Recent Commits to openclaw:main
人人都是产品经理
人人都是产品经理
P
Privacy International News Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog RSS Feed
阮一峰的网络日志
阮一峰的网络日志
D
DataBreaches.Net
Last Week in AI
Last Week in AI
罗磊的独立博客
Spread Privacy
Spread Privacy
Recent Announcements
Recent Announcements
The Cloudflare Blog
Google DeepMind News
Google DeepMind News
AWS News Blog
AWS News Blog
The Register - Security
The Register - Security
Y
Y Combinator Blog
J
Java Code Geeks
I
Intezer

张鑫旭-鑫空间-鑫生活

1分钟速度了解text-align match-parent声明 « 张鑫旭-鑫空间-鑫生活 光标的形状也能设置了,就是CSS caret-shape属性 « 张鑫旭-鑫空间-鑫生活 pretext与文字四面环绕效果的实现 « 张鑫旭-鑫空间-鑫生活 JSON.rawJSON方法的作用是什么? « 张鑫旭-鑫空间-鑫生活 如何使用CSS判断鼠标从哪个方向进入元素? « 张鑫旭-鑫空间-鑫生活 借助mediabunny纯JS实现视频水印、剪裁、合成等功能 « 张鑫旭-鑫空间-鑫生活 务必谨慎使用JS WeakRef弱引用 « 张鑫旭-鑫空间-鑫生活 CSS六边形头像的实现与蜂巢布局 « 张鑫旭-鑫空间-鑫生活 CSS corner-shape与背景底纹技术 « 张鑫旭-鑫空间-鑫生活 浅学WebTransport API:下一代Web双向通信技术 « 张鑫旭-鑫空间-鑫生活 HTML dialog元素新支持了closedBy属性 « 张鑫旭-鑫空间-鑫生活 HTML interestfor属性与悬停popover交互效果 « 张鑫旭-鑫空间-鑫生活 CSS3模拟window7炫酷界面效果展示 « 张鑫旭-鑫空间-鑫生活 图片旋转+剪裁js插件(兼容各浏览器) « 张鑫旭-鑫空间-鑫生活 纯js无图片无外链CSS图片幻灯片播放插件 « 张鑫旭-鑫空间-鑫生活 CSS border三角、圆角图形生成技术简介 « 张鑫旭-鑫空间-鑫生活 CSS “渐进增强”在web制作中常见应用举例 « 张鑫旭-鑫空间-鑫生活 让IE6/IE7/IE8浏览器支持CSS3属性 « 张鑫旭-鑫空间-鑫生活 jQuery – 高亮动态显示页面HTML代码插件 « 张鑫旭-鑫空间-鑫生活 翻译 – 逐渐消失的Flash网站 « 张鑫旭-鑫空间-鑫生活 CSS reset的重新审视 – 避免样式重置 « 张鑫旭-鑫空间-鑫生活 新浪微博插入话题后部分文字选中的js实现 « 张鑫旭-鑫空间-鑫生活 JavaScript实现http地址自动检测并添加URL链接 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变背景(gradient)效果 « 张鑫旭-鑫空间-鑫生活 CSS content内容生成技术以及应用 « 张鑫旭-鑫空间-鑫生活 CSS gradient渐变之webkit核心浏览器下的使用 « 张鑫旭-鑫空间-鑫生活 CSS渐变之CSS3 gradient在Firefox3.6下的使用 « 张鑫旭-鑫空间-鑫生活 区分IE8/IE7/IE6及其他浏览器-CSS “\9″hack « 张鑫旭-鑫空间-鑫生活 CSS实现跨浏览器兼容性的盒阴影效果 « 张鑫旭-鑫空间-鑫生活 CSS3&HTML5各浏览器支持情况一览表 « 张鑫旭-鑫空间-鑫生活 翻译 – CSS Sprites:实用技术还是生厌之物? « 张鑫旭-鑫空间-鑫生活 纯CSS实现易拉罐3D滚动效果 « 张鑫旭-鑫空间-鑫生活 纯CSS实现侧边栏/分栏高度自动相等 « 张鑫旭-鑫空间-鑫生活 CSS+JavaScript实现页面不同布局的切换 « 张鑫旭-鑫空间-鑫生活 JavaScript实现最简单的拖拽效果 « 张鑫旭-鑫空间-鑫生活 自己写的无图片版jQuery zxxbox弹出框插件 « 张鑫旭-鑫空间-鑫生活 中国古代道家思想与网页重构的思考 « 张鑫旭-鑫空间-鑫生活 让所有浏览器支持HTML5 video视频标签 « 张鑫旭-鑫空间-鑫生活 纯CSS实现各类气球泡泡对话框效果 « 张鑫旭-鑫空间-鑫生活 JS HEX十六进制与RGB, HSL颜色的相互转换 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变、高光等文字效果 « 张鑫旭-鑫空间-鑫生活 去除冗余 – 精简您的CSS样式代码 « 张鑫旭-鑫空间-鑫生活 对overflow与zoom”清除浮动”的一些认识 « 张鑫旭-鑫空间-鑫生活 jQuery Pagination Ajax分页插件中文详解 « 张鑫旭-鑫空间-鑫生活 absolute绝对定位的非绝对定位用法 « 张鑫旭-鑫空间-鑫生活 网页布局思想浅议-淘宝新版首页为实例 « 张鑫旭-鑫空间-鑫生活 回流与重绘:CSS性能让JavaScript变慢? « 张鑫旭-鑫空间-鑫生活 CSS float浮动的深入研究、详解及拓展(二) « 张鑫旭-鑫空间-鑫生活 CSS float浮动的深入研究、详解及拓展(一) « 张鑫旭-鑫空间-鑫生活 60个极富创造性的震撼的电影海报设计 « 张鑫旭-鑫空间-鑫生活 jQuery Lightbox(balupton版)图片展示插件讲解 « 张鑫旭-鑫空间-鑫生活 博客内嵌flash音乐播放器代码、下载与使用 « 张鑫旭-鑫空间-鑫生活 CSS3 animate实现图片墙3D翻转效果 « 张鑫旭-鑫空间-鑫生活 图片旋转效果的一些研究、jQuery插件及实例 « 张鑫旭-鑫空间-鑫生活 CSS3 border-image详解、应用及jQuery插件 « 张鑫旭-鑫空间-鑫生活 jQuery-两款不同原理的圆角插件讲解 « 张鑫旭-鑫空间-鑫生活 页面可用性之outline轮廓外框的一些研究 « 张鑫旭-鑫空间-鑫生活 CSS3 transition实现超酷图片墙动画效果 « 张鑫旭-鑫空间-鑫生活 HTML CSS列表元素ul,ol,dl的研究与应用 « 张鑫旭-鑫空间-鑫生活 jQuery图片文本滚动切换插件jCarousel中文翻译与详解 « 张鑫旭-鑫空间-鑫生活 酷酷的jQuery鼠标悬停图片放大切换显示效果 « 张鑫旭-鑫空间-鑫生活 IE6下z-index犯癫不起作用bug的初步研究 « 张鑫旭-鑫空间-鑫生活 checkbox复选框的一些深入研究与理解 « 张鑫旭-鑫空间-鑫生活 jQuery之使用slideToggle实现垂直下拉菜单 « 张鑫旭-鑫空间-鑫生活 jQuery-innerfade内部列表自动淡入淡出插件 « 张鑫旭-鑫空间-鑫生活 jQuery-火焰灯效果导航菜单 « 张鑫旭-鑫空间-鑫生活 IE下css bug集合-翻译自haslayout.net « 张鑫旭-鑫空间-鑫生活 翻译-IE7/8@font-face嵌入字体与文字平滑 « 张鑫旭-鑫空间-鑫生活 jQuery-马化腾产品设计与用户体验的一些技术实现 « 张鑫旭-鑫空间-鑫生活 像素的世界及其在web开发制作中的应用 « 张鑫旭-鑫空间-鑫生活 css行高line-height的一些深入理解及应用 « 张鑫旭-鑫空间-鑫生活 CSS实现圆角六色渐变自适应按钮详解 « 张鑫旭-鑫空间-鑫生活 我熟知的三种三栏网页宽度自适应布局方法 « 张鑫旭-鑫空间-鑫生活 jQuery照片图像剪裁插件Jcrop中文翻译详解 « 张鑫旭-鑫空间-鑫生活 Ajax Upload多文件上传插件翻译及中文演示 « 张鑫旭-鑫空间-鑫生活 告别图片—使用字符实现兼容性的圆角尖角效果beta版 « 张鑫旭-鑫空间-鑫生活 大小不固定的图片、多行文字的水平垂直居中 « 张鑫旭-鑫空间-鑫生活 jQuery boxy弹出层对话框插件中文演示及讲解 « 张鑫旭-鑫空间-鑫生活 JavaScript实现新浪微博文字放大显示动画效果 « 张鑫旭-鑫空间-鑫生活 翻译:让网络更快一些——最小化浏览器中的回流(reflow) « 张鑫旭-鑫空间-鑫生活 jQuery之addClasas与removeClass使用实例 « 张鑫旭-鑫空间-鑫生活 关于Google圆角高光高宽自适应按钮及其拓展 « 张鑫旭-鑫空间-鑫生活 JavaScript实现图片幻灯片滚动播放动画效果 « 张鑫旭-鑫空间-鑫生活 jQuery-鼠标经过显示大图并跟随鼠标效果插件 « 张鑫旭-鑫空间-鑫生活 关于gif图片(或png8)杂边锯齿的问题 « 张鑫旭-鑫空间-鑫生活 对html与body的一些研究与理解 « 张鑫旭-鑫空间-鑫生活 鲜为人知的一个解决兼容性问题的利器——小数 « 张鑫旭-鑫空间-鑫生活 搜狐白社会似iphone短信对话框效果的优化 « 张鑫旭-鑫空间-鑫生活 关于文字内容溢出用点点点(…)省略号表示 « 张鑫旭-鑫空间-鑫生活 jquery之append与insertBefore使用实例 « 张鑫旭-鑫空间-鑫生活 jQuery之图片关联伸缩效果 « 张鑫旭-鑫空间-鑫生活 jquery之图片左右切换动画效果 « 张鑫旭-鑫空间-鑫生活 jQuery之replace字符串替换实现不同尺寸图片切换 « 张鑫旭-鑫空间-鑫生活 jQuery-实现图片的放大镜显示效果 « 张鑫旭-鑫空间-鑫生活 jQuery-单击文字或图片内容放大显示效果插件 « 张鑫旭-鑫空间-鑫生活 reflection.js-实现图片投影倒影效果js插件 « 张鑫旭-鑫空间-鑫生活 jQuery-很酷的弹出层效果js插件 « 张鑫旭-鑫空间-鑫生活 复选框单选框与文字对齐问题的研究与解决 « 张鑫旭-鑫空间-鑫生活 css margin的相关属性,问题及应用 « 张鑫旭-鑫空间-鑫生活 IE6下png背景不透明问题的综合拓展 « 张鑫旭-鑫空间-鑫生活
密码强度效果最佳实现一定是HTML meter元素 « 张鑫旭-鑫空间-鑫生活
张鑫旭,zhangxinxu · 2021-11-14 · via 张鑫旭-鑫空间-鑫生活

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=10188 鑫空间-鑫生活
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

注册时候密码输入框显示密码强度是个很常见的交互效果,例如下面找的效果截图:

密码强度截图

这种效果实现最好的方法一定是使用 HTML <meter> 元素,无论是跟随强度的 UI 色值变化,还是弱中强的文字提示,都是可以使用纯 CSS 实现,无需 JS 去控制 DOM 的色值与尺寸变化。

一、先看实现效果

下面两张图就是最终在浏览器中实现的效果。

Chrome 浏览器下:

密码提示强弱

Safari 浏览器下:

Safari浏览器下截图

眼见为实,您可以狠狠的点击这里:meter元素与密码强度实现demo

接下来一步一步带大家了解具体的实现过程,先从了解 <meter> 元素开始。

二、meter 元素基本特性与效果

单词 meter 直译意思是“计量器”,“计量表”,因此,在 Web 中,任何与丈量相关,同时需要分阶段提示的场景都非常使用使用 <meter> 元素。

例如汽车油箱剩余油量,降雨量,风度,温度,游戏中人物角色的血量等。

先看下面一段代码:

生命值:<meter min="0" max="100" low="30" high="60" optimum="80" value="20"></meter>
生命值:<meter min="0" max="100" low="30" high="60" optimum="80" value="50"></meter>
生命值:<meter min="0" max="100" low="30" high="60" optimum="80" value="70"></meter>

在现代浏览器下就会有如下图所示的 UI 效果。

meter基本效果

下面则是实时渲染效果,大家可以看下自己当前访问设备中的效果:

生命值:

生命值:

生命值:

其中出现了 6 个 HTML 属性,正好涵盖了 <meter> 元素所有常用属性。

属性简介

  • minmax 属性表示数值范围,默认是 0-1,也就是如果 min 属性如果不设置,则认为是 0,max 属性不设置则认为是 1。
  • value 表示当前的值,默认是 0。
  • lowhigh 是比较特殊的 HTML 属性,目前仅出现在 <meter> 元素上,表示警戒值,其中 low 表示过低警戒值,high 表示过高警戒值。

    但是,大家务必注意,过低还是过高是否需要警戒还需要一个属性进行判定,那就是 optimum 属性。

  • optimum 属性表示最佳值,用来决定过低和过高值属于正常还是异常,这个属性很重要,也是 <meter> 元素学习的难点。

optimum 属性

optimum 属性的作用表现描述如下:

  • 如果 optimum 属性值在 lowhigh 之间,则说明 lowhigh 都是警戒值,只有在这个区间范围的值才是正常的,因此,最终的色值状态只会有两个,即橙色警戒和绿色正常。

    代码示意:

    生命值:<meter max="100" low="30" high="60" optimum="50" value="20"></meter>
    生命值:<meter max="100" low="30" high="60" optimum="50" value="50"></meter>
    生命值:<meter max="100" low="30" high="60" optimum="50" value="70"></meter>

    效果如下图所示,最多只会出现两种颜色。

    两种色值

  • 如果 optimum 属性值比 low 还要小,则说明 low 并不是警戒线,反而是推荐线,也就是越小反而越高,此时,low-high 之间的范围就属于警戒,而超过 high 的值就属于危险了。

    于是,最终 <meter> 元素可以有 3 段色值状态,HTML 代码示意:

    生命值:<meter max="100" low="30" high="60" optimum="20" value="20"></meter>
    生命值:<meter max="100" low="30" high="60" optimum="20" value="50"></meter>
    生命值:<meter max="100" low="30" high="60" optimum="20" value="70"></meter>

    meter 三段色值演示

  • 如果 optimum 属性值比 high 还要大,也会出现 3 段色值状态,此时,大于 high 的值会被认为是正常的,因此表现为绿色,这个效果,就是一开始那个例子所演示的那个效果,代码和截图效果是这样的:
    生命值:<meter max="100" low="30" high="60" optimum="80" value="20"></meter>
    生命值:<meter max="100" low="30" high="60" optimum="80" value="50"></meter>
    生命值:<meter max="100" low="30" high="60" optimum="80" value="70"></meter>

    meter基本效果

回到本文这里,由于密码强度越强越好,因此,很显然,需要设置 optimum 属性值比 high 还要大。

但是,我们需要的是下图这样的效果,需要明显分段的,而浏览器默认的 <meter> 元素效果就是个色条,不符合产品需求,那有没有什么办法自定义 UI 呢?

目标密码强度效果

二、meter 元素的样式自定义

在现代浏览器下,<meter> 元素提供了若干伪元素,可以让我们对 <meter> 元素进行样式自定义。

其中,Chrome 浏览器和 Safari 浏览器可以使用的伪元素非常丰富,Firefox 浏览器相对少一些。

这里,主要以 Chrome 浏览器示意。

所有可以设置 <meter> 元素的选择器包括下面这些:

  • meter 元素自身选择器;
  • ::-webkit-meter-inner-element {}
  • ::-webkit-meter-bar {} 灰色背景条。
  • ::-webkit-meter-even-less-good-value {} 红色。
  • ::-webkit-meter-optimum-value {} 橙色。
  • ::-webkit-meter-suboptimum-value {} 绿色。

各个伪元素所对应的 DOM 层级结构如下图所示:

伪元素结构

使用字符图形表示是这样的:

meter
  |-- ::-webkit-meter-inner-element
    |-- ::-webkit-meter-bar
      |-- ::-webkit-meter-even-less-good-value  -|
      |-- ::-webkit-meter-suboptimum-value      -|--> 只会同时出现1个
      |-- ::-webkit-meter-optimum-value         -|

所以,我们就可以使用上面的伪元素实现我们想要的 UI 效果了。

然而,事情并没有预想的那么简单。

  1. 密码强度如何确定?
  2. 表示 3 个颜色的伪元素最多只会出现 1 个,而我们的目标效果却是 3 色同时显示,另外,默认的色值是连续的,而需要的效果是分段的,该怎么实现呢?
  3. 强度色块下面还有“弱 中 强”的文字提示,这个布局效果又该如何实现呢?

关于这些实现难点,我们一个一个来看下,其中不乏一些有创意的实现技巧。

//zxx: 如果你看到这段文字,说明你现在访问是不是原文站点,更好的阅读体验在这里:https://www.zhangxinxu.com/wordpress/?p=10188(作者张鑫旭)

四、密码强度的计算

密码强度的计算直接使用开源的公认的算法就可以了,比方说 zxcvbn:https://github.com/dropbox/zxcvbn

使用也相当简单,引入然后执行,示意:

<script src="https://cdn.bootcdn.net/ajax/libs/zxcvbn/4.4.2/zxcvbn.js"></script>
<script>
    let objResult = zxcvbn('your password');
</script>

其中 objResult 包含下面这些属性:

{
    guesses: Number
    guesses_log10: Number
    score: Number (0-4)
    crack_times_seconds: Object (不同运算力下的破解时间,数值展示)
    crack_times_display: Object (不同运算力下的破解时间,字符描述展示)
    sequence: Array 验证序列
    feedback: 反馈与建议
    calc_time: zxcvbn 计算此密码强度花费的时间,单位是毫秒 ms
}

截图示意:
运行结果

其中,与密码强度直接相关的是:guesses、guesses_log10 和 score。

其中,score 范围是 0-4,数值越大,密码越安全,虽然也能解决强度的判断,但是体现在 <meter> 元素上就没有了丰度的 value 变化,视觉效果也不咋地。

因此,在本文所描述的场景下,我们使用 guesses_log10 作为我们的强度判断值。

根据我的测试,guesses_log10 的值在 12 以上,密码强度就已经很 Strong 了,考虑到弱中强三种状态的色条范围是三等分的,因此,最终的 <meter> 元素的高低值如下所示:

<meter min="0" max="12" low="4" high="8" optimum="10"></meter>

相关 JS 代码则是这样子的:

meter.value = zxcvbn('paddworld').guesses_log10;

剩下的视觉表现的工作全部都交给 CSS 好了。

五、最终样式实现的细节

1. 背景条的样式

首先,我们确定个尺寸,假设 长度是 120px,高度是 12px:

::-webkit-meter-bar {
    width: 120px;
    height: 12px;
}

浏览器默认的边框效果是不需要的,然后为了兼容性,需要统一背景色,于是有:

::-webkit-meter-bar {
    width: 120px; height: 12px;
    border: 0;
    background: #eee;
}

Firefox 浏览器可以使用 ::-moz-meter-bar 伪元素设置。

2. 色带的实现

浏览器默认的状态都是纯色,从左纯到右,想要变成一个一个的色带,不少人的想法会是叠加,也就是几个 <meter> 元素叠加在一起,其实不需要这么麻烦的,我们使用 CSS 渐变模拟就好了。

例如,进入橙色状态的时候,把前 1/3 部分改成红色(原来是橙色),这样,当状态条从红色变成橙色的时候,就像是无缝添加的,而不是突然替换,绿色这部分也是类似的。

代码示意:

::-webkit-meter-even-less-good-value {
    background: red;
}
::-webkit-meter-suboptimum-value {
    background: linear-gradient(to right, red 40px, orange 0);
}
::-webkit-meter-optimum-value {
    background: linear-gradient(to right, red 40px, orange 0 80px, green 0);
}

::-webkit-meter-optimum-value 伪元素举例,浏览器默认状态下,这个伪元素是纯绿色,这里使用 CSS 渐变重新实现之后,就是 红-橙-绿 三段,很好地模拟了三态强度效果。

最终的效果可以参见下面的 GIF 录屏。

三色模拟效果

3. 中间镂空分隔

上面的 GIF 效果,各个色块是紧密相连的,但是最终需要的效果是彼此之间有间隙,这个该如何实现呢?

方法其实挺多的,我这里选择使用遮罩实现,在色块的容器元素上绘制一个镂空渐变作为遮罩图像:

::-webkit-meter-bar {
    -webkit-mask: linear-gradient(to right, 
      red 39px, 
      transparent 0 41px, 
      orange 0 79px, 
      transparent 0 81px, 
      green 0
    );
}

此时,效果就会是这样:

带间隙的强度效果

4. 文字左中右对齐实现

接下来就是“弱中强”三个文字的效果实现了,如下图:
目标密码强度效果

有人会想到使用一个 <span> 元素和 <meter> 元素包在一起再重定位,这个虽然也能实现,但是 HTML 就啰嗦了,以后也不太好维护。

实际上,直接使用 <meter> 元素就可以实现,方法就是 ::after 伪元素。

meter::after {
    content: '弱中强';
}

效果如下截图所示:

文字显示效果

不过有几个问题,首先,文字占据的尺寸空间,影响了和输入框的垂直对齐,这个好办,设置为绝对定位就可以了:

meter::after {
    content: '弱中强';
    position: absolute;
}

但是,“弱中强”三个字要分别在 3 个颜色片段的中间,这个对齐该怎么实现呢?

我们可以让伪元素宽度充满 <meter> 元素,给文字中间增加空格、末尾增加一串长长的连续英文字符实现:

meter {
    position: relative;    
}
meter::after {
    content: '弱 中 强 aaaaaaaaaaaaaaaaaaaaaa';
    position: absolute;
    left: 0; right: 0;
    /* 两端对齐 */
    text-align: justify;
    /* 隐藏 aaaaaaaaaaaaaaaaaaaaaa */
    height: 20px;
    line-height: 20px;
    overflow: hidden;
}

为什么后面需要一段莫名其妙的 'aaaaaaaaaaaaaaaaaaaaaa' 呢,因为两端对齐效果的实现,处理字符之间有空格,还需要内容超过1行,而连续英文字符默认是不会换行的,因此会作为整体在第 2 行显示,从而让第一行的 “弱中强”三个字两端对齐。

效果如下所示:

文字对齐效果

我猜,有人会说,不对啊,“弱”和“强”两个字需要在色块的中间啊,不是边上。

对,边上是不对的,所以,需要修改下 lefttop 位置微调下(中文字符占据宽度是 1em):

meter {
    position: relative;    
}
meter::after {
    content: '弱 中 强 aaaaaaaaaaaaaaaaaaaaaa';
    position: absolute;
    left: calc(20px - .5em);
    right: calc(20px - .5em);
    /* 两端对齐 */
    text-align: justify;
    /* 隐藏 aaaaaaaaaaaaaaaaaaaaaa */
    height: 20px;
    line-height: 20px;
    overflow: hidden;
}

效果为:

对齐效果

接下来,就是文字变色的实现了。

5. 不同文字不同颜色实现

同一段文字显示不同颜色的技术其实很多很多年前(10年前)就介绍过了,详见:“CSS3下的渐变文字效果实现”,在《CSS新世界》这本书中也有介绍。

这里使用 background-clip:text加 linear-gradient 渐变背景实现的。

meter::after {
    -webkit-text-fill-color: transparent;
    background-image: linear-gradient(to right, 
        red 39px, 
        transparent 0 41px, 
        orange 0 79px, 
        transparent 0 81px, 
        green 0
    );
    -webkit-background-clip: text;
}

再加上一些尺寸和位置的细节调整,于是就有了最终的效果:

最终渐变文字效果

6. Safari 浏览器

好,Chrome 浏览器搞定了,看看 Safari 浏览器下的效果,结果……呃……:

Safari下效果

本以为是safari浏览器不支持,后来研究了一下,发现原来只需要设置外面的meter 元素边框尺寸为0或none就可以触发伪元素重定义了,也就是:

meter {
    border: 0;
}

所有的效果就会出现,如下所示:

密码效果Safari

7. 使用 CSS 变量优化

最后把上面所有的实现整合一下,同时使用css变量优化一下渐变以及尺寸。就会得到如下所示的终极代码:

meter {
     --size: 60px;
     --gradient: linear-gradient(to right, red calc(var(--size) - 1px), transparent 0 calc(var(--size) + 1px), orange 0 calc(var(--size) * 2 - 1px), transparent 0 calc(var(--size) * 2 + 1px), green 0);
    width: calc(3 * var(--size));
    border: 0; /* Safari */
    position: relative;
}
meter::after {
    content: '弱 中 强 aaaaaaaaaaaaaaaaaaaaaa';
    position: absolute;
    font-size: 14px;
    line-height: 20px;
    height: 20px;
    overflow: hidden;
    left: calc(var(--size) / 2 - .5em);
    right: calc(var(--size) / 2 - .5em);
    text-align: justify;
    -webkit-text-fill-color: transparent;
    background: var(--gradient) calc(.5em - var(--size) / 2) / calc(3 * var(--size));
    -webkit-background-clip: text;
}
::-webkit-meter-bar {
    height: 12px;
    width: calc(3 * var(--size));
    border: 0;
    background: #eee;
    -webkit-mask: var(--gradient);
    mask: var(--gradient);
}
::-webkit-meter-even-less-good-value {
    background: red;
}
::-webkit-meter-suboptimum-value {
    background: linear-gradient(to right, red var(--size), orange 0);
}
::-webkit-meter-optimum-value {
    background: linear-gradient(to right, red var(--size), orange 0 calc(2 * var(--size)), green 0);
}

如果想要改变强度测量条元素的宽度,只需要修改CSS自定义属性 --size 的值就可以了。

眼见为实,效果体验

您可以狠狠地点击这里:meter元素自定义效果纯享版demo

进行效果体验。

至此,所有相关实现的介绍都结束了。

六、总结

当然,正如一开始所提到的,<meter> 元素不仅可以用来表示密码强度。在 Web 中,所有与丈量、测量相关的场景,都可以考虑使用这一个 HTML 元素。

有人可能会纠结 IE 浏览器的问题。

毕竟 <meter> 元素的兼容性是这样子的。

meter 元素的兼容性

一种方法是使用polyfill,我这里找了个项目:https://github.com/fisker/meter-polyfill

这个项目的作者可能是国人,因为头像看起来非常熟悉,不过这个 polyfill 项目我自己没试过,所以质量如何并不清楚。

从我自己的角度讲,如果我是遇到这样的场景,我会说服产品直接放弃 IE浏览器,就不用搞什么所谓的密码强度了,本来这种密码强度就是锦上添花的功能,没有的话,也不影响功能。

况且现在 IE 浏览器占比其实非常低了,3%都不到,我不知道其他公司产品怎样的,以及我们开发产品总是要面向未来的,你不能说我当下还有一些 IE 浏览器用户,你就放弃了未来,想想看,现在项目中还有兼容 IE8 浏览器的代码,是不是想吐。

当然,如果产品是个直溜子说服不通,以为工程师就是想偷懒。

那我觉得专门给IE做一个特殊的处理,其实也不需要多大的成本,回头哪天 IE 嗝屁了直接移除就好。

好,巴拉巴拉,断断续续,没想到讲了这么多,这篇文章篇幅又铺出来了,所以就不再啰嗦了。

行文不易,欢迎分享,感谢转发!

本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=10188

(本篇完)