O z-index não funciona com posicionamento fixo

422

Eu tenho um divcom posicionamento padrão (ou seja position:static) e um divcom uma fixedposição.

Se eu definir os índices z dos elementos, parece impossível fazer o elemento fixo ficar atrás do elemento estático.

    #over {
      width: 600px;
      z-index: 10;
    }
    
    #under {
      position: fixed;
      top: 5px;
      width: 420px;
      left: 20px;
      border: 1px solid;
      height: 10%;
      background: #fff;
      z-index: 1;
    }
    <!DOCTYPE html>
    <html>
       <body>
          <div id="over">
             Hello Hello HelloHelloHelloHelloHello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello
          </div>  
          <div id="under">
          </div>
       </body>
    </html>

Ou no jsfiddle aqui: http://jsfiddle.net/mhFxf/

Eu posso contornar isso usando position:absolute o elemento estático, mas alguém pode me dizer por que isso está acontecendo?

(Parece haver uma pergunta semelhante a esta, ( Índice z de quebra de posicionamento fixo ), mas ela não tem uma resposta satisfatória; portanto, estou perguntando isso aqui com meu código de exemplo)

DanSingerman
fonte

Respostas:

146

Essa pergunta pode ser resolvida de várias maneiras, mas, na verdade, conhecer as regras de empilhamento permite encontrar a melhor resposta que funciona para você.

Soluções

O <html>elemento é o seu único contexto de empilhamento, portanto, basta seguir as regras de empilhamento dentro de um contexto de empilhamento e você verá que os elementos estão empilhados nessa ordem

  1. O elemento raiz do contexto de empilhamento (o <html>elemento neste caso)
  2. Elementos posicionados (e seus filhos) com valores de índice z negativos (valores mais altos são empilhados na frente de valores mais baixos; elementos com o mesmo valor são empilhados de acordo com a aparência no HTML)
  3. Elementos não posicionados (ordenados pela aparência no HTML)
  4. Elementos posicionados (e seus filhos) com um valor z-index de auto (ordenado pela aparência no HTML)
  5. Elementos posicionados (e seus filhos) com valores de índice z positivos (valores mais altos são empilhados antes de valores mais baixos; elementos com o mesmo valor são empilhados de acordo com a aparência no HTML)

Então você pode

  1. defina um índice z de -1, para o #underíndice z -ve posicionado aparecer atrás do #overelemento não posicionado
  2. defina a posição de #overpara relativeque a regra 5 se aplique a ela

O verdadeiro problema

Os desenvolvedores devem saber o seguinte antes de tentar alterar a ordem de empilhamento dos elementos.

  1. Quando um contexto de empilhamento é formado
    • Por padrão, o <html>elemento é o elemento raiz e o primeiro contexto de empilhamento
  2. Ordem de empilhamento em um contexto de empilhamento

A ordem de empilhamento e as regras de contexto de empilhamento abaixo são deste link

Quando um contexto de empilhamento é formado

  • Quando um elemento é o elemento raiz de um documento (o <html>elemento)
  • Quando um elemento possui um valor de posição diferente de estático e um valor de índice z diferente de automático
  • Quando um elemento tem um valor de opacidade menor que 1
  • Várias propriedades CSS mais recentes também criam contextos de empilhamento. Isso inclui: transformações, filtros, regiões css, mídia paginada e possivelmente outras. https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
  • Como regra geral, parece que se uma propriedade CSS requer renderização em um contexto fora da tela, ela deve criar um novo contexto de empilhamento.

Ordem de empilhamento em um contexto de empilhamento

A ordem dos elementos:

  1. O elemento raiz do contexto de empilhamento (o <html>elemento é o único contexto de empilhamento por padrão, mas qualquer elemento pode ser um elemento raiz para um contexto de empilhamento, consulte as regras acima)
    • Você não pode colocar um elemento filho atrás de um elemento de contexto de empilhamento raiz
  2. Elementos posicionados (e seus filhos) com valores de índice z negativos (valores mais altos são empilhados na frente de valores mais baixos; elementos com o mesmo valor são empilhados de acordo com a aparência no HTML)
  3. Elementos não posicionados (ordenados pela aparência no HTML)
  4. Elementos posicionados (e seus filhos) com um valor z-index de auto (ordenado pela aparência no HTML)
  5. Elementos posicionados (e seus filhos) com valores de índice z positivos (valores mais altos são empilhados antes de valores mais baixos; elementos com o mesmo valor são empilhados de acordo com a aparência no HTML)
