Масштаб преобразования работает неправильно для нечетных ширины пикселей

Я пытаюсь масштабировать div, но сохраняю внутренний элемент в той же позиции и того же размера. Для этого я использую transform: scale(value) на обертке и transform: scale(1/value) во внутреннем div.

Проблема заключается в том, что внутренний div смещается, когда я изменяю масштаб. Это происходит только в том случае, если ширина/высота обертки нечетная или не полная. Это не происходит даже для ширины/высоты обертки.

Моя цель состоит в том, чтобы иметь множество дочерних элементов оболочки, которые масштабируются рядом с оболочкой, но только один, который этого не делает.

Взгляните на этот пример, чтобы увидеть проблему в действии (наведите курсор на масштаб).

Пример с без проблем, внутренний элемент остается фиксированным по шкале (высота и ширина контейнера равны):

https://jsfiddle.net/o16rau6u/5/

.wrapper {
  width: 200px;
  height: 200px;
  background-color: blue;
  position: relative;
}

.bg {
  width: 20px;
  height: 20px;
  display: inline-block;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -10px;
  margin-left: -10px;
  background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Wiktionary_small.svg/350px-Wiktionary_small.svg.png");
  background-size: 100% 100%;
  background-repeat: no-repeat;
}

.wrapper:hover {
  transform: scale(2);
}

.wrapper:hover .bg {
  transform: scale(0.5);
}
<div id="wrapper" class="wrapper">
  <div id="bg" class="bg"></div>
</div>

Ответ 1

В начале я подумал, что это связано с расчетом, выполненным браузером и некоторым округлением, но, похоже, это ошибка. Я сделал много тестов и whartver значение масштаба, я использую его всегда не на нечетное значение.

Вот простой пример: scaleX

body:after {
  content: "";
  position: absolute;
  z-index: 999;
  top: 0;
  bottom: -200%;
  width: 2px;
  right: 50%;
  margin-right: -1px;
  background: rgba(0, 0, 0, 0.5);
}

.box {
  width: 200px;
  height: 100px;
  margin: 50px auto;
  background: blue;
  position: relative;
}

.inner {
  height: 20px;
  width: 20px;
  background: red;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -10px;
  text-align: center;
  color: #fff;
  margin-top: -10px;
}
<div class="box">
  <div class="inner">A</div>
</div>

<div class="box" style="transform:scaleX(2)">
  <div class="inner" style="transform:scaleX(0.5)">A</div>
</div>

<div class="box" style="width:201px;transform:scaleX(2)">
  <div class="inner" style="transform:scaleX(0.5)">A</div>
</div>

Ответ 2

Просто не помещайте один из этих divs в другой, вместо этого помещайте оба из них в третий div следующим образом:

.wrapper {
  width: 201px;
  height: 201px;
  position: relative;
}

.div-1 {
  width: 100%;
  height: 100%;
  background-color: blue;
}

.div-1:hover {
  transform: scale(2);
}

.div-2 {
  width: 20px;
  height: 20px;
  display: inline-block;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -10px;
  margin-left: -10px;
  background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Wiktionary_small.svg/350px-Wiktionary_small.svg.png");
  background-size: 100% 100%;
  background-repeat: no-repeat;
}
<div class="wrapper">
  <div class="div-1"></div>
  <div class="div-2"></div>
</div>

Ответ 3

Браузеры печально плохо при расчете. Было время, когда математика веб-разработчиков заявила, что (в некоторых браузерах) 33.33% раз 3 было больше 100% (но это было 14 лет назад). С тех пор все стало намного лучше, но не полагайтесь на него. Выполнение измененных трюков, подобных этому, - это не путь.

Мне кажется, что вы хотите изменить размер обертки, сохраняя при этом размер фона одинаковым. Для этого вы используете сложный трюк преобразования, который (unsrefixed) исключает 17% всех пользователей Интернета. Это неправильная поддержка браузера и еще одна причина не делать этого.

Этот эффект может быть легко достигнут при поддержке браузера 99,99%, работающем на всех размерах.

.wrapper {
  width: 402px;
  height: 402px;
  background-color: blue;
  position: relative;
}

.bg {
  width: 20px;
  height: 20px;
  display: block;
  position: absolute;
  top: 201px;
  left: 201px;
  margin-top: -10px;
  margin-left: -10px;
  background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Wiktionary_small.svg/350px-Wiktionary_small.svg.png");
  background-size: 100% 100%;
  background-repeat: no-repeat;
}

.wrapper:hover {
  width: 4020px;
  height: 4020px;
}
<div id="wrapper" class="wrapper">
  <div id="bg" class="bg"></div>
</div>