CSS трансформация, неровные края в хром


193

Я использовал CSS3-трансформацию для поворота изображений и текстовых полей с границами на моем веб-сайте.

Проблема в том, что границы выглядят неровными в Chrome, как игра (с низким разрешением) без сглаживания. В IE, Opera и FF это выглядит намного лучше, потому что используется AA (который все еще хорошо виден, но не так уж плохо). Я не могу проверить Safari, потому что у меня нет Mac.

Повернутая фотография и сам текст выглядят хорошо, только граница выглядит неровной.

Я использую CSS так:

.rotate2deg {
    transform: rotate(2deg);
    -ms-transform: rotate(2deg); /* IE 9 */
    -webkit-transform: rotate(2deg); /* Safari and Chrome */
    -o-transform: rotate(2deg); /* Opera */
    -moz-transform: rotate(2deg); /* Firefox */
}

Можно ли как-то это исправить, например, заставив Chrome использовать AA?

Пример ниже:

Jagged Edges пример


Для тех, кто читает его позже: он должен быть исправлен в Chrome начиная с версии 15 (ноябрь 2011 г.), но Safari представил точно такую ​​же проблему в 5.1 для Mac, которая на данный момент еще не исправлена
dtech

И они исправили это так хорошо, что вернуться невозможно. У нас есть случаи, когда сглаживание - это последнее, что мы хотим, но теперь в Chrome / Chromium / Safari нет способа отключить сглаживание в преобразованных изображениях, хотя они являются 1-битными изображениями (например, ч / б gif). Размытие это так круто, так круто, больше размытия это круто, говорят они! Единственный способ обеспечить четкие края - преобразовать все в пути или объекты SVG и добавить атрибут shape-render = "crispEdges".
Тимо Кяхконен

Для меня проблема заключается в прозрачных границах, используемых для создания стрелки. Это в Chrome 40 на win и mac. Ни один из вариантов здесь не решает проблему.
Гурнард

Ответы:


389

В случае, если кто-то ищет это позже, хороший способ избавиться от этих неровных краев при преобразованиях CSS в Chrome - добавить свойство CSS -webkit-backface-visibilityсо значением hidden. В моих собственных тестах это полностью сгладило их. Надеюсь, это поможет.

-webkit-backface-visibility: hidden;

7
Спасатель - этот прием позволил нам повторно включить -webkit-transform на ряде сайтов, которые ранее мы были вынуждены отключить преобразования из-за проблем сглаживания. Спасибо!
Даррен

любая помощь по этому вопросу: stackoverflow.com/questions/9235342/… ?
Abernier

5
Это работает в Chrome, но это делает их снова неровными в iOS 6!
13

11
@lazd, чтобы исправить это в iOS addpadding: 1px; -webkit-background-clip: content-box;
Роб Флетчер

2
@RobFletcher добавил padding и background-clip, которые кажутся для этой темы существенными для кросс-браузерного и перекрестного решения. Это также исправляет мою проблему с OSX / Chrome, так что ... я думаю, что полное решение будет что-то вроде:padding: 1px;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-background-clip:content-box;background-clip:content-box;
Бенджамин Луома

121

Если вы используете transitionвместо transform, -webkit-backface-visibility: hidden;не работает. Зубчатый край появляется во время анимации для прозрачного файла PNG.

Для ее решения я использовал: outline: 1px solid transparent;


4
похоже, это помогает в ситуациях, когда пропущено свойство web-kit-backface-visibility.
dgibbs

2
Работает для меня, когда никто другой не сделал. Перед добавлением этого свойства у Chrome Android были проблемы. Теперь все браузеры работают нормально.
Берни Сампшон

У меня работает в Safari на iOS 8.
Мориц Фридрих

Идеальное решение. Другие не работали. Я почти сдался и сомневался, что это сработает. Но это так!
Гарконис

1
Работает отлично для моих нужд. Я действительно использую переход, и другие ответы заставили мой PNG стать пикселированным в его состоянии по умолчанию. Ваш ответ помог удалить любую пикселизацию - как в состоянии по умолчанию, так и во время перехода. Отлично!
Гарконис

24

Добавление прозрачной границы размером 1 пиксель вызовет сглаживание

outline: 1px solid transparent;

Или добавьте прозрачную коробку-тень размером 1 пиксель.

box-shadow: 0 0 1px rgba(255,255,255,0);

rgba (255, 255, 255, 0), вероятно, лучше
ммм

4
Добавление верхнего раздела CSS в вашем ответе и outline: 1px solid transparent;работа хорошо для меня. Другие решения выше не работали достаточно хорошо.
Тимоти Цорн

