CSS centralização horizontal de uma div fixa?

183
#menu {
    position: fixed;
    width: 800px;
    background: rgb(255, 255, 255); /* The Fallback */
    background: rgba(255, 255, 255, 0.8);
    margin-top: 30px;
}

Eu sei que essa pergunta existe um milhão de vezes, mas não consigo encontrar uma solução para o meu caso. Eu tenho uma div, que deve ser corrigida na tela, mesmo que a página seja rolada, ela sempre deve permanecer centralizada no meio da tela!

A div deve ter 500pxlargura, deve estar 30pxafastada da parte superior (margem superior), centralizada horizontalmente no meio da página para todos os tamanhos de navegador e não deve se mover ao rolar o restante da página.

Isso é possível?

mate
fonte

Respostas:

167
left: 50%;
margin-left: -400px; /* Half of the width */
Quentin
fonte
25
não funciona como pretendido quando você redimensiona a janela do navegador.
3
@ Bahodir: Você tem certeza? Parece certo para mim no redimensionamento. Eu acho que isso -400se deve à largura da div que está sendo configurada 800.
Merlyn Morgan-Graham
1
@PrestonBadeer - Como o que a pergunta está fazendo?
Quentin
3
Concordo plenamente - isso NÃO é uma solução! Nunca codifique algo dessa maneira. -1
Nate I
3
Votei isso NÃO, porque era uma resposta ruim para o seu dia - era uma boa resposta, mas porque não é mais, e a resposta mais alta precisa de toda a ajuda possível para ser vista como a melhor resposta AGORA. Quentin: Eu acho que seria uma boa ideia editar um comentário para esse efeito na própria resposta - então eu reverteria meu voto negativo.
Nick Rice
547

As respostas aqui estão desatualizadas. Agora você pode facilmente usar uma transformação CSS3 sem codificar uma margem . Isso funciona em todos os elementos, incluindo elementos sem largura ou largura dinâmica.

Centro horizontal:

left: 50%;
transform: translateX(-50%);

Centro vertical:

top: 50%;
transform: translateY(-50%);

Horizontal e vertical:

left: 50%;
top: 50%;
transform: translate(-50%, -50%);

A compatibilidade não é um problema: http://caniuse.com/#feat=transforms2d

Maciej Krawczyk
fonte
86
+1 Esta resposta demonstra um problema com o stackoverflow: as respostas antigas que eram boas para o dia e foram corretamente aceitas podem ficar orgulhosas no topo, dando a impressão de que ainda são apropriadas, enquanto as ótimas respostas para um mundo mais novo, como este, precisam lutar contra as probabilidades.
Nick Rice
10
@NickRice 100% concordou. Essa resposta deve ser a nova resposta aceita. Os desenvolvedores juniores nem deveriam ver a resposta aceita atualmente!
Nate I
2
@matt, por favor aceite este. Role muito para ver isso.
Ssbb 01/07
4
Isso cria efeitos de desfoque na sombra da caixa nos elementos de conteúdo.
rab
4
Sim, o Chrome desfoca incorretamente o conteúdo que é transformado. O texto também está desfocado. Mas esta é a única solução para ter um elemento fixo centralizado sem codificação e usando elementos de wrapper. Se você não se importa com os eventos de ponteiro do plano de fundo, pode obter o mesmo efeito com um wrapper de tela cheia e flexbox, ou a solução do @ salomvary abaixo.
Maciej Krawczyk
58

Se o uso de blocos embutidos for uma opção, eu recomendaria esta abordagem:

.container { 
    /* fixed position a zero-height full width container */
    position: fixed;
    top: 0; /* or whatever position is desired */
    left: 0;
    right: 0;
    height: 0;
    /* center all inline content */
    text-align: center;
}

.container > div {
    /* make the block inline */
    display: inline-block;
    /* reset container's center alignment */
    text-align: left;
} 

Eu escrevi um pequeno post sobre isso aqui: http://salomvary.github.com/position-fixed-horizontally-centered.html

