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

dtech
fonte
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;
Neven
fonte
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
alguma ajuda sobre isso: stackoverflow.com/questions/9235342/… ?
abernier
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;

mhhorizon
fonte
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);
Callam
fonte
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);
Zypherone
fonte
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;}

chris
fonte
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;
        }
Pegues
fonte
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)

dtech
fonte
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 🎉

Nicholas McCreath
fonte
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.

chaser7016
fonte
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.

Aron
fonte
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'.

Kiryl
fonte