outline: 1px solid transparent;активировать сглаживание также в Firefox 52 (с теми же проблемами в Chrome)
Лука Детоми

18

Попробуйте 3d-трансформацию. Это работает как шарм!

/* Due to a bug in the anti-liasing*/
-webkit-transform-style: preserve-3d; 
-webkit-transform: rotateZ(2deg);

1
пробуя это в chrome сейчас (август 2013 г. на Mac), принятое решение не работает, но использование этого (в частности preserve-3d, rotateвсе еще может использоваться без перехода на rotateZ) делает.
Дэйв,

Супер хакер, но у меня сработало. Попробуйте даже меньшую степень, например 0,05, чтобы избежать видимого неправильного выравнивания.
cpursley

preserve-3d спас мне жизнь.
Ханнес Шнайдермайер

8

Выбранный ответ (ни один из других ответов) не сработал для меня, но это сработало:

img {outline:1px solid transparent;}


2

У меня возникла проблема с градиентом CSS3 с -45deg. backgroundКосо, был сильно зазубренными аналогичные, но хуже , чем исходное сообщение. Поэтому я начал играть с обоими background-size. Это растянет неровности, но все еще было. Кроме того, я прочитал, что у других людей тоже возникают проблемы с шагом 45 градусов, поэтому я настроился -45degна -45.0001degи моя проблема была решена.

В моем CSS ниже background-sizeизначально был 30pxи degдля градиента фона был точно -45deg, и все ключевые кадры были 30px 0.

    @-webkit-keyframes progressStripeLTR {
        to {
            background-position: 60px 0;
        };
    }

    @-moz-keyframes progressStripeLTR {
        to {
            background-position: 60px 0;
        };
    }

    @-ms-keyframes progressStripeLTR {
        to {
            background-position: 60px 0;
        };
    }

    @-o-keyframes progressStripeLTR {
        to {
            background-position: 60px 0;
        };
    }

    @keyframes progressStripeLTR {
        to {
            background-position: 60px 0;
        };
    }

    @-webkit-keyframes progressStripeRTL {
        to {
            background-position: -60px 0;
        };
    }

    @-moz-keyframes progressStripeRTL {
        to {
            background-position: -60px 0;
        };
    }

    @-ms-keyframes progressStripeRTL {
        to {
            background-position: -60px 0;
        };
    }

    @-o-keyframes progressStripeRTL {
        to {
            background-position: -60px 0;
        };
    }

    @keyframes progressStripeRTL {
        to {
            background-position: -60px 0;
        };
    }

    .pro-bar-candy {
        width: 100%;
        height: 15px;

        -webkit-border-radius:  3px;
        -moz-border-radius:     3px;
        border-radius:          3px;

        background: rgb(187, 187, 187);
        background: -moz-linear-gradient(
                        -45.0001deg,
                        rgba(187, 187, 187, 1.00) 25%,
                        transparent 25%,
                        transparent 50%,
                        rgba(187, 187, 187, 1.00) 50%,
                        rgba(187, 187, 187, 1.00) 75%,
                        transparent 75%,
                        transparent
                    );
        background: -webkit-linear-gradient(
                        -45.0001deg,
                        rgba(187, 187, 187, 1.00) 25%,
                        transparent 25%,
                        transparent 50%,
                        rgba(187, 187, 187, 1.00) 50%,
                        rgba(187, 187, 187, 1.00) 75%,
                        transparent 75%,
                        transparent
                    );
        background: -o-linear-gradient(
                        -45.0001deg,
                        rgba(187, 187, 187, 1.00) 25%,
                        transparent 25%,
                        transparent 50%,
                        rgba(187, 187, 187, 1.00) 50%,
                        rgba(187, 187, 187, 1.00) 75%,
                        transparent 75%,
                        transparent
                    );
        background: -ms-linear-gradient(
                        -45.0001deg,
                        rgba(187, 187, 187, 1.00) 25%,
                        transparent 25%,
                        transparent 50%,
                        rgba(187, 187, 187, 1.00) 50%,
                        rgba(187, 187, 187, 1.00) 75%,
                        transparent 75%,
                        transparent
                    );
        background: linear-gradient(
                        -45.0001deg,
                        rgba(187, 187, 187, 1.00) 25%,
                        transparent 25%,
                        transparent 50%,
                        rgba(187, 187, 187, 1.00) 50%,
                        rgba(187, 187, 187, 1.00) 75%,
                        transparent 75%,
                        transparent
                    );
        background: -webkit-gradient(
                        linear,
                        right bottom,
                        right top,
                        color-stop(
                            25%,
                            rgba(187, 187, 187, 1.00)
                        ),
                        color-stop(
                            25%,
                            rgba(0, 0, 0, 0.00)
                        ),
                        color-stop(
                            50%,
                            rgba(0, 0, 0, 0.00)
                        ),
                        color-stop(
                            50%,
                            rgba(187, 187, 187, 1.00)
                        ),
                        color-stop(
                            75%,
                            rgba(187, 187, 187, 1.00)
                        ),
                        color-stop(
                            75%,
                            rgba(0, 0, 0, 0.00)
                        ),
                        color-stop(
                            rgba(0, 0, 0, 0.00)
                        )
                    );

        background-repeat: repeat-x;
        -webkit-background-size:    60px 60px;
        -moz-background-size:       60px 60px;
        -o-background-size:         60px 60px;
        background-size:            60px 60px;
        }

    .pro-bar-candy.candy-ltr {
        -webkit-animation:  progressStripeLTR .6s linear infinite;
        -moz-animation:     progressStripeLTR .6s linear infinite;
        -ms-animation:      progressStripeLTR .6s linear infinite;
        -o-animation:       progressStripeLTR .6s linear infinite;
        animation:          progressStripeLTR .6s linear infinite;
        }

    .pro-bar-candy.candy-rtl {
        -webkit-animation:  progressStripeRTL .6s linear infinite;
        -moz-animation:     progressStripeRTL .6s linear infinite;
        -ms-animation:      progressStripeRTL .6s linear infinite;
        -o-animation:       progressStripeRTL .6s linear infinite;
        animation:          progressStripeRTL .6s linear infinite;
        }

