我想使用CSS模拟一个滑块。 This code pen显示了一个最小的工作示例。
可以使用javascript设置滑块的left
属性,或者如在代码笔示例中那样,将CSS变量设置为0到100。
0%时,滑块应位于其父级的左侧。在100%时,滑块应与右侧齐平。
父级是一个flex子级,其宽度由flex-grow
设置,并且与另一个flex子级共享其行。
在下图中,滑块的父级是黄色,滑块本身是蓝绿色。相邻的flex子项显示为橙色:
当CSS变量(或Javascript变量)达到100%时,滑块的右边缘应与黄色框的右边缘齐平,但当前它的移动方式如下:
我以为我可以使用以下方式计算left
属性:
calc((100% - 40px) / 100%)
但是as MDN states中,除法的右边必须是数字。
我缺少明显的东西吗?
.full {
display: flex;
height: 50px;
max-width: 600px;
}
.full p {
float: left;
padding-left: 10px;
}
.left {
flex-grow: 8;
background-color: yellow;
padding: 5px 0;
}
.right {
flex-grow: 2;
background-color: orange;
}
.slider {
height: 100%;
width: 40px;
background-color: steelblue;
opacity: 0.9;
}
.slider {
position: relative;
--complete: 100%;
left: calc(var(--complete));
}
<div class="full">
<div class="left">
<p>flex-grow: 8</p>
<div class="slider">
</div>
</div>
<div class="right">
<p>flex-grow: 2</p>
</div>
</div>
答案 0 :(得分:2)
您可以调整计算并从--complete
中删除百分比:
--complete:80;
left: calc( var(--complete) * 1% - var(--complete) * (40px/100));
完整代码:
.full {
display: flex;
height: 50px;
max-width: 600px;
}
.full p {
float: left;
padding-left: 10px;
}
.left {
flex-grow: 8;
background-color: yellow;
padding: 5px 0;
}
.right {
flex-grow: 2;
background-color: orange;
}
.slider {
height: 100%;
width: 40px;
background-color: steelblue;
opacity: 0.9;
}
.slider {
position: relative;
--complete:80;
left: calc( var(--complete) * 1% - var(--complete) * (40px/100));
}
<div class="full">
<div class="left">
<p>flex-grow: 8</p>
<div class="slider">
</div>
</div>
<div class="right">
<p>flex-grow: 2</p>
</div>
</div>
<div class="full">
<div class="left">
<p>flex-grow: 8</p>
<div class="slider" style="--complete:100">
</div>
</div>
<div class="right">
<p>flex-grow: 2</p>
</div>
</div>
<div class="full">
<div class="left">
<p>flex-grow: 8</p>
<div class="slider" style="--complete:0">
</div>
</div>
<div class="right">
<p>flex-grow: 2</p>
</div>
</div>
<div class="full">
<div class="left">
<p>flex-grow: 8</p>
<div class="slider" style="--complete:50">
</div>
</div>
<div class="right">
<p>flex-grow: 2</p>
</div>
</div>
<div class="full">
<div class="left">
<p>flex-grow: 8</p>
<div class="slider" style="--complete:20">
</div>
</div>
<div class="right">
<p>flex-grow: 2</p>
</div>
</div>
或将其与transform结合使用,如下所示:
--complete: 80%;
left: calc(var(--complete));
transform: translateX(calc(-1 * var(--complete)));
.full {
display: flex;
height: 50px;
max-width: 600px;
}
.full p {
float: left;
padding-left: 10px;
}
.left {
flex-grow: 8;
background-color: yellow;
padding: 5px 0;
}
.right {
flex-grow: 2;
background-color: orange;
}
.slider {
height: 100%;
width: 40px;
background-color: steelblue;
opacity: 0.9;
}
.slider {
position: relative;
--complete: 80%;
left: calc(var(--complete));
transform: translateX(calc(-1 * var(--complete)));
}
<div class="full">
<div class="left">
<p>flex-grow: 8</p>
<div class="slider">
</div>
</div>
<div class="right">
<p>flex-grow: 2</p>
</div>
</div>
<div class="full">
<div class="left">
<p>flex-grow: 8</p>
<div class="slider" style="--complete:100%">
</div>
</div>
<div class="right">
<p>flex-grow: 2</p>
</div>
</div>
<div class="full">
<div class="left">
<p>flex-grow: 8</p>
<div class="slider" style="--complete:0%">
</div>
</div>
<div class="right">
<p>flex-grow: 2</p>
</div>
</div>
<div class="full">
<div class="left">
<p>flex-grow: 8</p>
<div class="slider" style="--complete:50%">
</div>
</div>
<div class="right">
<p>flex-grow: 2</p>
</div>
</div>
<div class="full">
<div class="left">
<p>flex-grow: 8</p>
<div class="slider" style="--complete:20%">
</div>
</div>
<div class="right">
<p>flex-grow: 2</p>
</div>
</div>
答案 1 :(得分:0)
感谢Temani Afif关于using translateX as well as left的有用提示,我设法提出了一个虽然不错但可行的解决方案。
我仍然愿意接受更具吸引力的解决方案。
.slider {
position: relative;
--complete: 100;
left: calc(1% * var(--complete));
transform: translateX(calc(-40px * var(--complete) / 100));
}