transformação css, bordas irregulares em cromo


193

Eu tenho usado CSS3 transformar para girar imagens e caixas de texto com bordas no meu site.

O problema é que a borda parece irregular no Chrome, como um jogo (de baixa resolução) sem Anti-Aliasing. No IE, Opera e FF, parece muito melhor porque é usado o AA (que ainda é claramente visível, mas não tão ruim). Não posso testar o Safari porque não possuo um Mac.

A foto girada e o texto em si parecem bem, é apenas a borda que parece irregular.

O CSS que eu uso é o seguinte:

.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 */
}

Existe alguma maneira de corrigir isso, por exemplo, forçando o Chrome a usar AA?

Exemplo abaixo:

Exemplo de bordas irregulares


Para aqueles que o leem mais tarde: ele deve ser corrigido no Chrome a partir da versão 15 (novembro de 2011), mas o Safari apresentou exatamente o mesmo problema no 5.1 para Mac, que ainda não foi corrigido
— dtech

E eles consertaram tudo tão bem que é impossível voltar atrás. Temos casos em que antialiasing é a última coisa que queremos, mas agora o Chrome / Chromium / Safari não tem método para desativar o antialiasing em imagens transformadas, embora sejam imagens de 1 bit (por exemplo, b / w gif). O borrão é tão legal, tão legal, mais desfoque é mais legal, dizem eles! A única maneira de garantir arestas nítidas é converter tudo em caminhos ou objetos svg e adicionar o atributo shape-rendering = "crispEdges".
— Timo Kähkönen 7/10/12

Para mim, o problema é com bordas transparentes usadas para criar uma seta. Isso está no Chrome 40 no win e no mac. Nenhuma das opções aqui corrige o problema.
— Gurnard

Respostas:


389

Caso alguém procure mais tarde, um bom truque para se livrar dessas arestas irregulares nas transformações de CSS no Chrome é adicionar a propriedade CSS -webkit-backface-visibilitycom um valor de hidden. Nos meus próprios testes, isso os suavizou completamente. Espero que ajude.

-webkit-backface-visibility: hidden;

7
Lifesaver - esse truque nos permitiu reativar o -webkit-transform em vários sites que anteriormente fomos forçados a desativar as transformações devido a problemas de anti-aliasing. Obrigado!
— Darren


5
Isso funciona no Chrome, mas os torna irregulares novamente no iOS 6!
— lazd

11
@lazd para corrigi-lo no iOS addpadding: 1px; -webkit-background-clip: content-box;
— Rob Fletcher

2
O @RobFletcher adicionou preenchimento e clipe de plano de fundo que, de acordo com esse segmento, parecem essenciais para uma solução entre navegadores e sistemas operacionais. Isso corrige meu problema de OSX / Chrome também, então ... acho que uma solução completa seria algo como:padding: 1px;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-background-clip:content-box;background-clip:content-box;
— Benjamin Luoma

119

Se você estiver usando em transitionvez de transform, -webkit-backface-visibility: hidden;não funciona. Uma aresta serrilhada aparece durante a animação para um arquivo png transparente.

Para resolvê-lo, usei: outline: 1px solid transparent;


4
isso parece ajudar em situações em que a propriedade web-kit-backface-visible perdeu.
— precisa saber é

2
Funciona para mim quando nenhum dos outros funcionou. Antes de adicionar essa propriedade, o Chrome Android tinha problemas. Agora, todos os navegadores parecem funcionar corretamente.
— Bernie Sumption

Funciona para mim no Safari no iOS 8.
— Moritz Friedrich

Solução perfeita. Os outros não funcionaram. Eu quase desisti e duvidava que isso funcionasse. Mas faz!
— Garconis

1
Funciona perfeitamente para as minhas necessidades. Na verdade, estou usando a transição, e as outras respostas estavam fazendo com que meu PNG se tornasse pixelizado no estado padrão. Sua resposta ajudou a remover qualquer pixelização - no estado padrão e durante a transição. Perfeito!
— Garconis

24

Adicionar uma borda transparente de 1px acionará o anti-aliasing

outline: 1px solid transparent;