1

Возможно, вы сможете замаскировать неровности с помощью размытых теней . Использование -webkit-box-shadow вместо box-shadow гарантирует, что это не повлияет на браузеры, не относящиеся к webkit. Возможно, вы захотите проверить браузеры Safari и мобильный webkit.

Результат несколько лучше, но все же намного хуже, чем в других браузерах:

с тенью от коробки (нижняя сторона)


1

Просто подумал, что мы добавим и наше решение, поскольку у нас была точно такая же проблема в Chrome / Windows.

Мы попробовали решение по @stevenWatkins выше, но все еще имели «степпинг».

Вместо того

-webkit-backface-visibility: hidden;

Мы использовали:

-webkit-backface-visibility: initial;

Для нас это помогло 🎉


1

Добавление следующего в div, окружающий рассматриваемый элемент, исправило это для меня.

-webkit-transform-style: preserve-3d;

В моем случае вокруг видеоокна появлялись неровные края.


0

Для меня это было свойство CSS перспективы, которое добилось цели:

-webkit-perspective: 1000;

Совершенно нелогично в моем случае, так как я не использую 3d-переходы, но, тем не менее, работает.


0

Для холста в Chrome (Версия 52)

Все перечисленные ответы об изображениях. Но моя проблема связана с canvas в chrome (v.52) с transform rotate. Они стали зазубренными, и все эти методы не могут помочь.

Решение, которое работает для меня:

  1. Увеличьте холст на 1 px для каждой стороны => +2 px для ширины и высоты;
  2. Нарисуйте изображение со смещением + 1px (в положении 1,1 вместо 0,0) и фиксированным размером (размер изображения должен быть на 2px меньше размера холста)
  3. Применить необходимое вращение

Итак, важные блоки кода:

// Unfixed version
ctx.drawImage(img, 0, 0, 335, 218);
// Fixed version
ctx.drawImage(img, 1, 1, 335, 218);
/* This style should be applied for fixed version */
canvas {
  margin-left: -1px;
  margin-top:-1px;
}        
<!--Unfixed version-->
<canvas width="335" height="218"></canvas>
<!--Fixed version-->
<canvas width="337" height="220"></canvas>

Пример: https://jsfiddle.net/tLbxgusx/1/

Примечание: вложенных элементов div много, потому что это упрощенная версия из моего проекта.


Эта проблема воспроизводится также для Firefox для меня. На Safari и FF с сетчаткой нет такой проблемы.

И еще одно обоснованное решение - поместить canvas в div такого же размера и применить к нему следующий CSS:

overflow: hidden;
box-shadow: 0 0 1px rgba(255,255,255,0);
// Or
//outline:1px solid transparent;

И вращение должно быть применено к этому упаковочному div. Таким образом, указанное решение работает, но с небольшими изменениями.

И модифицированный пример для такого решения: https://jsfiddle.net/tLbxgusx/2/

Примечание: см. Стиль div с классом «третий».

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.