Posições corrigidas não funcionam ao usar -webkit-transform


155

Estou usando -webkit-transform (e -moz-transform / -o-transform) para girar uma div. Além disso, a posição fixa foi adicionada para que a div role com o usuário.

No Firefox, ele funciona bem, mas nos navegadores baseados em webkit está quebrado. Depois de usar a transformação -webkit, a posição corrigida não funciona mais! Como isso é possível?


4
Uma página de demonstração geralmente ajuda as pessoas a responderem a perguntas - o jsbin.com permite criar páginas temporárias para ilustrar o problema, se você não deseja criar um link para o seu site.
Ricos Bradshaw

jsfiddle.net é outro bom exemplo de uma lixeira temporária de edição.
Kyle

@ Rich Bradshaw jsbin.com é muito legal. Não sabia até agora. A maioria dos meus projetos são executados localmente, então vou usá-lo na próxima vez. Tnx
iSenne

7
Não funciona bem no Firefox.
vsync

3
Ainda é um problema em 2017. Parece que eles ainda estão aderindo ao "É um recurso, não um bug!" argumento ...
Max

Respostas:


87

Após algumas pesquisas, houve um relatório de bug no site do Chromium sobre esse problema, até o momento os navegadores Webkit não conseguem processar esses dois efeitos juntos ao mesmo tempo.

Eu sugeriria adicionar algum CSS apenas do Webkit à sua folha de estilo e transformar a div transformada em uma imagem e usá-la como plano de fundo.

@media screen and (-webkit-min-device-pixel-ratio:0) {
  /* Webkit-specific CSS here (Chrome and Safari) */

  #transformed_div {
    /* styles here, background image etc */
  }
}

Então, por enquanto, você terá que fazer isso da maneira antiga, até que os navegadores Webkit atinjam o FF.

EDIT: A partir de 24/10/2012, o bug não foi resolvido.


Parece não ser um bug, mas um aspecto da especificação devido aos dois efeitos que exigem sistemas de coordenadas e ordens de empilhamento separados. Como explicado nesta resposta .


34
Ainda mais anos depois, ainda não resolvido. Muito triste.
Amalgovinus

9
De acordo com esta resposta , não é um bug, mas parte das especificações.
precisa

15
sente-se e assista - aposto que ele viverá até seu aniversário de 10 anos #
lzl124631x

29
30 de agosto de 2017, log do capitão. Também encontramos a estranha anomalia descrita há muito tempo por outros capitães. Uma solução ainda está para ser implementada.
Luoruize 30/08

14
Este é o bug que o pai do meu pai me alertou.
danjones_mcr

96

A especificação CSS Transforms explica esse comportamento. Os elementos com transformações agem como um bloco de contenção para descendentes de posições fixas; portanto, position: fixo em algo com uma transformação não tem mais comportamento fixo.

Eles funcionam quando aplicados ao mesmo elemento; o elemento será posicionado como fixo e depois transformado.


9
Essa é a única resposta útil e correta. Pare de traduzir o elemento pai e traduza os filhos onde o elemento fixo faz parte dele. Aqui está o meu violino: JSFIDDLE
Falk

2
e se eu quiser transformar um elemento fixo também?
Marc

7

Para quem acha que suas imagens de plano de fundo estão desaparecendo no Chrome devido ao mesmo problema com o anexo de plano de fundo: corrigido; - esta foi a minha solução:

// run js if Chrome is being used
if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
    // set background-attachment back to the default of 'scroll'
    $('.imagebg').css('background-attachment', 'scroll');

    // move the background-position according to the div's y position
    $(window).scroll(function(){

        scrollTop = $(window).scrollTop();
        photoTop = $('.imagebg').offset().top;
        distance = (photoTop - scrollTop);
        $('.imagebg').css('background-position', 'center ' + (distance*-1) + 'px');

    });
}  

6

Algo (um pouco hacky) que funcionou para mim é position:sticky:

.fixed {
     position: sticky;
}

5
updates.html5rocks.com/2012/08/... ah sim .. mas não bem suportado ainda parece
Coiso

1
pegajoso é diferente. O principal problema é que, com o fixo, queremos ignorar a posição do contêiner (muito útil. Para animações de opacidade, por exemplo). Não acredito que esse bug ainda esteja lá anos depois. Horrível.
FlorianB 07/07

6

Agosto de 2016 e posição fixa e animação / transformação ainda são um problema. A única solução que funcionou para mim - foi criar uma animação para o elemento filho que leva mais tempo.


