Предотвращение размытого рендеринга с помощью transform: scale

я масштабирую div С свойством transform, но я хочу сохранить его детей (которые имеют 1px ширина или высота) тот же размер. Я сравнил их по .5, с ожидаемым результатом, что элемент 1px масштабируется на 2, а затем .5, должны в конечном итоге обратно в 1px, но они оказываются размытыми 2px.

вот поле перед его масштабирование:

.container {
    width: 200px;
    height: 200px;
    margin: 100px;
    background-color: #EEE;
    position: absolute;
}

.outline {
    position: absolute;
    background: #1899ef;
    z-index: 999999;
    opacity: 1 !important;
}

.outlineBottom, .outlineTop {
  width: 100%;
  height: 1px;
}

.outlineLeft, .outlineRight {
    height: 100%;
    width: 1px;
}

.outlineRight {
    right: 0px;
}

.outlineBottom {
    bottom: 0px;
}
<div class="container">
    <div class="outline outlineTop"></div>
    <div class="outline outlineRight"></div>
    <div class="outline outlineBottom"></div>
    <div class="outline outlineLeft"></div>
</div>

как вы можете видеть, элементы по краям ясны, темны 1px синий. Вот как выглядит коробка после масштабирование, хотя:

.container {
    width: 200px;
    height: 200px;
    margin: 100px;
    background-color: #EEE;
    position: absolute;
    transform: scale(2);
}

.outline {
    position: absolute;
    background: #1899ef;
    z-index: 999999;
    opacity: 1 !important;
    transform: scale(.5);
}

.outlineBottom, .outlineTop {
  width: 100%;
  height: 1px;
  transform: scale(1,.5);
}

.outlineLeft, .outlineRight {
    height: 100%;
    width: 1px;
    transform: scale(.5,1);
}

.outlineRight {
    right: 0px;
}

.outlineBottom {
    bottom: 0px;
}
<div class="container">
    <div class="outline outlineTop"></div>
    <div class="outline outlineRight"></div>
    <div class="outline outlineBottom"></div>
    <div class="outline outlineLeft"></div>
</div>

и вот пост-масштабируемая визуализация из Chrome 41.0.2272.89 Mac, который я запускаю.

добавлять transform-3d(0, 0, 0) похоже, не помогло. А решение был найден с помощью zoom свойства, но поскольку zoom не очень хорошо поддерживается, я бы хотел избегать этого. Добавление filter: blur(0px); похоже, тоже никакого эффекта.

он был положено в чат что, возможно, дети сначала масштабируется до .5 а затем удвоился в размере, в результате чего они будут уменьшены до .5px и затем обратно оттуда. Есть ли способ обеспечить порядок, в котором они отображаются, заставляет их сначала масштабироваться до 2px а потом наполовину? Вопреки здравому смыслу, я попытался!--45-->форсирование порядка рендеринга с помощью JS, но неудивительно, что это не имело никакого эффекта (хотя, что интересно, нижний элемент сохранил свой первоначальный цвет).

в противном случае, есть ли какие-либо другие решения, плавающие там? Я не могу быть единственным, кто столкнулся с этой проблемой.

1 ответов


это связано с дефолтом transform-origin на масштабных элементов. Значение по умолчанию 50% 50% для любого преобразуемого элемента, но это имеет проблемы при масштабировании значений 1px, поскольку он должен центрировать scale на половине пикселя и рендеринга элементов имеет проблемы отсюда. Вы можете видеть, как он работает здесь с transform-origin переехал в соответствующие крайности для каждого элемента.

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

body {
    padding: 1em;
}

.container {
    width: 200px;
    height: 200px;
    margin: 100px;
    background-color: #EEE;
    position: absolute;
    transform: scale(2);
}

.outline {
    position: absolute;
    background: #1899ef;
    z-index: 999999;
    opacity: 1 !important;
}

.outlineBottom, .outlineTop {
    width: 100%;
    height: 1px;
    transform: scale(1, 0.5);
}

.outlineBottom {
    bottom: 0;
    transform-origin: 0 100%;
}

.outlineTop {
    transform-origin: 0 0;
}

.outlineLeft, .outlineRight {
    height: 100%;
    width: 1px;
    transform: scale(.5,1);
}

.outlineRight {
    right: 0px;
    transform-origin: 100% 0;
}

.outlineLeft {
    left: 0px;
    transform-origin: 0 0;
}
<div class="container">
    <div class="outline outlineTop"></div>
    <div class="outline outlineRight"></div>
    <div class="outline outlineBottom"></div>
    <div class="outline outlineLeft"></div>
</div>