从父对象的开始到末尾平滑移动对象,没有重叠

时间:2018-10-10 14:53:18

标签: css css3 flexbox css-calc

我想使用CSS模拟一个滑块。 This code pen显示了一个最小的工作示例。

可以使用javascript设置滑块的left属性,或者如在代码笔示例中那样,将CSS变量设置为0到100。

0%时,滑块应位于其父级的左侧。在100%时,滑块应与右侧齐平。

父级是一个flex子级,其宽度由flex-grow设置,并且与另一个flex子级共享其行。

在下图中,滑块的父级是黄色,滑块本身是蓝绿色。相邻的flex子项显示为橙色:

Slider at 0%

当CSS变量(或Javascript变量)达到100%时,滑块的右边缘应与黄色框的右边缘齐平,但当前它的移动方式如下:

50%

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>

2 个答案:

答案 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));
}