Poziome centrowanie CSS stałego div?

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

Wiem, że to pytanie jest milion razy, ale nie mogę znaleźć rozwiązania dla mojej sprawy. Mam div, który powinien zostać naprawiony na ekranie, nawet jeśli strona jest przewijana, zawsze powinna pozostać ŚRODKOWANA na środku ekranu!

Div powinien mieć 500pxszerokość, powinien znajdować 30pxsię z dala od góry (margines-góra), powinien być wyśrodkowany poziomo na środku strony dla wszystkich rozmiarów przeglądarki i nie powinien się poruszać podczas przewijania pozostałej strony.

Czy to jest możliwe?

matowy
źródło

Odpowiedzi:

167
left: 50%;
margin-left: -400px; /* Half of the width */
Quentin
źródło
25
po zmianie rozmiaru okna przeglądarki nie działa zgodnie z przeznaczeniem.
3
@Bahodir: Jesteś pewien? Przy zmianie rozmiaru wygląda mi to dobrze. Myślę, że -400wynika to z ustawionej szerokości div 800.
Merlyn Morgan-Graham,
1
@PrestonBadeer - Podoba Ci się pytanie?
Quentin
3
Całkowicie się zgadzam - to NIE jest rozwiązanie! Nigdy nie koduj czegoś w ten sposób. -1
Nate I
3
Głosowałem za tym NIE, ponieważ była to zła odpowiedź na ten dzień - to była dobra odpowiedź, ale ponieważ już nie jest, a następna najwyższa odpowiedź potrzebuje wszelkiej pomocy, jaką może być postrzegana jako najlepsza odpowiedź TERAZ. Quentin: Myślę, że dobrym pomysłem byłoby edytowanie w komentarzu do tego efektu w samej odpowiedzi - odwróciłbym wtedy swój głos w dół.
Nick Rice
547

Odpowiedzi tutaj są nieaktualne. Teraz możesz łatwo korzystać z transformacji CSS3 bez kodowania marginesu . Działa to na wszystkich elementach, w tym elementach bez szerokości lub szerokości dynamicznej.

Centrum poziome:

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

Centrum pionowe:

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

Zarówno poziomy, jak i pionowy:

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

Zgodność nie stanowi problemu: http://caniuse.com/#feat=transforms2d

Maciej Krawczyk
źródło
86
+1 Ta odpowiedź pokazuje problem z przepełnieniem stosu: stare odpowiedzi, które były dobre na ich dzień i zostały słusznie przyjęte, mogą z dumą siedzieć na szczycie, dając wrażenie, że są nadal odpowiednie, podczas gdy świetne odpowiedzi dla nowego świata, takiego jak ten, muszą walczą o swoje szanse.
Nick Rice
10
@NickRice w 100% uzgodniony. Ta odpowiedź powinna być nową zaakceptowaną odpowiedzią. Młodsi deweloperzy nie powinni nawet zobaczyć aktualnie przyjętej odpowiedzi!
Nate I
2
@matt proszę przyjąć zamiast tego. Przewiń daleko, aby długo to zobaczyć.
ssbb
4
Powoduje to efekt rozmycia w cieniu ramki w elementach treści.
rab
4
Tak, Chrome nieprawidłowo zamazuje treść, która jest transformowana. Tekst jest również rozmazany. Jest to jednak jedyne rozwiązanie, w którym ustalony element jest wyśrodkowany bez twardego kodowania i przy użyciu elementów opakowania. Jeśli nie obchodzą Cię zdarzenia wskaźnika w tle, możesz osiągnąć ten sam efekt za pomocą pełnoekranowego opakowania i Flexboksa lub rozwiązania @ salomvary poniżej.
Maciej Krawczyk
58

Jeśli użycie bloków wbudowanych jest opcją, poleciłbym to podejście:

.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;
} 

Napisałem krótki post na ten temat tutaj: http://salomvary.github.com/position-fixed-horizontally-centered.html

salomwary
źródło
1
10x, to działało świetnie dla mnie bez konieczności kodowania na widthstałe dowolnych cyfr lub czegoś - w przeciwieństwie do odpowiedzi
@Quentins
30

Edytuj wrzesień 2016: Chociaż miło jest wciąż sporadycznie głosować za tym, ponieważ świat się zmienił, wybiorę teraz odpowiedź, która używa transformacji (i ma mnóstwo głosów pozytywnych). Nie zrobiłbym tego więcej w ten sposób.

Innym sposobem, aby nie musieć obliczać marginesu lub potrzebować sub-kontenera:

#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
źródło
@Joey Co robi bottom: 0? tj. dlaczego jest to potrzebne? (Minęło trochę czasu, odkąd na to spojrzałem!)
Nick Rice,
bottom:0upewniłbym się, że menu jest zawsze wyśrodkowane pionowo, ale teraz widzę, że nie o to prosił PO. :)
Jordan H
Próbowałem użyć tego w innym kontekście, ale zorientowałem się, że nie wyśrodkowuje w FF, jeśli wysokość elementów jest wyższa niż wysokość okna (rzutni)
Philipp Werminghausen
Ponieważ świat się zmienił, wybrałbym teraz odpowiedź wykorzystującą transformację. (Robiłem ten komentarz wcześniej, odwołując się do nazwy, której używał odpowiadający - ale zmienili tę nazwę, więc mój komentarz nie ma już sensu i usunąłem go - po prostu wyszukaj na tej stronie transformację).
Nick Rice
7

Istnieje możliwość poziomego wyśrodkowania div w ten sposób:

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;
}

W ten sposób zawsze będziesz mieć wyśrodkowany blok wewnętrzny, a ponadto można go łatwo zmienić na prawdziwy responsywny (w tym przykładzie będzie on płynny na mniejszych ekranach), dlatego nie ma ograniczeń jak w przykładzie pytania i w wybranej odpowiedzi .

Denis V.
źródło
5

... lub możesz owinąć menu div innym:

    <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
źródło
5

Oto kolejne rozwiązanie dla dwóch dywizji. Próbowałem zachować zwięzłość i nie zakodować na stałe. Po pierwsze, oczekiwany HTML:

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

Zasadą stojącą za poniższym css jest umieszczenie pewnej strony „zewnętrznego”, a następnie użycie faktu, że przyjmuje ona rozmiar „wewnętrznego”, aby względnie przesunąć drugą stronę.

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

To podejście jest podobne do podejścia Quentina, ale wewnętrzna może mieć różną wielkość.

Anonimowy
źródło
-1

Oto rozwiązanie typu flexbox w przypadku korzystania z pełnowymiarowego opakowania div. justify-content centre to div div dziecka w poziomie, a align-items centruje go w pionie.

<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
źródło