自定义Scrollbar样式-封装复用

81 篇文章 7 订阅

自定义Scrollbar样式


旧题新解,自定义scrollbar样式,是一个前端程序员经常遇到的问题了,答案也是一搜一大堆,滚动条的样式属性:

  • ::-webkit-scrollbar:控制滚动条整体
  • ::-webkit-scrollbar-track:控制滚动条的轨道
  • ::-webkit-scrollbar-thumb:控制滚动条的拖拽部分

以上属性,基本就够我们定义一个好看的滚动条样式了,还有一些不常用的属性:

  • ::-webkit-scrollbar-button:控制滚动条上下(或左右)两端的按钮
  • ::-webkit-scrollbar-track-piece:控制滚动条轨道中未被可拖拽部分覆盖的区域
  • ::-webkit-scrollbar-corner:控制垂直滚动条和水平滚动条交汇的区域

不同的浏览器,样式属性上会有差别,写的时候要注意。


不过这都是老生常谈的话题了,我们现在做一个项目不可能说每个出现滚动条的地方,我们都去把自定义好的样式重新再写一遍。

于是,就出现了样式的封装和复用。

在现在前端框架流行的时代,CSS的预编译框架也为我们提供了样式封装和复用的语法:mixin

当然了,如果只是写个mixin,然后把样式写进去,好像也没啥新意,怎么玩呢?

接下来我就给大家说一下我在写项目时,简单封装过的一个使用scss封装的scrollbarmixin

也不算多高级,有想法的朋友也可以在此基础上继续扩展,小生献丑了。


进入正文

友情提示1:得有一定的scss语法基础哦,less也行,基本也能看懂,如果二者都没有,那么有些用法可能会看不懂。

友情提示2:完整的文件代码我会放到文章最后,有需要的自取。

入口函数

首先,定义一个scrollbarmixin这是基础:

@mixin scrollbar {}

其次就要想了,样式的封装和复用本质和封装一个函数没啥区别嘛,所以,为了人人可用,我们还需要让使用者提供自己的名字即传类名进来:

@mixin scrollbar($class) {}

参数处理

再想一下,传了类名就完了吗?

  • 我经常碰到一个问题,那就是我自己在使用我写的scrollbar这个mixin时,我有时会纠结,我要传的$class参数是个啥样的?是传一个.abc呢,还是直接传abc呢?

  • 我经常会忘,所以每次都得翻看之前怎么写的,或者看看mixin中的定义,很烦。

由此,为了应对这种情况,我们还需要有能自动帮我们处理$class这个传入的类名参数的逻辑,那就在写一个函数吧,毕竟封装就要做到逻辑清晰-功能单一

@use "sass:string";

@function classHandle($class) {}

封装这个函数要用到scss的内置模块string,通过@use引入即可。

PS:

string内置模块包含了很多函数包,比如:

  • quote函数,可以将传入的参数作为带引号的字符串返回。
  • slice可以进行字符串剪切.
  • unquote可以将字符串进行反解析,变成不带引号的字符串返回。

想深入了解的,可以去scss官网学习下,目前了解这么多就够用了。

这个函数长这样:

@use "sass:string";
@function classHandle($class) {
  $c: string.quote($class);

  @if string.slice($c, 1, 1)==string.quote(".") {
    @return string.unquote($c);
  }
  @else {
    @return string.unquote(".#{$c}");
  }
}

这简单的逻辑,应该不用我多讲了吧:

  • 将参数转换为字符串,定义一个变量接收一下,然后对字符串第一位剪切,判断是不是.,然后就是是否拼接.,然后返回处理结果。

到此为止,类名参数的处理算是完成了。

样式添加

接下来要做的就是把样式添加进去了。

那添加之前我们要考虑一个问题,你说有没有滚动条是不需要我们定义颜色的?

我在使用ant-designtable组件的时候就碰到了这个问题,我只需要改变这个滚动条的宽高就好了,不需要设置样式,那如果我们把这些样式添加的逻辑写到一起,是不是会比较难搞,所以怎么办?

拆分呗,正好把样式的逻辑也拆分出去一部分,方便以后如果有其他的特殊情况我们也好处理。

@mixin addColor(){}

定义一个添加颜色的mixin

那你可能要问了,为啥不用@function了?@function不好用吗?

当然不是,是因为二者的使用环境不同:

@function用来定义复杂操作的函数,接收参数并返回结果。@function函数有一条规则就是必须用指定的return 语句@return,用于返回函数调用的结果

@mixin是用于定义样式的函数,这些样式可以在整个样式表中重复使用,从而允许编写可重复使用的样式规则。

了解了这些,接下来,我们就是常规操作了,写样式呗:

$-color: #c1c1c1;