salomário
fonte
1
10x, isso funcionou muito bem para mim w / o ter que codificar os números para widthou algo assim - ao contrário @Quentins resposta
Yatharth Agarwal
30

Editar setembro de 2016: Embora seja bom ainda obter uma votação ocasional ocasional para isso, porque o mundo mudou, agora eu iria com a resposta que usa transform (e que tem uma tonelada de votos). Eu não faria mais dessa maneira.

Outra maneira de não precisar calcular uma margem ou precisar de um sub-container:

#menu {
    position: fixed;   /* Take it out of the flow of the document */
    left: 0;           /* Left edge at left for now */
    right: 0;          /* Right edge at right for now, so full width */ 
    top: 30px;         /* Move it down from top of window */
    width: 500px;      /* Give it the desired width */ 
    margin: auto;      /* Center it */
    max-width: 100%;   /* Make it fit window if under 500px */ 
    z-index: 10000;    /* Whatever needed to force to front (1 might do) */
}
Nick Rice
fonte
@ Joey O que faz o fundo: 0 faz? ou seja, por que é necessário? (É algum tempo desde que eu olhei para isso!)
Nick Rice,
bottom:0garantiria que o menu esteja sempre centralizado verticalmente, mas agora vejo que não é isso que o OP solicitou. :)
Jordan H
Eu tentei usar isso em um contexto diferente byt descobri que não centro em FF se a altura elementos é maior do que a altura da janela (janela)
Philipp Werminghausen
Como o mundo seguiu em frente, agora eu iria com a resposta que usa transformação. (Eu fiz este comentário antes, fazendo referência ao nome que responde usado - mas eles mudaram esse nome assim que meu comentário não fazia mais sentido e eu excluí-la -. Basta procurar nesta página, para transformar em vez)
Nick Rice,
7

É possível centralizar horizontalmente a div desta maneira:

html:

<div class="container">
    <div class="inner">content</div>
</div>

css:

.container {
    left: 0;
    right: 0;
    bottom: 0; /* or top: 0, or any needed value */
    position: fixed;
    z-index: 1000; /* or even higher to prevent guarantee overlapping */
}

.inner {
    max-width: 600px; /* just for example */
    margin: 0 auto;
}

Dessa maneira, você sempre terá seu bloco interno centralizado; além disso, ele pode ser facilmente transformado em verdadeiro responsivo (no exemplo, será apenas fluido em telas menores), portanto, não há limitação, como no exemplo da pergunta e na resposta escolhida. .

Denis V
fonte
5

... ou você pode agrupar seu menu div em outro:

    <div id="wrapper">
       <div id="menu">
       </div>
    </div>


#wrapper{
         width:800px;
         background: rgba(255, 255, 255, 0.8);
         margin:30px auto;
         border:1px solid red;
    }

    #menu{
        position:fixed;
        border:1px solid green;
        width:300px;
        height:30px;
    }
Meduza
fonte
5

Aqui está outra solução de duas div. Tentou mantê-lo conciso e não codificado. Primeiro, o html esperado:

<div id="outer">
  <div id="inner">
    content
  </div>
</div>

O princípio por trás do css a seguir é posicionar algum lado de "externo" e, em seguida, usar o fato de que ele assume o tamanho de "interno" para mudar relativamente o último.

#outer {
  position: fixed;
  left: 50%;          // % of window
}
#inner {
  position: relative;
  left: -50%;         // % of outer (which auto-matches inner width)
}

Essa abordagem é semelhante à de Quentin, mas interna pode ser de tamanho variável.

Anônimo
fonte
-1

Aqui está uma solução flexbox ao usar uma div de wrapper de tela cheia. justificar conteúdo centra sua criança div horizontalmente e alinhar itens centraliza verticalmente.

<div class="full-screen-wrapper">
    <div class="center"> //... content</div>
</div>

.full-screen-wrapper { 
  position: fixed;
  display: flex;
  justify-content: center;
  width: 100vw;
  height: 100vh;
  top: 0;
  align-items: center;
}

.center {
  // your styles
}
Vien Tang
fonte