前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >优雅地实现滚动容器遮罩

优雅地实现滚动容器遮罩

作者头像
戴兜
发布2023-12-10 10:37:56
1780
发布2023-12-10 10:37:56
举报
文章被收录于专栏:daidrdaidr

在设计前端页面时,常常会遇到这种情况:可滚动容器的边界并非父容器的边界,导致子元素溢出造成裁切,让页面产生比较怪异的视觉效果(左图)

添加遮罩之后,效果自然了许多(右图)

纯色遮罩

以上图的这种情况举例,我们需要做的,是在可滚动容器的顶部和底部分别放置一个线性渐变的纯色遮罩,遮挡生硬的裁切线。创建两个元素 .top-mask.bottom-mask 来作为遮罩,遮罩的颜色与父容器背景一致,使用 absolute 定位。

代码语言:javascript
复制
.top-mask {

    position: absolute;

    top: 0;

    left: 0;

    right: 0;

    height: 24px;

    background: linear-gradient(to top, transparent 0%, white 100%);

}



.bottom-mask {

    position: absolute;

    bottom: 0;

    left: 0;

    right: 0;

    height: 24px;

    background: linear-gradient(to bottom, transparent 0%, white 100%);

}

直接为可滚动容器设置 position: relative 是行不通的,这会导致遮罩跟随容器滚动。所以需要在可滚动容器外部再嵌套一层 relative 定位的元素,使两个遮罩根据其位置定位,最终的结构大概是下面这样的:

代码语言:javascript
复制
<!-- 无遮罩 -->

<div class="out-container">

    <div class="scrollable-container">

        <!-- 很多很多的子元素 -->

    </div>

</div>



<!-- 有遮罩 -->

<div class="out-container">

    <div class="relative-container">

        <div class="top-mask"></div>

        <div class="bottom-mask"></div>

        <div class="scrollable-container">

            <!-- 很多很多的子元素 -->

        </div>

    </div>

</div>

Codepen 查看演示

后续为了优化视觉效果,可以根据条件显示/隐藏对应的 mask 元素(滚动条在顶部时不显示 top-mask,反之亦然)

改进:Alpha 遮罩

上面的这种方法有许多缺陷:

  1. 引入了许多额外的元素,致使整体布局变得复杂。
  2. 蒙版覆盖在可滚动容器之上,需要使用 pointer-events: none; 避免影响滚动操作。
  3. 仅适用于父容器为纯色的场景,在父容器有透明度、有背景图案或渐变时,遮罩会露馅。

是否有一种方法,在不引入额外元素、不使用绝对定位的条件下,解决这些缺陷呢?这时候就可以用到 mask CSS属性。mask 属性允许提供一张图片作为蒙版,改变元素的可视区域。我们只需要生成一个线性渐变,将其作为可滚动容器的蒙版即可。

使用linear-gradient创建一个多段的线性渐变,得到图中的蒙版效果。

代码语言:javascript
复制
linear-gradient(to bottom, transparent 0%, white 25px, white calc(100% - 25px), transparent 100%)

接着,将得到的渐变图案作为 mask 应用到滚动容器上,为了便于自定义,将这里的遮罩高度 25px 提取出来,以 CSS 变量的形式提供。下面是完整的样式:

代码语言:javascript
复制
.scrollable-container {

  --show-top-mask: 0;

  --show-bottom-mask: 0;

  --mask-size: 25px;

  --gradient: linear-gradient(to bottom, transparent 0%, white calc(var(--show-top-mask) * var(--mask-size)),white calc(100% - calc(var(--mask-size)*var(--show-bottom-mask))), transparent 100%);

  -webkit-mask: var(--gradient);

  mask: var(--gradient);

}



.top-mask {

  --show-top-mask: 1;

}



.bottom-mask {

  --show-bottom-mask: 1;

}

因为我们将容器两侧的遮罩合并到了一个线性渐变中,想要控制其中一侧的遮罩就不太容易了,为了实现遮罩的独立控制,额外定义了 --show-top-mask--show-bottom-mask 变量。最终的效果如下图所示:

CodePen 查看

code{background: #f5f2f0;}

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 纯色遮罩
  • 改进:Alpha 遮罩
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档