Mr_Moneybags
fonte
3
Alguns podem achar isso útil também: O que ninguém lhe disse sobre Z-Index
Mentalist
450

Adicionar position: relative;a #over

    #over {
      width: 600px;
      z-index: 10;
      position: relative;    
    }
    
    #under {
      position: fixed;
      top: 5px;
      width: 420px;
      left: 20px;
      border: 1px solid;
      height: 10%;
      background: #fff;
      z-index: 1;
    }
    <!DOCTYPE html>
    <html>
    <body>
    	<div id="over">
    		Hello Hello HelloHelloHelloHelloHello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello
    	</div>  
    
    	<div id="under"></div>
    </body>
    </html>

Violino

stephenmurdoch
fonte
14
updates.html5rocks.com/2012/09/… é uma excelente referência sobre como a posição fixa, absoluta e relativa interage com o z-index.
Será que
@marflar O prazer é meu. Aliás, dê uma olhada no seu violino. há uma tag extra </body>e uma tag extra </html>no final.
Michel Ayres
2
Aqui está um violino que demonstra o contexto de empilhamento. Está explicado aqui .
Kdbanman
A remoção position: relativedo elemento over realmente corrigiu meu problema.
Alex G
thanksssssss <3
Karl Anthony Baluyot
32

O índice z funciona apenas dentro de um contexto específico relative, fixedou seja , absoluteposição.

O índice z de uma div relativa não tem nada a ver com a z-indexde uma div absoluta ou fixa.

EDITAR Esta é uma resposta incompleta. Esta resposta fornece informações falsas. Leia o comentário e o exemplo de @ Dansingerman abaixo.

cusimar9
fonte
3
Você pode expandir como o z-index funciona em um contexto específico e / ou fornecer uma referência?
precisa saber é o seguinte
13
O índice z afeta a ordem de dois divs, mesmo que um seja relativo à posição e o outro seja absoluto.
Raffael
65
Esta resposta está errada. Aqui está um violino que demonstra o contexto de empilhamento, conforme explicado aqui . @Dansingerman.
Kdbanman
1
Obrigado pelo seu jsFiddle @kbdanman, isso me ajudou a entender o contexto de empilhamento com um visual.
precisa saber é o seguinte
8
@ JoeMorano, o z mais alto está mais próximo do topo, independentemente do posicionamento absoluto ou relativo. O que importa é o nível na árvore de documentos. Divs 4, 5, 6 são filhos da div 3, enquanto divs 1 e 2 são irmãos da div 3. Div 1 tem um z maior que div 3, então div 1 está no topo da div 3 e de todos os seus filhos. Div 2 tem um Z menor do que div 3, de modo div 3 e todos os seus filhos estão no topo de div 2
kdbanman
31

como sua overdiv não tem um posicionamento, o z-index não sabe onde e como posicioná-lo (e com relação a quê?). Apenas mude a posição do over div para relativo, para que não haja efeitos colaterais nesse div e, em seguida, o under div obedecerá à sua vontade.

Aqui está o seu exemplo no jsfiddle: Fiddle

edit : vejo alguém já mencionou esta resposta!

eu estou sério
fonte
18

#underum negativo z-index, por exemplo-1

Isso acontece porque a z-indexpropriedade é ignorada position: static;, que passa a ser o valor padrão; portanto, no código CSS que você escreveu, z-indexé 1para ambos os elementos, independentemente da altura em que você o definir #over.

Ao dar #underum valor negativo, estará atrás de qualquer z-index: 1;elemento, ie #over.

Carlos Precioso
fonte
Eu também tive esse problema - definir o 'under' div para 0 funcionou para mim.
Mick Sear
5

Eu estava construindo um menu de navegação. Eu tenho overflow: hiddenno CSS da minha nav que escondeu tudo. Eu pensei que era um problema do índice z, mas realmente estava escondendo tudo fora da minha navegação.

thedanotto
fonte
0

o comportamento de elementos fixos (e elementos absolutos), conforme definido em CSS Spec:

Eles se comportam à medida que são desanexados do documento e colocados no parente mais próximo fixo / absoluto. (não uma citação de palavra por palavra)

Isso torna o cálculo do zindex um pouco complicado, resolvi meu problema (a mesma situação) criando dinamicamente um contêiner no elemento body e movendo todos esses elementos (que são classificados como "my-fixed-ones" dentro desse elemento no nível do corpo )

Bakhshi
fonte