0


前端实现输入金额带单位提示及 box-shadow和drop-shadow 对比思考

项目中要求金额输入框实现单位提示,在输入指定位数后,左上角分别提示百、千、万、十万、百万、千万、亿……,效果如下图所示,原来以为很容易就实现了,实际操作后,发现还有一丢丢门道需要注意。

image-20241114155935358

大概分为以下几点的实现思路:

  • 使用定位将单位提示放在上方,采用阴影样式实现凸起样式,box-shadow 还是 filter +drop-shadow
  • 三角形使用 border 实现,使用伪元素添加三角,避免在 dom 中增加新的节点

box-shadow vs filter +drop-shadow

box-shadow

用法:

box-shadow: x-shadow y-shadow blur spread color inset || none; // 默认为null

值描述x-shadow必需。水平阴影的位置。允许负值y-shadow必需。垂直阴影的位置。允许负值blur可选。模糊半径。值越大,阴影越大越模糊。若未指定,默认为

0

,产生清晰、不模糊的边缘。不允许有负值。spread可选,阴影的扩展半径。取正值时,阴影扩大;取负值时,阴影收缩。默认为 0,此时阴影与元素同样大color可选。阴影的颜色inset可选。将外部阴影outset改为内部阴影
注意:默认是外阴影,但不可以写outset,否则导致 阴影无效;阴影不占用空间,不影响其他盒子;

drop-shadow

用法:

filter: drop-shadow(x-shadow y-shadow blur spread color);

值描述x-shadow必需。水平阴影的位置。允许负值y-shadow必需。垂直阴影的位置。允许负值blur可选。模糊半径。值越大,阴影越大越模糊。若未指定,默认为

0

,产生清晰、不模糊的边缘。不允许有负值。spread可选,阴影的扩展半径。取正值时,阴影扩大;取负值时,阴影收缩。默认为 0,此时阴影与元素同样大。大多数浏览器不支持这个参数;如果使用,效果将不会呈现。color可选。阴影的颜色

两者差异

1、兼容性不一样。CSS3

box-shadow

从IE9浏览器开始就支持了,

filter 

中的

drop-shadow

IE13开始支持

2、同样的参数值,表现效果有差异,

box-shadow

的阴影距离更小,色值要更深

使用同样参数右下5像素偏移,10像素模糊的黑色阴影

5px 5px 10px black

, 两种实现效果差异如下:

<style>.box{margin: 50px;line-height: 120px;text-align: center;width: 120px;height: 120px;background-color: antiquewhite;}.box-shadow{box-shadow: 5px 10px 10px black;}.drop-shadow{filter:drop-shadow(5px 10px 10px black);}</style><body><divclass="box box-shadow">box-shadow</div><divclass="box drop-shadow">drop-shadow</div></body>

image-20241115150801937
3、drop-shadow没有内阴影效果

4、drop-shadow 不能阴影叠加,而box-shadow可以多个阴影叠加,例如:

box-shadow: 2px 0 2px 2px #ccc, -2px 0 2px 2px #ccc; // 左右两边有阴影

5、box-shadow 是盒阴影,不能穿透,而 drop-shadow 是投影,可以穿透透明的区域。
image-20241115154626044

阴影实现

上文写了 box-shadow 和 drop-shadow 的区别,盒阴影和投影。

而三角是使用

border

绘制的,没法

box-shadow

,但三角如果没有阴影,就会被同色系的 van-filed 完美隐藏,达不到开头示意图展示效果了。除非箭头处的颜色和底色背景选择不同色,如下图所示。

没有阴影的三角

所以采用 filter + drop-shadow 实现

指示三角形

html 结构,使用

van-field

实现

<div class="money-container">
    <van-field
        v-model="money"
        type="number"
        label="金额"
    />
<div v-if="moneyUnit" class="money-unit">{{ moneyUnit }}</div>

使用伪元素实现三角形:

