总结7个工作中常用的css3案例,带你了解冷门却实用的特性

2022-12-25 0 615

采用表达式 currentColor 增加多次重复标识符

市场需求叙述

移到按键上后,发生改变该原素的 border-color 、 color ,除了两个具备有效性的全黑大背景。点选按键后,色调更改成移出按键时的混种颜色。
总结7个工作中常用的css3案例,带你了解冷门却实用的特性

试著计划

我坚信任何人两个前端开发者都能迅速同时实现那个市场需求,不晓得我们好不好的,我在以后始终都是下列标识符加速同时实现:

index.html 文档 :

<div class=good>请给我雅雷</div> 拷贝标识符

index.scss 文档 :

.good { padding: 3px 6px; color: #333; background: rgba(#333, 0.1); border: 1px solid #333;border-radius: 3px; cursor: pointer; &:hover { color: #0069ff; background: rgba(#0069ff, 0.1); border: 1px solid #0069ff; } &.good-click { color: #0069ff; background: rgba(#0069ff, 0.1); border: 1px solid #0069ff; } } 拷贝标识符

index.js 文档 :

const goodBtn = document.querySelector(.good) goodBtn.addEventListener(click, () => { if (goodBtn.classList.contains(good-click)) { goodBtn.classList.remove([good-click]) return } goodBtn.classList.add([good-click]) }) 拷贝标识符

是的,就是那么朴实无华,缺点也暴露无遗:

相同的色调我们采用了多次,比如 #333 和 #0069ff 。如果有一天产品说把那个那个色调改一下,细心点的你多动动手指也没啥问题,改就改了,但是这种方式很不“程序员”。

针对那个问题我们直接采用预处理器(SASS/LESS)的表达式就完事了:

index.scss 文档 :

$color: #333; $hoverColor: #0069ff; .good { padding: 3px 6px; color: $color; background: rgba($color, 0.1); border: 1px solid $color; border-radius: 3px; cursor: pointer; &:hover { color: $hoverColor; background: rgba($hoverColor, 0.1); border: 1px solid $hoverColor; } &.good-click { color: $hoverColor; background: rgba($hoverColor, 0.1); border-color: $hoverColor; } } 拷贝标识符

咋一看已经是很好的同时实现方式了,但是也有缺点:

有时候(比如我大多数时候)都不想为了某两个特殊的类下的 color 单独设置两个表达式,仅仅只有它采用,我还要专门为其定义两个表达式就显得标识符很臃肿;在我添加了 good-click 那个类名后,我要把 color 、 border-color 、 background 全都重新设置一遍;

那个时候,css 原生表达式 currentColor 即可大显身手了。

改进计划

表达式 currentColor 能拿到本原素的 color 属性的值,如果没有显示设置,拿的将会是父原素的 color 属性的值,由此类推。借助那个优点,我们即可优化上述标识符:

index.scss 文档 :

.good { position: relative; padding: 3px 6px; color: #333; border: 1px solid currentColor; border-radius: 3px; cursor: pointer; &::before { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: currentColor; opacity: 0.1; content: ; } &:hover { color: #0069ff; } &.good-click { color: #0069ff; } } 拷贝标识符

现在看起来是不是好多了,我每次要更改色调,只需要将此原素的 color 属性更改即可,不需要再重新写一堆多次重复的属性,当然,原生的 cs

所以现在我只能添加两个 ::before 来模拟大背景色块,真正做到只改 color 属性,即可改全部色调。

现在我们就可以在 React 或 Vue 中通过状态来控制发生改变色调的类名添加与否并设置 color 属性,以此来完美地进行色调的加速变换了~

多说一句,如果我们直接采用 ele.style.color = #fff 这种操作 dom 的形式来发生改变字体色调,在未采用 currentColor 的情况下,我们是没法操作伪原素的,也就发生改变不了伪原素的 background 、 border-color 等其他与字体色调一致的属性,所以这时候 currentColor 的优势就更明显了~

在线演示

采用表达式 currentColor 增加多次重复标识符 – codepen(

https://codepen.io/vortesnail/pen/MWyzerK)

完美的带小箭头的聊天框

市场需求叙述

主体功能聊天气泡,需有有边框 border 、大背景色 background 、阴影、带边框的小三角箭头。小三角的边框色调和阴影色调与主体框的色调要一致,小三角的边框有 border-radius 。
总结7个工作中常用的css3案例,带你了解冷门却实用的特性

试著计划

给该原素加个伪原素,大背景色与聊天框大背景色一致,再给该伪原素添加上、左全黑边框,绝对定位调整位置,再来个 border-top-left-radius: 3px ,最后 transform: rotate(-45deg) 旋转一下,标识符如下:

index.html 文档 :

<div class=“chat-box”>我们好,我是 vortesnail,如果我们喜欢我的文章,对我们有所帮助,麻烦给个小小的赞支持一下,谢谢</div> 拷贝标识符

index.scss 文档 :

.chat-box { position: relative; max-width: 200px; padding: 10px; color: #faae43; background: #fff9ed; border: 1px solid #ffc16b; border-radius: 4px; box-shadow: 0 2px 6px rgba(250, 174, 67, 0.8); }.chat-box::before { position: absolute; top: 20px; left: –6px; width: 10px; height: 10px; background: #fff9ed; border-color: #ffc16b; border-style: solid; border-width: 1px 0 0 1px; transform: rotate(-45deg); content: ;/* box-shadow: 0 2px 6px rgba(250, 174, 67, 0.8); */ } 拷贝标识符

可以达到现在下面的效果:

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

细心的你一定发现了,那个小三角指示箭头是没有阴影的,如果我给其加上与主体原素一致的 box-shadow ,又因为那个属性不能像 border-color 一样分别给各边设置为透明,结果就会像下面这样:

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

这已经是无法满足具备相同阴影的要求了,而且我们如过想一下就晓得,在我主体原素不设 padding 或设的很小的情况下,小三角的大背景色会将我们的文字挡住,这种计划直接宣布失败!

改进计划

针对以上的问题,我们进行一步步改造。

首先,我们考虑到主体原素不设置 padding 的情况,为了防止内容被我们的小三角大背景色覆盖,我们可通过加两个伪原素 ::before ,利用 border 来画成两个三角形,标识符如下:

.chat-box { // 其他样式 &::before { position: absolute; top: 20px; left: –8px; // 注意,这里做了略微调整 width: 0;width height: 0; border-color: transparent#fff9ed transparent transparent; border-style: solid; border-width: 8px 8px 8px 0; content: ; } } 拷贝标识符

现在是那个样子:

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

注意,这里的小三角已经是没有右边部分的了,解决了我们不设置 padding 时导致内容被遮挡的问题。但是这样就没有办法同时实现边框,毕竟你已经是采用边框做出来的三角形了。

那我们就再采用两个伪原素呗, ::after 安排上了。接下来为我们提供两个思路:采用试著计划中的方式再画两个正方形做旋转,但是不为其设置大背景色,只设置其 border ,调整下位置即可。

.chat-box { // 其他样式 &::before {} &::after { position: absolute; top: 22px; left: –7px; width: 10px; height: 10px;/* border-color: inherit transparent transparent inherit; */ border-color: transparent; border-style: solid;border-width: 1px; border-top-color: inherit; border-left-color: inherit; border-top-left-radius: 3px; transform: rotate(-45deg); content: ; } } 拷贝标识符

可以看到,标识符中我设置上和左的 border-color 为 inherit ,表示继承父级原素的 border-color ,因我注释那部分的写法不被识别,所以我们新增了几行标识符同时实现,利用 inherit 可以在色调更改时少写色调值的多次重复标识符,与 currentColor 想要达到的目的是一致的。

现在,越来越接近我们的目标:

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

这里小三角还是没有阴影,因为 box-shadow 并不会作用于伪原素,解决计划就是采用 filter 属性, drop-shadow 接受的参数和 box-shadow 基本一致,我们替代它即可:

// box-shadow: 0 2px 6px rgba(250, 174, 67, 0.8);box-shadow filter: drop-shadow(0 2px 6px rgba(250, 174, 67, 0.8)); 拷贝标识符

现在已经完美同时实现~

在线演示

同时实现两个完美的带小箭头的聊天框 – codepen(

https://codepen.io/vortesnail/pen/mdPQgwY)

利用 grid 同时实现完美的水平铺满、间隔一致的自适应布局

市场需求叙述

在两个容器原素下,有不确定数量的子原素,要求他们水平铺满,并且在当前行的最左边和最右边的子原素距离父原素左边缘和右边缘都是无缝贴合的。每个子原素之间的间隔必须一致。当浏览器窗口大小变动自适应。
总结7个工作中常用的css3案例,带你了解冷门却实用的特性

试著计划

那个问题从我入职第一份组织工作后困扰了我接近半年,我基本还是惯性思维,一眼看过去就是 flex弹性盒子 一把梭,于是我有了以下这种计划:

index.html 文档 :

<body> <div class=“father”> <div class=“child”>Child1</div> <div class=“child”>Child2</div> <div class=“child”>Child3</div> <div class=“child”>Child4</div> <div class=“child”>Child5</div> <div class=“child”>Child6</div> <div class=“child”>Child7</div> <div class=“child”>Child8</div> <div class=“child”>Child9</div> <div class=“child”>Child10</div> </div> </body> 拷贝标识符

index.scss 文档 :

.father { display: flex;flex-wrap: wrap; align-items: flex-start; justify-content: flex-start; width: 100%; padding: 10px 0 10px 20px; .child { margin-right: 14px; margin-bottom: 14px; // 其他卡片样式 } } 拷贝标识符

可以看到,我会为每个子原素都设置 margin-top 以及 margin-right 来固定他们之间的间距,但是因为每一行最右边的子原素也有 margin-right ,为了补偿那个,我就将父原素的 padding-right 去掉了,这样做的坏处太多了,需要自己去计算,做补偿,而且右边有时候容纳不下两个完整的子原素,就会导致换行而留下一大片白。。

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

为了能用弹性盒子做到想要的效果,我已经把阮一峰老师的Flex 布局教程:语法篇看烂了。。根本没法同时实现最佳最想要的效果,以上只是我多次试著后唯一能接受的计划,我就这么个计划用了好多次。

直到有一天,我又遇到了这种布局市场需求,我辛辛苦苦用 js 去硬算他们之间的间距,算是同时实现了想要的效果,但是真的非常繁琐,我就受不了了。那个时候我又偶遇了阮一峰老师的CSS Grid 网格布局教程,谢天谢地,采用 Grid 可完美同时实现以上市场需求!

改进计划

Flex 布局是轴线布局,只能指定”项目”针对轴线的位置,可以看作是一维布局。Grid 布局则是将容器划分成”行”和”列”,产生单元格,然后指定”项目所在”的单元格,可以看作是二维布局。Grid 布局远比 Flex 布局强大

首先我们需要给容器指定为 grid 网格布局,就像 flex 一样:

.father { display: grid; } 拷贝标识符

接着要为其划分列数, grid-template-columns 属性可定义每一列的列宽,假如标识符如下,我们将容器划分成 3 列,每列宽度为容器的 100px :

.father { grid-template-columns: 100px 100px 100px; } 拷贝标识符

但是那个时候我们看到的效果会是下面这样:

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

子原素并没有把父原素占满,这显然不是我们想要的效果,幸亏有 repeat() 函数帮助我们简化多次重复值, 它接受两个参数,第两个参数是多次重复的次数,第二个参数是所要多次重复的值。上面的标识符完全可用下列标识符代替:

.father { grid-template-columns: repeat(3, 100px); } 拷贝标识符

当然,这只是第一步,我们还需要借助 auto-fill 关键字,在我们需要容器能尽可能容纳子原素时,就需要用到它,表示自动填充,我的理解是 repeat() 接受了那个 auto-fill 的参数时,会去自动计算容纳的数量,就好像你事先算出来那个容器能容纳多少子原素,然后把那个“多少”传给该函数一样。这时候标识符如下:

.father { display: grid; grid-template-columns: repeat(auto-fill, 100px); } 拷贝标识符

现在图形如下,已经越来越接近我们的目标了:

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

但是很显然,右边有两个空隙, justify-content 属性拯救我们,它整个内容区域在容器里面的水平位置,当我设置其为 space-between 时,意味着子原素之间的间隔相等,而子原素与容器边框之间没有间隔

不过子原素之间还是没有间隔,简单设置一下属性 gap 即可,它是 column-gap 和 row-gap 的合并简写,分别表示列与列行与行之间的间距,现在标识符如下:

.father { display: grid; grid-template-columns: repeat(auto-fill, 100px); justify-content: space-between; gap: 14px 4px; } 拷贝标识符

由此简单的几行标识符就已经完美同时实现了我们想要的效果:

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

不过 grid 网格布局的兼容性不是很好,点此查看支持的浏览器列表~

在线演示

利用 grid 同时实现完美的水平铺满、间隔一致的自适应布局 – codepen(

https://codepen.io/vortesnail/pen/NWNEmvx)

间距可调整的虚线框

市场需求叙述

同时实现两个按键,该按键边框为虚线,且虚线的每个笔触之间的空隙和长度都是可调的。能支持有圆角,即可设置 border-radius 。
总结7个工作中常用的css3案例,带你了解冷门却实用的特性

试著计划

其实我始终很迷惑为什么 css3 不提供一些能调整虚线框的必要属性,默认的 dash-border 经常会和 ui 所需要的虚线框要求会不一致,既然官方不支持,我们只能自己寻找一些解决计划。

那个解决计划看似很多,其实每一种解决计划都会有一定的局限性,选择最合适的就是最好的,具体我列出了下列几条:

利用 border-image 和自定义的图片来进行虚线框的生成,该计划在 stackoverflow 查到的,我个人也试著了下,但是修改起来特别麻烦,我第一感觉就是不会采用这种计划,有兴趣的可以看下:Brew your own border with border-image。在所需要虚线框的原素的宽高是固定的情况下,可以让 UI 画好那个虚线框就行,弊端很明显,长度若一旦发生变化,虚线比例和原来就不会一致,特别丑。利用 4 个绝对定位的“伪原素”来模拟,标识符示例如下:

index.html 文档 :

<body> <div id=“box”> <div class=“border-horizontal top”></div> <div class=“border-vertical right”></div> <div class=“border-horizontal bottom”></div> <div class=“border-vertical left”></div>I am vortesnail, now i try to make a custom dashed border!</div> </body> 拷贝标识符

index.scss 文档 :

$border-color: #ccc; $border-dashed-unit-width: 8px; $border-dashed-unit-height: 1px; $stroke-rate: 50%; body { #box { width: 400px; background: #fff; padding: 10px; box-sizing: border-box; position: relative; .border-horizontal { position: absolute; width: 100%; height: $border-dashed-unit-height; left: 0; background-image: linear-gradient( to right, $border-color 0%, $border-color $stroke-rate, transparent $stroke-rate ); background-size: $border-dashed-unit-width $border-dashed-unit-height; background-repeat: repeat-x; } .border-vertical { position: absolute; width: $border-dashed-unit-height; height: 100%; top: 0; background-image: linear-gradient( to bottom, $border-color $stroke-rate, $border-color $stroke-rate, transparent $stroke-rate ); background-size: $border-dashed-unit-height $border-dashed-unit-width; background-repeat: repeat-y; } .top { top: 0; } .right { right: 0; } .bottom { bottom: 0; } .left { left: 0; } } } 拷贝标识符

其实其思想很简单,就是 4 个矩形,每个矩形加上渐变大背景,并 repeat 即可模拟虚线效果,其间距、比例可根据我们设定的表达式去调整。

但是它的弊端非常大,就是无法调整 border-radius ,即没有圆角!这里向我们展示只是为了抛砖引玉,万一你有更好的想法,或者你不需要圆角,那就可以用那个计划。效果如下:

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

改进计划

其实我们借助 svg 就能比较不错的同时实现自定义虚线框,如果不想自己写 svg 的朋友可以直接在那个网站进行调整和生成:Customize your CSS Border ,但如果你稍微介绍一些 svg 的用法,也完全可以自己同时实现,如果你想介绍一下,可阅读这篇文章:SVG入门—如何手写SVG

标识符如下: index.html 文档 :

<body> <div id=“box”>I am vortesnail, now i try to draw a dashed border box.</div> </body> 拷贝标识符

index.scss 文档 :

body { #box { width: 400px; border-radius: 4px; padding: 10px; background-image: url(data:image/svg+xml,\<svg xmlns=“http://www.w3.org/2000/svg”>\ <rect width=“100%” height=“100%” rx=“4” ry=“4” style=“stroke: black; stroke-width: 2px; fill: none; stroke-dasharray: 8px 5px; stroke-dashoffset: 10px;”/>\ </svg>); } } 拷贝标识符

可通过 stroke-width 调整虚线框宽度, stroke-dasharray 调整比例及长度、间距, stroke-dashoffset 调整偏移值。

tips:svg 计划在一些比较老的安卓机上会不兼容,即使在新的机型上,也会出现一些表现差异,虽然在 web 端支持 svg 的浏览器上表现是正常的,但若考虑到移动端用户群体时,采用请慎重。

在线演示

同时实现两个间距可调的虚线框 – codepen(

https://codepen.io/vortesnail/pen/ZEWPwey)

自定义复选框

市场需求叙述

能够完全自定义复选框样式,就像定义两个普通的 div 原素一样。disabled 状态复选框样式也可以自定义。
总结7个工作中常用的css3案例,带你了解冷门却实用的特性

试著计划

很显然,当我们采用默认的 input.checkbox 计划时,是没有办法发生改变其样式的,而且在不同浏览器之间,其表现也不一致,标识符如下:

index.html 文档 :

<body> <div class=“checkbox-container”> <input type=“checkbox” id=“apple”> <label for=“apple”>苹果</label> </div> <div class=“checkbox-container”> <input type=“checkbox” id=“banana” disabled> <label for=“banana”>香蕉</label> </div> <div class=“checkbox-container”> <input type=“checkbox” id=“watermelon”> <label for=“watermelon”>西瓜</label> </div> </body> 拷贝标识符

index.scss 文档 :

.checkbox-container { display: flex; align-items: center; input[type=checkbox] { & + label { color: #333; } } input[type=checkbox]:disabled { &+ label { color: #c6c6c6; } } } 拷贝标识符

在 chrome 下表现为:

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

在 firefox 下表现为:

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

在 safari 下与在 firefox 下一致。

如果任由这种情况的发生,你们 ui 可能会找产品经理和你打一架~

改进计划

我们可以在不发生改变上面试著计划中的 html 结构,只需 css 即可做到!给每两个 label 标签添加两个伪原素 ::before 作为复选框!

首先,我们给那个伪原素添加必要样式,使其符合 ui 的设计:

input[type=”checkbox”]{ & +label { display: flex; align-items: center; } & + label::before { box-sizing: border-box; content: “\a0”; /* 不换行空格 */ width: 13px; height: 13px; margin-right: 4px; border-radius: 2px; border: 1px solid #333; } } 拷贝标识符

现在的拙劣效果如下:

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

我们发现,默认的复选框还是存在的,我们怎么做到将其隐藏而不破坏其可访问性呢(即不能采用 display: none )?

input[type=”checkbox”] { position: absolute; clip: rect(0, 0, 0, 0); & + label {…} & + label::before{…} } 拷贝标识符

以上隐藏的计划引用至 css揭秘151页

现在点选我们自定义的复选框是没有任何人效果的,接下来借助 css 的相邻兄弟选择器对 checked 状态、disabled 状态分别设置样式即可:

input[type=”checkbox”]:checked { & + label::before { background-color: #1890ff; background-image: url(“https://s1.ax1x.com/2020/10/11/0cUbi4.png”); background-repeat: no-repeat; background-size: 100% 100%; border: none; } } input[type=”checkbox”]:disabled { & + label { color: #868686; cursor: not-allowed; } & +label::before { border-color: #868686; } } 拷贝标识符

可以看到,经过此番处理后,我们可以完全自主地去设计复选框样式,比如我在上面选中时,呈现了一张对勾的图片: background-image: url(“

https://s1.ax1x.com/2020/10/11/0cUbi4.png”); ,这极大地方便了我们对其呈现形式的掌控。

除此之外,你还可以设置 input[type=”checkbox”]:focus 时的样式哦,赶快试试吧!

在线演示

自定义复选框 – codepen(

https://codepen.io/vortesnail/pen/abZOBjx)

交互式图片对比效果

市场需求叙述

before 和 after 图片对比效果,可拖过拖拽中间的竖形条状进行两张图片的宽度变化。
总结7个工作中常用的css3案例,带你了解冷门却实用的特性

试著计划

css3 中引入了 resize 属性,该属性可以不通过 js 就可以发生改变设置该属性的原素的宽度 width ,我们一定采用过 textarea 标签把?那个右下角的可拖拽更改长宽的东西就是该属性的功劳。实际上,所有标签都可以设置该属性!

于是,简单的几段标识符就可以达到交互式图片对比效果,虽然和我们想要同时实现的效果有点差异,但如果要求不高的话,就采用它吧:

index.html 文档 :

<divclass=“image-slider”> <div class=“before-container”> <img src=“https://img3.doubanio.com/view/photo/l/public/p2622600072.webp” alt=“before”> </div> <img src=“https://img9.doubanio.com/view/photo/l/public/p2380745925.webp” alt=“after”> </div> 拷贝标识符

index.scss 文档 :

.image-slider { position: relative; img { display: block;width: 720px; user-select: none; } .before-container { position: absolute; top: 0; left: 0; width: 50%; max-width: 100%; /* 防止容器宽度拉长至比图片还宽 */ overflow: hidden; /* 必须不可见 */ resize: horizontal; /* 赋予水平宽度可拉伸功能 */ &::before { position: absolute; right: 0; bottom: 0; width: 12px; height: 12px; background: linear-gradient(-45deg, #000 50%, transparent 0); background-clip: content-box; cursor: ew-resize; content: ; } } } 拷贝标识符

我们利用两个伪原素 ::before 来对右下角的拉伸图标进行覆盖,以便于自定义样式,现在效果如下:

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

那个计划弊端就是右下角的可拖拽图标无法更改位置和大小,即使我们利用伪原素去覆盖,但是和我们市场需求中所需要的效果也相差甚远,于是我们不得不借助 js 了!

改进计划

在上述计划中增加两个 span 标签用于画我们的拖拽竖条,紧接着按照上述计划先将两张照片的位置和大小调好:

index.html 文档 :

<body> <div class=“image-slider”> <div class=“before-container”> <img src=“https://img3.doubanio.com/view/photo/l/public/p2622600072.webp” alt=“before”> </div> <img src=“https://img9.doubanio.com/view/photo/l/public/p2380745925.webp” alt=“after”> <span class=“handler”></span> </div> </body> 拷贝标识符

index.scss 文档 :

body { .image-slider { position: relative; img { display: block; width: 520px; user-select: none; pointer-events: none; } .before-container { position: absolute; left: 0; top: 0; width: 50%; overflow: hidden; } } } 拷贝标识符

现在效果如下:

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

初步的效果出来了,接下来增加可拖拽发生改变水平宽度的功能。首先需要先在两张图片交际出添加两个竖形的条状,用于拖拽位置,更改 class=handler 样式:

.handler { position: absolute; top: 0; left: 50%; display: block; width: 4px; height: 100%; background: rgba(0, 0, 0, 0.4); transform: translateX(-50%); cursor: ew-resize; } 拷贝标识符

注意中间的透明竖形条状即是我们可拖拽的位置:

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

接下来写我们的 js 脚本,首先通过原生 js 方法找到三个 dom 节点:

index.js 文档 :

const imageSlider = document.querySelector(“.image-slider”); const beforeContainer = document.querySelector(“.before-container”); const handler = document.querySelector(“.handler”); 拷贝标识符

然后我们还需要获得 image-slider 那个最外层原素相对页面左边的距离,我们定义为表达式 leftX ,并在鼠标于 handler 原素上按下时计算该值:

let leftX; handler.onmousedown = (e) =>{ leftX = e.pageX – handler.offsetLeft; }; 拷贝标识符

用一张图来解释说明下:

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

然后在给 window 对象添加两个 mousemove 的监听事件,该回调用于发生改变 handler 位置和 before-image 的宽度:

handler.onmousedown =(e) => { leftX = e.pageX – handler.offsetLeft; window.addEventListener(mousemove, moveHandler) }; const moveHandler = e => { const beforeWidth = e.pageX – leftX; constimageSliderWidth = imageSlider.offsetWidth;if (beforeWidth >= 0&& beforeWidth <= imageSliderWidth) { handler.style.left = beforeWidth +px; beforeContainer.style.width = beforeWidth + px; } } 拷贝标识符

目前为止,我们拖拽 handler 已经能同时实现所需的效果,但是无法停止,我们需要添加两个鼠标按键抬起的监听事件,需要注意的是不能在 handler 上添加,比如: handler.onmouseup ,必须在 window 对象上添加,具体为什么,我们可以动手试试就晓得了:

window.onmouseup = (e) => { window.removeEventListener(mousemove, moveHandler) }; 拷贝标识符

到此为止,就已经完美同时实现了该效果,我们还可以在 handler 上做更多组织工作,使其用户体验达到更好~

在线演示

交互式图片对比效果 – codepen(

https://codepen.io/vortesnail/pen/wvWaJRB)

有效性渐变层代替滚动条提示

市场需求叙述

两个可滚动列表,在未滚动到顶部以后,需有有两个渐变层代替滚动条作为剩余内容提示,底部同理;滚到到顶部时,渐变层消失,底部同理;渐变层未矩形渐变。试著计划
总结7个工作中常用的css3案例,带你了解冷门却实用的特性

首先很明确的是,先将内容滚动条搞出来:

index.html 文档 :

<body> <div class=“content-wrapper”> <header>目录</header> <div class=“list-wrapper”> <ul> <li>如何长高</li> …省略 </ul> </div> </div> </body> 拷贝标识符

index.scss 文档 :

body { .content-wrapper { width: 248px; padding: 20px 0; background: #fafafa; header { padding: 0 20px 0 24px; font-weight: 500; font-size: 16px; } .list-wrapper { ul { height: 400px; padding: 0 20px 0 24px; overflow-y: auto;color: #595959; li { padding: 6px 0; font-size: 14px; list-style: none; } } } } } 拷贝标识符

现在效果如下:

总结7个工作中常用的css3案例,带你了解冷门却实用的特性

接下来为滚动范围的顶部和底部都先加上我们所需要的渐变层,通过父容器的 ::before 和 ::after 伪原素来同时实现,同时动态为 list-wrapper 那个原素增加两个类名,用于控制渐变层的显隐:

.list-wrapper { position: relative; &::before { position: absolute; right: 0; left: 0; z-index: 1; height: 60px; content: ; pointer-events: none; } &.top-gradient::before { top: 0; background: linear-gradient(to bottom,#fafafa,hsla(0,0%,98%,.5) 84%,hsla(0,0%,98%,.13)); } &::after{position: absolute; right: 0; left: 0; z-index: 1; height: 60px; content: ; pointer-events: none; } &.bottom-gradient::after { bottom: 0; background: linear-gradient(to top,#fafafa,hsla(0,0%,98%,.5) 84%,hsla(0,0%,98%,.13)); } } 拷贝标识符

但是我们想要达到的效果是:一旦滚动条不是最顶部,顶部就要有渐变层;一旦滚动条不是最底部,底部就要有渐变层。现在完全是写死在两头,需要通过简单的 js 脚本来判断 ul 原素的滚动条的位置:

index.js 文档 :

const listWrapper = document.querySelector(“.list-wrapper”); const ul = document.querySelector(“ul”); const onScroll = (e) => { // 滚动条是否在顶部 if(e.target.scrollTop >0) { listWrapper.classList.add(“top-gradient”); } else { listWrapper.classList.remove(“top-gradient”); } // 滚动条是否在底部 if(e.target.scrollHeight – e.target.scrollTop !== ul.offsetHeight) { listWrapper.classList.add(“bottom-gradient”); } else { listWrapper.classList.remove(“bottom-gradient”); } }; ul.addEventListener(“scroll”, onScroll); 拷贝标识符

最后再将原生滚动条隐藏,OK!

ul{ … scrollbar-width: none;scrollbar-width /* Firefox */ -ms-overflowstyle: none; /* IE10+ */&::-webkit-scrollbar { display: none;/* Chrome */ } } 拷贝标识符

顺带说一句,在 codepen 中滚动条隐藏不了,本地调试时可以,我也不晓得啥问题~

改进计划

实际上上述计划是我看《css揭秘》后想到的,在这本书中,讲到了利用两层 background 以及 background-attachment 属性来进行渐变层的同时实现,但是我按书中同时实现后,发现效果并不完美,甚至可以说有很大缺陷!我想了好久还是觉得用 js 方便,css 看起来是无法同时实现我想要的效果的!

所以上述计划就是最终改进计划,《css揭秘》中的方法我实在不敢认同,不过关于 background-attachment 属性的介绍倒是给我学到了~

在线演示

有效性渐变层代替滚动条提示 – codepen(

https://codepen.io/vortesnail/pen/PozqKyM)

结语

虽然标题写了是 css3,但是还是难免涉及到了 js,我的目的是希望有同类市场需求的小伙伴能通过本篇文章得到帮助。欢迎各位理性讨论~如果有更好的方法,请大佬们务必不吝赐教!如果你已经看到此处,干脆点个赞再走吧~

作者:vortesnail

链接:

https://juejin.cn/post/6882704719882485774

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务