Como alternativa, adicione uma sombra de caixa transparente de 1px.

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

rgba (255, 255, 255, 0) é provavelmente melhor
— mmm

4
Adicionar a seção superior do CSS na sua resposta e outline: 1px solid transparent;funcionou bem para mim. As outras soluções acima não funcionaram bem o suficiente.
— Timothy Zorn #

outline: 1px solid transparent;gatilho anti-aliasing também em Fogo 52 (que tem os mesmos problemas de cromo)
— Luca Detomi

18

Experimente a transformação 3D. Isso funciona como um encanto!

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

1
tentando fazer isso no chrome agora (agosto de 2013 em um Mac), a solução aceita não está funcionando, mas usá-lo (especificamente preserve-3d; rotateainda pode ser usado sem mudar para rotateZ) funciona.
— 21413 Dave

Super hacky, mas funcionou para mim. Tente um grau menor, como 0,05, para evitar um alinhamento visível.
— cpursley

preserve-3d salvou minha vida.
— Hannes Schneidermayer

8

A resposta escolhida (nem nenhuma das outras respostas) não funcionou para mim, mas isso funcionou:

img {outline:1px solid transparent;}


2

Estou tendo um problema com um gradiente CSS3 com -45deg. A backgroundinclinação era muito irregular, mas pior do que o post original. Então eu comecei a jogar com os dois background-size. Isso esticaria a irregularidade, mas ainda estava lá. Além disso, li que outras pessoas também estão tendo problemas com incrementos de 45 graus, então ajustei de -45degpara-45.0001deg e meu problema foi resolvido.

No meu CSS abaixo, background-sizeera inicialmente 30pxe o deggradiente de fundo era exatamente -45deg, e todos os quadros-chave eram 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

Você pode mascarar o entalhe usando sombras de caixa borradas . O uso de -webkit-box-shadow em vez de box-shadow garantirá que não afete os navegadores que não são da Webkit. Você pode querer verificar o Safari e os navegadores móveis da Web.

O resultado é um pouco melhor, mas ainda muito menos bom que os outros navegadores:

com sombra na caixa (lado de baixo)


1

Apenas pensei em lançar nossa solução também, pois tínhamos exatamente o mesmo problema no Chrome / Windows.

Tentamos a solução por @stevenWatkins acima, mas ainda tivemos o "passo".

Ao invés de

-webkit-backface-visibility: hidden;

Nós costumavamos:

-webkit-backface-visibility: initial;

Para nós, isso fez o truque 🎉


1

Adicionar o seguinte na div que envolve o elemento em questão corrigiu isso para mim.

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

As bordas irregulares estavam aparecendo na janela do vídeo no meu caso.


0

Para mim, foi a propriedade CSS da perspectiva que fez o truque:

-webkit-perspective: 1000;

Completamente ilógico no meu caso, como não uso transições 3D, mas funciona mesmo assim.


0

Para tela no Chrome (versão 52)

Todas as respostas listadas são sobre imagens. Mas meu problema é sobre a tela no chrome (v.52) com transform rotate. Eles ficaram irregulares e todos esses métodos não podem ajudar.

Solução que funciona para mim:

  1. Aumente a tela em 1 px para cada lado => +2 px para largura e altura;
  2. Desenhar imagem com deslocamento + 1px (na posição 1,1 em vez de 0,0) e tamanho fixo (o tamanho da imagem deve ser 2px menor que o tamanho da tela)
  3. Aplicar rotação necessária

Blocos de código tão importantes:

// 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>

Exemplo: https://jsfiddle.net/tLbxgusx/1/

Nota: existem muitas divs aninhadas porque é uma versão simplificada do meu projeto.


Este problema é reproduzido também para o Firefox para mim. Não existe esse problema no Safari e no FF com retina.

E outra solução fundada é colocar a tela em div do mesmo tamanho e aplicar o seguinte css a esta div:

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

E a rotação deve ser aplicada a esta div de empacotamento. A solução listada é trabalhada, mas com pequenas modificações.

E um exemplo modificado para essa solução é: https://jsfiddle.net/tLbxgusx/2/

Nota: Veja o estilo de div com a classe 'third'.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.