.money-container {
    position: relative;
    .money-unit {
        padding: 0 14px;
        height: 40px;
          line-height: 40px;
        border-radius: 6px;
        text-align: center;
        background-color: #fff;
        position: absolute;
        left: 7em;
        top: -20px;
          /* 下文介绍实现 */
        transform: translateZ(0);
        filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.1));
        &::before {
            content: '';
            position: absolute;
            left: 50%;
            bottom: 0;
            width: 0;
            height: 0;
            border-color: transparent;
            border-style: solid;
            border-width: 10px;
            border-top-color: #fff;
            transform: translate(-50%, 100%);
        }
    }
}

最终实现效果

输入金额带单位提示

drop-shadow 在 ios 渲染问题

问题原因和解决

在 pc 端测试正常,在 iPhone 打开页面发现会出现以下情况,单位从有到无,或者单位框框宽度由大变小时,会出现阴影仍然存在的情况。

drop-shadow 在 ios 渲染问题

解决办法:加上 transform: translateZ(0); 添加到gpu复合层渲染就正常了。

复合图层介绍

CPU 和 GPU:CPU 即中央处理器,GPU 即图形处理器。

定义:

  • 渲染图层:是页面的普通的文档流,我们虽然可以使用绝对定位相对定位来脱离文档流,但是它仍属于默认复合层,都公用同一个绘画上下文对象
  • 复合图层:它会单独分配系统资源,每个复合图层都有一个独立的GraphicsContext(当然也会脱离文档流,这样一来,不管复合图层中如何变化,都不会影响默认图层内的重绘重排),硬件加速就用在了这里

如何创建复合图层:

可以

Chrome源码调试 -> More Tools -> Rendering -> Layer borders

中看到,黄色的就是复合图层信息。

  1. translate3D 或者 translateZ
  2. opacity属性/过渡动画(需要动画执行的过程中才会创建合成层,动画没有开始或结束后元素还会回到之前的状态)
  3. will-chang属性(这个比较偏僻),一般配合opacity与translate使用。作用是提前告诉浏览器要变化,这样浏览器会开始做一些优化工作(这个最好用完后就释放)
  4. video/iframe/canvas/webgl 等元素

复合图层的优点

  1. 合成层的位图,会交由 GPU 合成,比 CPU 处理要快
  2. 当需要 repaint 时,只需要 repaint 本身,不会影响到其他的层
  3. 对于 transform 和 opacity 效果,不会触发 layout 和 paint

最大的优点:形成复合图层之后,和其他的复合图层是相对独立的,内部元素发生重排或者重绘的时候,不会影响其他复合层的元素

复合图层的注意点

  1. 创建复合图层是一个相对比较占资源的操作。所以在创建复合图层的时候,要考虑是否会得不偿失。
  2. 层爆炸现象。也就是页面中不可预期的产生了很多复合层,导致大量占用内存。产生这种情况的原因可能是在给某个元素添加复合图层的时候,这个元素的层级比较低,那么在这个元素的后面其它元素(层级比这个元素高的,或者相同的,并且releative或absolute属性相同的), 会默认变为复合层渲染

所以在创建复合图层的时候,最好给元素加上一个z-index属性,提高元素的层级。避免创建多余的复合图层。

absolute和复合图层的区别

absolute虽然脱离了文档流,但是并不能创建一个单独的复合图层,也就是说还是在默认的复合图层中的。所以,就算absolute中信息改变时不会改变普通文档流中 render 树, 但是,浏览器最终绘制时,是整个复合层绘制的,所以absolute中信息的改变,仍然会影响整个复合层的绘制。

所以如果复合层中的节点很多的时候,绘制整个复合层也是相当耗费资源的,所以这时就要考虑给元素创建新的复合图层。

reference

CSS3 box-shadow盒阴影图形生成技术

IOS真机下动态修改filter:drop-shadow导致的渲染异常问题

复合图层,渲染图层及性能优化

谈谈复合图层

标签: 前端

本文转载自: https://blog.csdn.net/qq_34630087/article/details/143805438
版权归原作者 攒一筐小丸子 所有, 如有侵权,请联系我们删除。

“前端实现输入金额带单位提示及 box-shadow和drop-shadow 对比思考”的评论:

还没有评论