Перемещение объекта плавно от начала до конца родительского без наложения - PullRequest
0 голосов
/ 10 октября 2018

Я бы хотел смоделировать слайдер с помощью CSS. Этот код пера показывает минимальный рабочий пример.

Свойство ползунка left можно установить с помощью javascript или, как в примере с пером кода, установив переменную CSS из 0до 100.

При 0% ползунок должен находиться слева от своего родителя.При значении 100% ползунок должен находиться на одном уровне с правым.

Родитель - это гибкий дочерний элемент, ширина которого установлена ​​на flex-grow, и он делит свой ряд с другим дочерним гибким элементом.

InНа изображении ниже родительский элемент ползунка - желтый, а сам ползунок - чирок.Соседний дочерний элемент flex отображается оранжевым цветом:

Slider at 0%

Когда переменная CSS (или переменная Javascript) достигает 100%, правый край ползунка долженсидеть на одном уровне с правым краем желтой рамки, но в настоящее время он движется так:

50%

100%

Я думал, что мог бы вычислить свойство left, используя что-то вроде:

calc((100% - 40px) / 100%)

Но , поскольку MDN сообщает , правая часть деления должна бытьчисло.

Я что-то упускаю из виду?

.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 голосов
/ 10 октября 2018

Вы можете настроить расчет и удалить проценты из --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>

Или объедините его с преобразованием и используйте его так:

--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>
0 голосов
/ 10 октября 2018

Благодаря полезной подсказке от Temani Afif о с использованием translateX и оставленной мне удалось собрать решение, которое не красиво, но работает.

Я все еще открыт для более «привлекательных» решений.

.slider {
  position: relative;
  --complete: 100;
  left: calc(1% * var(--complete));
  transform: translateX(calc(-40px * var(--complete) / 100));
}
...