多脚步滑块:一般案例
这个两部分系列的第一部分详细介绍了我们如何获得两次跑步的滑块。现在,我们将研究一个一般的多阶段案例,但采用了一种不同,更好的技术来在拇指之间创建填充。最后,我们将深入研究造型的造型在现实的3D滑块和扁平的造型背后。
文章系列:
- 多脚步滑块:特定的两次案件
- 多脚步滑块:一般案例(此帖子)
更好,更灵活的方法
假设,在覆盖与范围输入相同区域的包装器伪元素上,我们从左到右的线性级别()层堆叠与每个拇指相对应的层。每个梯度层都是完全不透明的(即alpha为1),从轨道最小到拇指的中线,然后完全透明(即alpha为0)。
请注意,RGB值无关紧要,因为我们关心的只是alpha值。我个人使用了代码中的红色(对于完全不透明的部分)和透明的关键字,因为它们的字符数量最少。
我们如何计算从完全不透明到完全透明的梯度停止位置?好吧,这些位置始终位于从左边缘的拇指半径之间,从右边缘的拇指半径之间,因此它们在等于有用宽度的范围内(轨道宽度,减去拇指直径)。
这意味着我们首先添加一个拇指半径。然后,我们通过将当前拇指位置和最小值之间的差为最大值和最小值之间的差( - dif)来计算进度。该进度值是[0,1]间隔中的一个数字 - 当当前的拇指位置处于最小值时,当当前的拇指位置处于滑块最大值时,即0。为了确切地沿着有用的宽度间隔,我们将该进度值乘以有用的宽度。
我们所追求的位置是这两个长度值之间的总和:拇指半径和我们在有用的宽度间隔内走多远。
下面的演示使我们能够看到2D视图中的所有外观如何堆叠在一起,以及在父母的伪元素上的范围输入和梯度如何在3D视图中分层。它也是交互式的,因此我们可以拖动滑块拇指,并查看相应的填充(由梯度层在其父母的伪元素上创建)如何变化。
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
该演示最好在Chrome和Firefox中观看。
好吧,但是仅仅堆叠这些梯度层并不能为我们带来我们追求的结果。
这里的解决方案是使这些梯度掩盖层,然后将其XOR(更确切地说,在CSS掩码的情况下,这意味着将其Xor alphane Xor)。
如果您需要对XOR的工作方式进行复活,这里有一个:给定的两个输入,如果输入值不同(其中一个是1,另一个是0),则此操作的输出为1,如果输入值相同(它们两个是0或两个是1),则为1)
XOR操作的真实表看起来如下:
输入 | 输出 | |
---|---|---|
一个 | b | |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
您还可以在以下交互式演示中使用它,在此可以切换输入值并查看输出的变化:
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
在我们的情况下,输入值是沿水平轴的梯度掩模层的alpha。 XOR-ing多层意味着对前两个从底部进行,然后从底部的第三层XOR-ing-thing the先前的XOR操作等等。对于我们的特定情况,即alpha的左右梯度等于1(由相应的拇指值决定),然后为0,它看起来如下所示(我们从底部开始并上升):
如果两层从底部的alpha为1,则我们在XOR-unging之后获得的结果层的alpha为0。它们的alpha值不同,所得层的alpha为1。在它们的alpha中,它们的alpha均为0,结果层的Alpha为0。
向上移动,我们将第三层与上一步中获得的结果层相关。这两个层具有相同的alpha,第二个XOR操作产生的层的alpha为0。它们具有不同的alpha,所得的alpha为1。
同样,我们从底部将第四层分为第四层,而第二阶段XOR操作产生的层。
就CSS而言,这意味着使用标准蒙版复合材料的排除值和非标准-Webkit-mask-Composite的XOR值。 (为了更好地了解面具合并,请查看速成课程。)
这项技术为我们提供了所需的结果,同时还允许我们为所有填充物使用单个伪元素。这也是一种适合任何数量拇指的技术。让我们看看如何将其放入代码中!
为了使事情保持完全灵活,我们首先更改哈停与代码,以便它可以添加或删除拇指并通过简单地添加或从拇指对象中添加或删除项目,从而相应地更新所有内容,每个对象都包含一个值和标签(仅适用于屏幕读取器):
- 令最小= -50,max = 50; - 让拇指= [ - {val:-15,lbl:'value a'}, - {val:20,lbl:'value b'}, - {val:-35,lbl:'value c'}, - {val:45,lbl:'value d'} - ]; - 令nv = thumbs.length; 。 style =`$ {thumbs.map(((c,i)=>`-v $ {i}:$ {c.val}`).join(';')}; - 米:$ {min}; -max:$ {max}`) #多LBL多拇指滑块: - for(让i = 0; i <nv i label.sr-inly .lbl min="min" value="thumbs" .val max="max)"><p>在这些精确四个值的特定情况下,生成的标记看起来如下:</p> <pre rel="HTML"> <div class="'wrap'角色='组'aria-labelledby" v0> <div id="'多lbl'">多拇指滑块:</div> <label class="'sr-inly'for">值a </label> <input type="'range'id"> <label class="'sr-inly'for">值b </label> <input type="'range'id"> <label class="'sr-inly'for">值c </label> <input type="'range'id"> <label class="'sr-inly'for">值d </label> <input type="'range'id"> </div>
我们不需要在CSS或JavaScript中添加任何内容,就可以为我们提供一个功能性的滑块,其中
。裹 { / *与以前相同 */ 网格 - 板板行:max-content#{$ h}; / *现在只有2行 */ &::后 { 背景:#95A; // 内容: ''; //现在不显示 网格列:1/ span 2; 网格行:3; } } 输入[type ='range'] { / *与以前相同 */ 网格行:2; / *最后一行是第二行 */ } 输出 { 颜色:透明; 位置:绝对; 右:0; &::后 { 内容:计数器(c); 计数器:C var(-c); } }
我们将采取更多措施以稍后的结果来效果,但是现在,这就是我们所拥有的:
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
接下来,我们需要将那些拇指放到拇指填充物上。我们通过在哈巴狗中生成蒙版层并将其放入包装器上的填充自定义属性中来做到这一点。
// - 和以前一样 - 令layers = thumbs.map((c,i)=>`线性级别(90DEG,red calc(var(-r)(var(-v $ {i}) - var(-min))/var(-min))/var(-vir)*var(-uw)*var(-uw)),透明度0)`); 。 style =`$ {thumbs.map(((c,i)=>`-v $ {i}:$ {c.val}`).join(';')}; - 米:$ {min}; -max:$ {max}; - 填充:$ {layers.join(',')}`) // - 和以前一样
对于具有这些值的四个拇指的特定情况的生成的HTML可以在下面看到。请注意,如果我们从初始数组中添加或删除项目,则会自动更改。
<div class="'wrap'角色='组'aria-labelledby" v0 dif> <div id="'多lbl'">多拇指滑块:</div> <label class="'sr-inly'for">值a </label> <input type="'range'id"> <label class="'sr-inly'for">值b </label> <input type="'range'id"> <label class="'sr-inly'for">值c </label> <input type="'range'id"> <label class="'sr-inly'for">值d </label> <input type="'range'id"> </div>
请注意,这意味着我们需要将与尺寸相关的SASS变量转换为CSS变量,并替换使用它们的属性中的SASS变量:
。裹 { / *与以前相同 */ -w:20em; -H:4EM; -d:calc(.5*var(-h)); -r:calc(.5*var(-d)); -uw:calc(var(-w) - var(-d)); 背景:线性级别(0DEG,#CCC var(-h),透明0); 网格通信:max-content var(-h)/ var(-w); 宽度:var(-w); }
我们设置了包装器的口罩oo ::伪元素之后:
。裹 { / *与以前相同 */ &::后 { 内容: ''; 背景:#95A; 网格列:1/ span 2; 网格行:2; / *非标准WebKit版本 */ -webkit mask:var( - 填充); -webkit面具复合材料:XOR; / *标准版本,在Firefox中支持 */ 蒙版:var( - 填充); 面具复合材料:排除; } }
现在,我们已经拥有了我们想要的东西,而对此技术的真正酷的事情是,更改拇指的数量所需要做的就是添加或删除拇指对象(每个值和标签,每个值)到Pug代码中的拇指阵列 - 绝对没有其他需要更改的东西!
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
优惠的调整
到目前为止,我们所拥有的只是一个漂亮的景象。因此,让我们开始解决这个问题!
选项#1:逼真的外观
假设我们想实现以下结果:
第一步是使轨道的高度与拇指相同,然后绕轨道末端。到目前为止,我们已经在.wrap元素上模仿了曲目。尽管在技术上可以通过使用分层的线性和径向梯度来模拟具有圆形末端的轨道,但它确实不是最好的解决方案,尤其是当包装器仍然具有免费的伪元素(前面的::)时。
。裹 { / *与以前相同 */ -h:2em; -d:var(-h); &::之前,&:: efter { Border-Radius:var(-r); 背景:#ccc; 内容: ''; 网格列:1/ span 2; 网格行:2; } &::后 { 背景:#95A; / *非标准WebKit版本 */ -webkit mask:var( - 填充); -webkit面具复合材料:XOR; / *标准版本,在Firefox中支持 */ 蒙版:var( - 填充); 面具复合材料:排除; } }
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
使用::在模拟轨道之前,它打开了略微3D外观的可能性:
<pre rel="“" scss> <code> .wrap { / *与以前相同 */ &::之前,&:: efter { / *与以前相同 */ 盒子阴影:插图0 2PX 3PX RGBA(#000,.3); } &::后 { / *与以前相同 */ 背景: 线性毕业生(RGBA(#FFF,.3),RGBA(#000,.3)) #95a; } }</code>
我绝不是设计师,所以这些值可能可以调整以获得更好的结果,但是我们已经可以看到一个区别:
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
这给我们留下了一个非常丑陋的拇指,所以让我们也要修复该部分!
我们利用具有不同背景折叠(和背景 - 原始)值的多个背景的技术。
@mixin thumb(){ 边框:实心calc(.5*var(-r))透明; 边界拉迪乌斯:50%; / *制作圆形 */ 盒子大小:边框框; / * Chrome&Firefox之间的不同 */ / *现在我们有一个非零边框 */需要盒子大小 */ 背景: 线性级别(RGBA(#000,.15),rgba(#fff,.2))content-box, 线性级别(RGBA(#FFF,.3),RGBA(#000,.3))边框框, CurrentColor; 指针盛会:自动; 宽度:var(-d);高度:var(-d); }
我在一篇较旧的文章中对此技术进行了很多详细的描述。确保您是否需要复习!
但是,如果当前的彩色值为黑色(#000),则上述代码将几乎一无所有。让我们解决这个问题,还将拇指上的光标更改为更合适的东西:
输入[type ='range'] { / *与以前相同 */ 颜色:#eee; 光标:抓取; &:Active {光标:抓取; } }
结果当然比以前更令人满意:
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
真正困扰我的其他事情是标签文本与滑块的距离有多近。我们可以通过在包装器上引入网格差距来解决此问题:
。裹 { / *与以前相同 */ 网格间隙:.625EM; }
但是我们仍然遇到的最糟糕的问题是右上角绝对位置的输出。解决此问题的最佳方法是为他们引入第三个网格行,并用大拇指移动它们。
拇指的位置的计算方式与我们用于填充面膜的梯度层的尖锐停止的方式相似。
最初,我们将输出的左边缘放在垂直线的左侧边缘,该线是一个拇指半径-r远离滑块的左边缘。为了将输出与此垂直线对齐,我们将它们翻译回去(向左,沿x轴的负方向,因此我们需要减去符号)的宽度的一半(50%,因为translate()函数中的百分比值相对于元素的尺寸,将变换应用于元素的尺寸)。
为了用拇指移动它们,我们从相应的拇指(-c)的当前值中减去最小值( - min),将此差异除以最大值(-max)和最小值(-min)之间的差( - dif)。这为我们提供了[0,1]间隔的进度值。然后,我们将该值乘以有用的宽度(-UW),该值描述了实际运动范围。
。裹 { / *与以前相同 */ 网格 - 板行:最大var(-h)max-content; } 输出 { 背景:CurrentColor; 边界拉迪乌斯:5px; 颜色:透明; 网格列:1; 网格行:3; 左键:var(-r); 填充:0 .375EM; 变换:转换(calc((var(-c) - var(-min))/var( - dif)*var(-uw)-50%)); 宽度:Max-Content; &::后 { 颜色:#fff; 内容:计数器(c); 计数器:C var(-c); } }
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
乍一看,这看起来好多了。但是,仔细检查表明我们仍然有很多问题。
第一个是溢出:当我们到达轨道末端时,隐藏的元素会切出一点。
为了解决此问题,我们必须了解确切的溢出:隐藏的做法。如下面的交互式演示所示,它削减了元素填充框之外的所有内容,您可以单击代码以切换CSS声明。
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
这意味着解决此问题的快速解决方法是在包装器.wrap上添加足够大的侧面填充。
填充:0 2em;
我们在这里孤立地对我们的多次滑块进行了设计,但实际上,这可能不会是页面上唯一的东西,因此,如果间距有限,我们可以将其侧向填充,并具有负侧向边缘。
如果附近的元素仍然具有默认位置:静态,那么我们相对定位包装器的事实应该使输出在其重叠之上的顶部,否则,对.wrap上的z索引进行调整。
更大的问题是,我们已经在拖动拇指时使用了一些非常奇怪的
当集中在相应的
输入[type ='range'] { &:重点 { 轮廓:实心0透明; &, & 输出 { 颜色:深色态; z索引:2; } } }
但是,它对基本问题没有任何作用,当我们更改身体背景时,这变得显而易见,尤其是如果我们将其更改为图像,因为这不允许
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
这意味着我们需要重新思考如何将
解决方案是使用我一年前在“使用CSS变量的干交换开关”中描述的技术:使用突出显示 - HL自定义属性,其中值在正常状态下为0,在亮点状态下为1(:focus)。我们还计算了其否定(-nothl)。
* { -hl:0; -nothl:calc(1-var(-hl)); 保证金:0; 字体:继承 }
实际上,这还没有任何作用。诀窍是使我们想在两个状态之间更改的所有属性取决于-HL,如有必要,其否定(代码> –nothl)。
$ HLC:#f90; @mixin thumb(){ / *与以前相同 */ 背景色:$ hlc; } 输入[type ='range'] { / *与以前相同 */ 过滤器:灰度(var(-nothl)); z index:calc(1 var(-hl)); &:重点 { 轮廓:实心0透明; &&&output {-hl:1; } } } 输出 { / *相同的网格放置 */ 左键:var(-r); 最大宽度:最大包含; 变换:转换(calc((var( - c) - var(-min))/var( - dif)*var(-uw))); &::后 { / *与以前相同 */ 背景: 线性毕业生(RGBA(#FFF,.3),RGBA(#000,.3)) $ HLC; 边界拉迪乌斯:5px; 显示:块; 填充:0 .375EM; 变换:转换(-50%)比例(var(-hl)); } }
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
我们快到了!我们还可以添加有关状态变化的过渡:
$ t:.3s; 输入[type ='range'] { / *与以前相同 */ 过渡:过滤器$ t suble; } 输出:: efter { / *与以前相同 */ 过渡:变换$ t suble; }
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
最终的改进将是灰度()如果没有一个拇指,则填充是填充。我们可以使用以下方式来做到这一点:焦点对我们的包装器:
。裹 { &::后 { / *与以前相同 */ 过滤器:灰度(var(-nothl)); 过渡:过滤器$ t suble; } &:focus-within {-hl:1; } }
就是这样!
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
选项#2:平坦的外观
让我们看看如何获得平坦的设计。例如:
第一步是删除框的阴影和梯度,使我们以前的演示具有3D外观,并使轨道背景为重复梯度。
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
拇指的大小变化:焦点可以通过缩放变换来控制,其因子取决于高光开关变量(-hl)。
@mixin thumb(){ / *与以前相同 */ 变换:比例(calc(1-.5*var(-nothl))); 过渡:变换$ t suble; }
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
但是,拇指周围赛道上的孔呢?
蒙版合成技术在这里非常有用。这涉及将径向梯度分层以在每个拇指位置创建圆盘,并且在我们完成后,将其反转(即与完全不透明的层合成),将这些圆盘变成孔的结果。
这意味着要更改哈巴索代码,以便我们生成创建与每个拇指相对应的光盘的径向梯度列表。反过来,我们将在CSS中反转:
// - 和以前一样 - 令tpos = thumbs.map((c,i)=>`calc(var(-r)(var(-v $ {i})-var(-min))/var(-min))/var(-dif)*var(-uw))`; - 令fill = tpos.map(c =>`线性级别(90DEG,red $ {c},透明0)`); - 令hole = tpos.map(c =>`径向级别($ {c},红色var(-r),透明0)`) 。 style =`$ {thumbs.map(((c,i)=>`-v $ {i}:$ {c.val}`).join(';')}; - 米:$ {min}; -max:$ {max}; - 填充:$ {fill.join(',')}; - 孔:$ {hole.join(',')}`) // - 像以前一样的包装器内容
这会生成以下标记:
<div class="'wrap'角色='组'aria-labelledby" v0 dif> </div>
在CSS中,我们在两个伪元素上设置了一个掩码,并为每个元素设置了不同的值。我们还XOR上的面具层。
在::之前的情况下,掩码是带有完全不透明层的Xor-eD discs Xor-eD列表(作为逆变器,可以将圆盘变成圆形孔)。对于::之后,这是填充线性级别()层的列表。
。裹 { / *与以前相同 */ &::之前,&:: efter { 内容: ''; / *与以前相同 */ - 面具:线性级别(红色,红色),var( - 孔); / *非标准WebKit版本 */ -webkit面具:var(-mask); -webkit面具复合材料:XOR; / *标准版本,在Firefox中支持 */ 蒙版:var(-mask); 面具复合材料:排除; } &::后 { 背景:#95A; - 面具:var( - 填充); } }
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
最后一步是调整轨道,填充高度和中间,将它们垂直对齐在网格单元中(以及拇指):
。裹 { / *与以前相同 */ &::之前,&:: efter { / *与以前相同 */ 对齐:中心; 身高:6px; } }
现在,我们拥有所需的平坦多脚步滑块!
请参阅Codepen上的thebabydino(@TheBabydino)的笔。
以上是多脚步滑块:一般案例的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)