трансформація css, нерівні краї в хромі


193

Я використовував перетворення CSS3 для обертання зображень та текстових полів з рамками на своєму веб-сайті.

Проблема полягає в тому, що рамки виглядають нерівними в Chrome, як гра (з низькою роздільною здатністю) без функції Anti-Aliasing. У 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?

Приклад нижче:

Приклад із зубчастими краями


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

І вони так добре виправили, що повернутися назад неможливо. У нас є випадки, коли антиаліазія - це останнє, що ми хочемо, але зараз Chrome / Chromium / Safari не має способу вимкнути антиаліанізацію в трансформованих зображеннях, хоча вони є 1-бітними зображеннями (наприклад, b / w gif). Вони розмовляють так круто, так круто, тим більше розмиття, крутіше, кажуть! Єдиний спосіб забезпечити чіткі краї - це перетворити всі на SVG шляхи чи об’єкти та додати атрибут shape-rendering = "crispEdges".
Тімо Кехьонен

Для мене проблема полягає в прозорих рамках, які використовуються для створення стрілки. Це в Chrome 40 на win та mac. Жоден із варіантів тут не вирішує проблему.
Гурнард

Відповіді:


389

У разі, якщо хтось шукає цього згодом, приємним трюком для позбавлення від нерівних країв перетворень CSS у Chrome є додавання властивості CSS -webkit-backface-visibilityзі значенням hidden. На моїх власних тестах це повністю їх згладило. Сподіваюся, що це допомагає.

-webkit-backface-visibility: hidden;

7
Рятувальник - ця хитрість дозволила нам знову включити -webkit-перетворення на ряді сайтів, які раніше ми змушені були вимкнути перетворення через проблеми з антизбудженням. Дякую!
Даррен

будь-яка допомога щодо цього: stackoverflow.com/questions/9235342/… ?
аберньє

5
Це працює в Chrome, але це робить їх знову зазубрими в iOS 6!
lazd

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

2
@RobFletcher додав прокладки та фонові кліпи, які, здається, за цією темою є важливими для крос-браузера та крос-os рішення. Це теж виправляє мою проблему з 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
це, здається, допомагає у ситуаціях, коли властивість видимості веб-набору повернути до уваги.
dgibbs

2
Для мене працює, коли ніхто з інших не робив. Перш ніж додати цю властивість, у Chrome Android виникли проблеми. Зараз, здається, всі браузери працюють належним чином.
Bernie Sumption

Працює для мене в 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)
Luca Detomi

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

зберегти-3d врятувало мені життя.
Hannes Schneidermayer

8

Обрана відповідь (ні будь-яка інша відповідь) для мене не спрацювала, але це зробило:

img {outline:1px solid transparent;}


2

У мене виникли проблеми з градієнтом CSS3 з -45deg. backgroundКосо, був сильно зазубреними аналогічні, але гірше , ніж вихідне повідомлення. Тому я почав грати з обома background-size. Це би розтягнуло зубчастість, але воно все одно було. Тоді на додачу я прочитав, що у інших людей виникають проблеми також з кроком 45deg, тому я налаштувався -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 та веб-переглядачі мобільних веб-програм.

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

з тіньовою коробкою (нижня сторона)


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)

Усі перелічені відповіді стосуються зображень. Але моє питання стосується полотна в хромі (v.52) з обертанням перетворення. Вони стали нерівними, і всі ці методи не можуть допомогти.

Рішення, яке працює для мене:

  1. Зробіть полотно більшим на 1 пікс для кожної сторони => +2 пікс для ширини та висоти;
  2. Намалюйте зображення зі зміщенням + 1 пікс (у позиції 1,1 замість 0,0) та фіксованим розміром (розмір зображення повинен бути на 2 пікселя менше розміру полотна)
  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/

Примітка: є багато вкладених дівок, оскільки це спрощена версія з мого проекту.


Це питання відтворено також для Firefox для мене. На Сафарі та ФФ із сітківкою такої проблеми немає.

І іншим обґрунтованим рішенням є розміщення полотна в div однакового розміру та застосування цього css до цього div:

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

І обертання слід застосувати до цього обгорткового діла. Так перераховане рішення працює, але з невеликою модифікацією.

І модифікованим прикладом такого рішення є: https://jsfiddle.net/tLbxgusx/2/

Примітка: Дивіться стиль діва з класом "третій".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.