@mixin addColor() {
  /* 外层轨道 */
  &::-webkit-scrollbar-track {
    border-radius: 3px;
    background: rgba($color: $-color, $alpha: 0.1);
  }
  /* 滚动的滑块 */
  &::-webkit-scrollbar-thumb {
    border-radius: 3px;
    background: rgba($color: $-color, $alpha: 0.2);

    &:hover {
      background: rgba($color: $-color, $alpha: 0.4);
    }
  }
}

需要注意的,我们定义的$-color,再变量名面前,加上-,意味着变量私有,外部不可使用。

另外有个小tips:

不同的样式,我们不一定非要写不同的颜色值,颜色的变化明暗变化也可以营造不同的效果,而且还一脉相承。

需要注意的是rgba($color: $color, $alpha: 0.4)这只是rgba的一种写法,跟你直接写rgba(255,255,255,0)一个道理;

逻辑整合

好了,说了这么多,我们基本完工了,现在需要的就是把这些逻辑整合起来,并放到入口函数中即可了。

@mixin scrollbar($class, $addColor:true){}

因为要知道使用者需不需要我们添加的scrollbar颜色,所以需要一个额外的参数让使用者告诉我们是否要用,默认值为true(要用)

现在,往里面添加逻辑:

@mixin scrollbar($class, $addColor:true){
    $classname: classHandle($class);
    
    ::ng-deep #{$classname} {
      /* 宽高 */
      &::-webkit-scrollbar {
        width: 0.6vw;
      	height: 0.8vh;
      }
      @if $addColor {
      	@include addColor();
   	  }
  }
}

这里面的逻辑也很简单:

  • 首先处理传进来的类名,并定义一个$classname变量接收一下。

  • ::ng-deep这个是angular中样式穿透的用法,如果你使用的vue或者react,只需要改成对应的即可.

  • 下面就是scss中样式的写法了,值得注意的是:

    width 代表的是垂直滚动条的宽,height代表的是水平滚动条的高,莫得搞混了。不要以为我们定义的是一个宽度0.6,高度0.8的滚动条。

  • 最后就是判断是不是要添加颜色了。

到此为止,一个简单的scrollbar样式的mixin就写好了,我会把完整的文件代码放到最后,有需要的自取。

私有成员

做到上面那一步,整个样式文件就已经完成了,但是还不是很严谨,因为我们都知道,一个class类中的成员方法,有些是不对外暴露的,只允许类内部使用,这叫私有成员。

那变量的私有上面说了,方法怎么不对外暴露呢?

这就需要用到scss@forward规则了:

  • 通过在语句中添加hide或者show关键字,后面加上成员名称来指定样式表的成员的可见性。
  • 类似这样:@forward './myStyle.scss hide privateFunc' 这就代表着隐藏myStyle样式表中的privateFunc成员
  • 其他用法,还是参见官网啦:scss官网

那接下来就是文件划分啦,一般来说,我们定义的mixin模块是单独的,我们还需要一个文件做整理和收集,不然在后续项目开发中,除了scrollbar模块之外,我们有定义了好多其他模块,那我们还得在使用到的地方一个个引入吗?

所以,在定义一个mixin.scss文件:

@forward "./mixins/scrollbar" hide classHandle, addColor;

这样我们只管在这个文件中引入其他模块,然后用到的地方直接简单的引入mixin.scss就能使用所有想用的模块啦。

结尾

话说回来,你可能经常会简单有一些scss文件名称是以_开头的,比如_scrollbar.scss,那这和正常的scrollbar.scss有啥差别呢?有兴趣的可以去官网看下。

到此,本文就结束,这里给大家提供一下文章的源代码,以及文件结构。

scrollbar.scss

@use "sass:string";

/**
 * class 类名处理
 */
@function classHandle($class) {
  $c: string.quote($class);

  @if string.slice($c, 1, 1)==string.quote(".") {
    @return string.unquote($c);
  }
  @else {
    @return string.unquote(".#{$c}");
  }
}

/**
 * 是否给滑块增加颜色
 * [使用场景:适合一些特殊的不需要颜色的滚动条,如ant-table组件 .ant-table-header]
 */
$-color: #c1c1c1;

@mixin addColor() {

  /* 外层轨道 */
  &::-webkit-scrollbar-track {
    border-radius: 3px;
    background: rgba($color: $-color, $alpha: 0.1);
  }

  /* 滚动的滑块 */
  &::-webkit-scrollbar-thumb {
    border-radius: 3px;
    background: rgba($color: $-color, $alpha: 0.2);

    &:hover {
      background: rgba($color: $-color, $alpha: 0.4);
    }
  }
}

/**
 * $class 类名
 */
@mixin scrollbar($class, $addColor: true) {
  /* 处理 class 类名 */
  $classname: classHandle($class);

  ::ng-deep #{$classname} {

    /* 宽高 */
    &::-webkit-scrollbar {
      width: 0.6vw;
      height: 0.8vh;
    }

    @if $addColor {
      @include addColor();
    }

  }
}

mixins.scss

@forward "./mixins/scrollbar" hide classHandle, addColor;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值