Por favor, responda a novas perguntas. Essas perguntas precisam de você mais do que da pessoa que fez a pergunta em 2010. Elas devem ter resolvido o problema agora, você não acha? Além disso, esta pergunta já tem uma resposta aceita.
Umair Farooq

5
Não! Ainda é um problema ... a pessoa que fez a pergunta pode ter encontrado outra solução - mas eu encontrei esse tópico por um motivo.
Deflitra

Como quiser. Deixei esse comentário enquanto analisava as primeiras perguntas das pessoas. E desde que você entrou hoje, essa foi sua primeira resposta e também uma resposta tardia, por isso deixei esse comentário. Eu não voto negativo. Essa é uma boa chance para você.
Umair Farooq

1
@UmairFarooq talvez fazer outra pergunta seja inútil, pois pode ser marcado como duplicado. Eu vim aqui apenas com uma pesquisa no google e achei esta pergunta útil, resposta defligra também.
Ḳomah

3

Na verdade, eu encontrei outra maneira de corrigir esse "bug":

Eu tenho um elemento contêiner que contém página com animações CSS3. Quando a página concluiu a animação, a propriedade css3 possui o valor: transform: translate (0,0) ;. Então, acabei de remover essa linha e tudo funcionou como deveria - position: fixed é exibido corretamente. Quando a classe css é aplicada para traduzir a página, a propriedade translate é adicionada e a animação css3 também funciona.

Exemplo:

.page {
     top: 50px;
     position: absolute;
     transition: ease 0.6s all;
     /* -webkit-transform: translate(0, 0); */
     /* transform: translate(0,0); */
 }
 .page.hide {
     -webkit-transform: translate(100%, 0);
     transform: translate(-100%, 0);    
 }

Demonstração: http://jsfiddle.net/ZWcD9/


1
Para mim, foi o fato de ter esses estilos no wrapper contendo o elemento fixo que impedia que o elemento fixo fosse pegajoso: -webkit-perspective: 1000; -webkit-transform-style: preserve-3d; Tirei isso e tudo funciona bem. Eles eram otimizações questionáveis ​​de qualquer maneira!
Amalgovinus

A remoção da transformação, por qualquer meio, é provavelmente a melhor solução alternativa até o momento. Algo como um desvanecimento, uma vez concluído, deve ser removível sem afetar a aparência do elemento. Na verdade, não tenho certeza do que ter um transformX (0) por aí faria para renderizar o desempenho, se é que havia alguma coisa; isso pode ser ignorado ou prejudicar o desempenho ou torná-lo melhor forçando algum tipo de aceleração 3D. Quem sabe. De qualquer forma, quando uma animação é concluída, ou mesmo antes de um elemento fixo ser incluído, é possível remover as classes CSS da transformação.
Triynko

1

no meu projeto phonegap, o webkit transform -webkit-transform: translateZ (0); funcionou como um encanto. Ele já estava funcionando no chrome e safari, mas não no navegador móvel. também pode haver mais um problema, pois os DIVs WRAPPER não são concluídos em alguns casos. aplicamos uma classe clara no caso de divs flutuantes.

<div class="Clear"></div> .Clear, .Clearfix{clear:both;}

1

Provavelmente devido a um erro no Chrome, pois não consigo replicar no Safari nem no Firefox, mas isso funciona no Chrome 40.0.2214.111 http://jsbin.com/hacame/1/edit?html,css,output

É uma estrutura muito particular e, portanto, não é de forma alguma uma correção de CSS universalmente aplicável, mas talvez alguém possa mexer nela para fazê-la funcionar no Safari e Firefox.


1

Eu tive esse problema enquanto tentava implementar a cor do reator com visualizações de swipeable de reação (rsw). O problema para mim foi que rsw se aplica translate(-100%, 0)a um painel de guias que quebra a div de posição fixa padrão adicionada na tela inteira que, quando clicada, fecha o modelo do seletor de cores.

Para mim, a solução foi aplicar a transformação oposta ao elemento corrigido (nesse caso, translate(100%, 0)que corrigiu meu problema. Não tenho certeza se isso é útil em outros casos, mas pensei em compartilhar de qualquer maneira.

Aqui está um exemplo mostrando o que descrevi acima:

https://codepen.io/relativemc/pen/VwweEez


0

Adicionar o -webkit-transformelemento fixo resolveu o problema para mim.

.fixed_element {
   -webkit-transform: translateZ(0);
   position: fixed;
   ....
} 

20
Isso não funcionou para mim. Você é capaz de criar uma demonstração disso funcionando?
alex

4
Isso corrigiu um problema para mim no Chrome, FWIW. Obrigado Ron.
31413 Chris

3
Obrigado, isso me corrigiu um problema. Salvou a minha vida!
styke

1
@ Neil Monroe, o Android 2.3 é uma história totalmente nova. Ele não suporta o posicionamento fixo em todos os :)
Wiseman

