CSS горизонтальное центрирование фиксированного div?

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

Я знаю, что этот вопрос миллион раз, но я не могу найти решение для моего случая. У меня есть div, который должен быть исправлен на экране, даже если страница прокручивается, она всегда должна оставаться в центре экрана!

Элемент div должен иметь 500pxширину, должен располагаться 30pxвдали от верхней части (margin-top), должен быть горизонтально центрирован по центру страницы для всех размеров браузера и не должен перемещаться при прокрутке остальной части страницы.

Это возможно?

матовый
источник

Ответы:

167
left: 50%;
margin-left: -400px; /* Half of the width */
Quentin
источник
26
он не работает должным образом при изменении размера окна браузера.
3
@ Баходир: Ты уверен? Это выглядит правильно для меня при изменении размера. Я думаю, что это -400связано с шириной div, установленной на 800.
Мерлин Морган-Грэм
1
@PrestonBadeer - Как тот, о котором спрашивает вопрос?
Квентин
3
Полностью согласен - это НЕ решение! Никогда не кодируйте что-либо таким образом. -1
конец I
3
Я проголосовал за это НЕ, потому что это был плохой ответ для его дня - это был хороший ответ, но потому что это больше не так, и следующий самый высокий ответ нуждается во всей помощи, которую он может получить, чтобы быть замеченным как лучший ответ СЕЙЧАС. Квентин: Я думаю, что было бы неплохо отредактировать комментарий в этом отношении в самом ответе - тогда я бы изменил свое отрицательное голосование.
Ник Райс
547

Ответы здесь устарели. Теперь вы можете легко использовать CSS3-преобразование без жесткого кодирования поля . Это работает для всех элементов, включая элементы без ширины или динамической ширины.

Горизонтальный центр:

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

Вертикальный центр:

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

Горизонтальное и вертикальное:

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

Совместимость не является проблемой: http://caniuse.com/#feat=transforms2d

Мацей Кравчик
источник
87
+1 Этот ответ демонстрирует проблему со stackoverflow: старые ответы, которые были хороши для своего дня и были правильно приняты, могут гордо стоять на вершине, создавая впечатление, что они все еще уместны, в то время как отличные ответы для нового мира, такого как этот, должны пробиться против шансов.
Ник Райс
11
@NickRice согласен на 100%. Этот ответ должен быть новым принятым ответом. Младшие разработчики не должны даже видеть текущий принятый ответ!
Nate I
2
@matt, пожалуйста, прими это. Прокрутите далеко, чтобы увидеть это.
ssbb
4
Это создает эффект размытия в тени блока в элементах содержимого.
Rab
4
Да, Chrome неправильно размывает содержимое, которое преобразуется. Текст также размыт. Но это единственное решение, когда фиксированный элемент центрируется без жесткого кодирования и использования элементов-оболочек. Если вас не волнуют события указателя на фоне, вы можете добиться того же эффекта с помощью полноэкранного упаковщика и flexbox или решения @ salomvary ниже.
Мацей Кравчик
58

Если использование inline-блоков является вариантом, я бы рекомендовал этот подход:

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

Я написал небольшой пост по этому вопросу здесь: http://salomvary.github.com/position-fixed-horizontally-centered.html

salomvary
источник
1
В 10 раз это прекрасно сработало для меня без необходимости жесткого кодирования любых чисел widthили чего-то еще - в отличие от ответа
@Quentins
30

Редактировать сентябрь 2016 года. Хотя неплохо все же время от времени получать за это повышенное голосование, поскольку мир движется дальше, теперь я бы пошел с ответом, в котором используется преобразование (и которое имеет массу голосов). Я бы так больше не делал.

Другой способ - не рассчитывать маржу и не использовать субконтейнер:

#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) */
}
Ник Райс
источник
@Joey Что делает дно: 0? т.е. зачем это нужно? (Прошло некоторое время с тех пор, как я посмотрел на это!)
Ник Райс
bottom:0будет гарантировать, что меню всегда центрировано по вертикали, но теперь я вижу, что это не то, о чем просил ОП. :)
Джордан Х
Я попытался использовать это в другом контексте, но выяснил, что он не центрируется в FF, если высота элементов выше, чем высота окна (области просмотра)
Philipp Werminghausen
Поскольку мир движется дальше, я бы сейчас пошел с ответом, который использует преобразование. (Я сделал этот комментарий раньше, ссылаясь на имя, которое использовал ответчик - но они изменили это имя, так что мой комментарий больше не имел смысла, и я удалил его - просто вместо этого ищите на этой странице преобразование.)
Ник Райс
7

Можно центрировать div по горизонтали следующим образом:

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

Используя этот способ, вы всегда будете центрировать свой внутренний блок, кроме того, его можно легко превратить в истинно отзывчивый (в примере он будет просто плавным на меньших экранах), поэтому нет ограничений как в примере вопроса, так и в выбранном ответе. ,

Денис V
источник
5

... или вы можете обернуть ваше меню div в другое:

    <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
источник
5

Вот еще одно решение для двух делений. Старался быть кратким и не жестко закодированным. Во-первых, ожидаемый HTML:

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

Принцип, лежащий в основе следующего CSS, состоит в том, чтобы расположить некоторую сторону «внешней», а затем использовать тот факт, что он принимает размер «внутренней», чтобы относительно сместить последнюю.

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

Этот подход похож на подход Квентина, но внутренний может иметь переменный размер.

анонимное
источник
-1

Вот решение flexbox при использовании полноэкранного упаковщика div. justify-content centres это дочерний div горизонтально, а align-items центрирует его вертикально.

<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
}
Вена Тан
источник