8
Aqui está um violino onde o uso translateZ(0) NÃO funciona. É verdade que às vezes funciona, já vi ocasiões em que funcionava. Mas ainda não consigo reduzi-lo.
Zequez 10/03

0

Aqui está o que funciona para mim em todos os navegadores e dispositivos móveis testados (Chrome, IE, Firefox, Safari, iPad, iphone 5 e 6, Android).

img.ui-li-thumb {
    position: absolute;
    left: 1px;
    top: 50%;

    -ms-transform: translateY(-50%);
    -webkit-transform: translateY(-50%);
    -moz-transform: translateY(-50%);
    -o-transform: translateY(-50%);
    transform: translateY(-50%);
}

2
Por que os votos negativos? Seria bom se você fornecesse um comentário sobre por que votou na minha resposta?
Murf 15/08/16

0

a posição fixa de um elemento será interrompida se você aplicar a conversão a qualquer ancestral.

<div style='position:fixed;-.*-transform:scale(2)'>...</div> //ok

<div style='-.*-transform:scale(2)'>
      <div style='position:fixed'>...</div> // broken
</div>

0

Se você pode usar o javascript como uma opção, isso pode ser uma solução alternativa para posicionar um elemento fixo da posição relutivo para a janela quando estiver dentro de um elemento transformado:

  let fixedEl // some node that you is position 
              // fixed inside of an element that has a transform

  const rect = fixedEl.getBoundingClientRect()
  const distanceFromWindowTop = rect.top
  const distanceFromWindwoLeft = rect.left
  let top = fixedEl.offsetTop
  let left = fixedEl.offsetLeft

  if(distanceFromWindowTop !== relativeTop) {
    top = -distanceFromWindowTop
    fixedEl.style.top = `${top}px`
  }

  if(distanceFromWindowLeft !== relativeLeft) {
    left = -distanceFromWindowLeft
    fixedEl.style.left = `${left}px`
  }

Concedido, você também terá que ajustar suas alturas e largura, porque fixedElcalculará isso com base no contêiner. Isso depende do seu caso de uso, mas isso permitirá que você defina previsivelmente a posição de algo fixo, independentemente de seu contêiner.


0

Adicione uma classe dinâmica enquanto o elemento se transforma. $('#elementId').addClass('transformed'). Em seguida, declare em css,

.translatX(@x) { 
     -webkit-transform: translateX(@X); 
             transform: translateX(@x);
      //All other subsidaries as -moz-transform, -o-transform and -ms-transform 
}

então

#elementId { 
      -webkit-transform: none; 
              transform: none;
}

então

.transformed {
    #elementId { 
        .translateX(@neededValue);
    }
}

Agora position: fixed quando fornecido com os valores das propriedades top e z-index em um elemento filho, apenas funciona bem e permanece fixo até que o elemento pai se transforme. Quando a transformação é revertida, o elemento filho aparece como corrigido novamente. Isso deve facilitar a situação se você estiver realmente usando uma barra lateral de navegação que abre e fecha com um clique e você tem um conjunto de guias que deve permanecer fixo ao rolar a página.


0

no meu caso, descobri que não podemos usar transform: translateX () antes de transform: translateY (). se quisermos usar os dois, devemos usar transform: translate (,).


-1

Por favor, não vote, porque essa não é a resposta exata, mas pode ajudar alguém, porque é a maneira mais rápida de desativar a transformação. Se você realmente não precisa da transformação no pai e deseja que sua posição fixa volte a funcionar:

#element_with_transform {
  -webkit-transform: none;
  transform: none;
}

1
Isto é, tipo, realmente no título da pergunta
Eugene Pankov

@EugenePankov Não vê 'nenhum' no título. Foi o que resolveu o meu problema e, em geral, ninguém sugere desligá-lo. Embora essa não seja a resposta exata para essa pergunta, ela pode ajudar alguém que não deseja usar a transformação e a transformação vem de outra biblioteca. Então, eu não quero votos, mas, por favor, não vote abaixo. Vou editar minha pergunta para dizer que não quero que o voto seja votado.
makkasi
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.