Як вертикально центрувати вміст зі змінною висотою в розділі?


158

Який найкращий спосіб вертикально центрувати вміст діва, коли висота вмісту змінюється. У моєму конкретному випадку фіксується висота діва контейнера, але було б чудово, якби було рішення, яке працювало б у випадках, коли контейнер також має змінну висоту. Крім того, я б хотів рішення, що не має або дуже мало використовує хаки CSS та / або несемантичну розмітку.

alt текст


метод у цій статті розпадається на Safari (4.0.5): S

7
@ ripper234 Не зовсім так, оскільки це питання стосується перемінної висоти div
Rauli Rajande

9
Також це питання було задано спочатку.
Gui Imamura

Відповіді:


147

Просто додайте

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

до внутрішнього діву.

Це - переміщення верхньої межі внутрішнього діва на половину висоти зовнішнього div ( top: 50%;), а потім внутрішнього поділу на половину його висоти ( transform: translateY(-50%)). Це буде працювати з position: absoluteабо relative.

Майте на увазі, що transformі translateє префікси постачальників, які не включені для простоти.

Codepen: http://codepen.io/anon/pen/ZYprdb


6
Просто цікавило, чому це працює на Chrome і Firefox, але не для Safari. Тоді я помітив, що більшість transformпов’язаних речей - це -webkit-префікс, і зараз це працює. Тож як нагадування: Не забудьте додати і -webkit-префікс.
miho

5
Використовуйте такий інструмент, як github.com/postcss/autoprefixer для обробки префіксів для вас.
Джеймі Чонг

6
Ця відповідь має бути вгорі.
Хосе Фаети

3
Це повинно мати набагато більше результатів! До речі, це теж працює position: absolute, чи не так?
каре

4
Цей метод має невдалий побічний ефект у Chrome - якщо у вашій обгортці є непарна кількість пікселів, то translateвсе буде розмито, коли він намагається обробити висоту .5px у всьому.
Кіт

157

Це здається найкращим рішенням, що я знайшов у цій проблемі, якщо ваш браузер підтримує ::beforeпсевдоелемент: CSS-Tricks: Centering in the Unknown .

Він не вимагає додаткової розмітки і, здається, працює надзвичайно добре. Я не міг використати display: tableметод, оскільки tableелементи не підкоряються max-heightвластивості.

.block {
  height: 300px;
  text-align: center;
  background: #c0c0c0;
  border: #a0a0a0 solid 1px;
  margin: 20px;
}

.block::before {
  content: '';
  display: inline-block;
  height: 100%; 
  vertical-align: middle;
  margin-right: -0.25em; /* Adjusts for spacing */

  /* For visualization 
  background: #808080; width: 5px;
  */
}

.centered {
  display: inline-block;
  vertical-align: middle;
  width: 300px;
  padding: 10px 15px;
  border: #a0a0a0 solid 1px;
  background: #f5f5f5;
}
<div class="block">
    <div class="centered">
        <h1>Some text</h1>
        <p>But he stole up to us again, and suddenly clapping his hand on my
           shoulder, said&mdash;"Did ye see anything looking like men going
           towards that ship a while ago?"</p>
    </div>
</div>


3
Тепер -це - це -BRILLIANT- рішення. Велике спасибі за повідомлення про це!
Трой Алфорд

Як і в іншій відповіді, і ця була б набагато краще, якби вона описала підхід і включила код із посилання.
KatieK

3
+1, це рішення справді досить геніальне! До речі, ви могли б додати .block { white-space: nowrap; font-size: 0; line-height: 0; }і залишити від'ємний правий запас на псевдоелементі, вам просто потрібно скинути fs і lh на .centered ... як це, ви гарантуєте, що елемент буде правильно розміщений, навіть якщо він ширший за область перегляду (і don мені не доведеться використовувати imo трохи безладний від’ємний запас).
Симон

@jessegavin - на ваш погляд ... як робить наступний стек проти підходу , я коротко виклав: stackoverflow.com/questions/396145 / ...
pulkitsinghal

1
Крім того, це руйнується, коли зовнішній контейнер .block замість висоти має мінімальну висоту.
Лінкольн Б

16

Мені це потрібно було робити багато разів, і послідовне рішення все ж вимагає додати трохи несемантичної розмітки та певних хакерських особливостей. Коли ми отримаємо підтримку браузера для css 3, ви отримаєте ваше вертикальне центрування без гріхів.

Для кращого пояснення методики ви можете подивитися статтю, з якої я її адаптував , але в основному вона передбачає додавання додаткового елемента та застосування різних стилів в IE та браузерах, які підтримують position:table\table-cellелементи, що не є таблицями.

<div class="valign-outer">
    <div class="valign-middle">
        <div class="valign-inner">
            Excuse me. What did you sleep in your clothes again last night. Really. You're gonna be in the car with her. Hey, not too early I sleep in on Saturday. Oh, McFly, your shoe's untied. Don't be so gullible, McFly. You got the place fixed up nice, McFly. I have you're car towed all the way to your house and all you've got for me is light beer. What are you looking at, butthead. Say hi to your mom for me.
        </div>
    </div>
</div>

<style>
    /* Non-structural styling */
    .valign-outer { height: 400px; border: 1px solid red; }
    .valign-inner { border: 1px solid blue; }
</style>

<!--[if lte IE 7]>
<style>
    /* For IE7 and earlier */
    .valign-outer { position: relative; overflow: hidden; }
    .valign-middle { position: absolute; top: 50%; }
    .valign-inner { position: relative; top: -50% }
</style>
<![endif]-->
<!--[if gt IE 7]> -->
<style>
    /* For other browsers */
    .valign-outer { position: static; display: table; overflow: hidden; }
    .valign-middle { position: static; display: table-cell; vertical-align: middle; width: 100%; }
</style>

Існує багато способів (хакків) застосування стилів у певних наборах браузерів. Я використовував умовні коментарі, але перегляньте статтю, зв'язану вище, щоб побачити дві інші методи.

Примітка. Існують прості способи отримання вертикального центрування, якщо ви знаєте деякі висоти заздалегідь, якщо ви намагаєтеся відцентрувати один рядок тексту або в кількох інших випадках. Якщо у вас є більше деталей, тоді введіть їх, тому що може бути метод, який не вимагає злому браузера або несемантичної розмітки.

Оновлення: Ми починаємо отримувати кращу підтримку браузера для CSS3, пропонуючи як flex-box, так і перетворення як альтернативні методи отримання вертикального центрування (серед інших ефектів). Дивіться це інше запитання для отримання додаткової інформації про сучасні методи, але майте на увазі, що підтримка браузера все ще є схематичною для CSS3.


Так, я знайшов цю статтю сьогодні і не зміг змусити її працювати в моїй конкретній ситуації. Можливо, мені потрібно ще далі розглянути це.
jessegavin

Можливо, ви можете опублікувати використаний код, який не працює?
Кріс Марасті-Георг

Це все-таки найкраще рішення цієї проблеми?
ripper234

Ця стаття, здається, не працює в Chrome 23, Firefox 16 та IE 9. Ця відповідь здається кращим рішенням.
Фернандо Коррея

Ні, ця стаття все ще працює в останніх Chrome і Firefox станом на 24 лютого 2013 року
OMA

9

Користуючись дочірнім селектором, я звернувся до неймовірної відповіді Фаді і звів її лише до одного правила CSS, яке я можу застосувати. Тепер все, що мені потрібно зробити, це додати contentCenteredім’я класу до елементів, які я хочу зосередити:

.contentCentered {
  text-align: center;
}

.contentCentered::before {
  content: '';
  display: inline-block;
  height: 100%; 
  vertical-align: middle;
  margin-right: -.25em; /* Adjusts for spacing */
}

.contentCentered > * {
  display: inline-block;
  vertical-align: middle;
}
<div class="contentCentered">
  <div>
    <h1>Some text</h1>
    <p>But he stole up to us again, and suddenly clapping his hand on my
      shoulder, said&mdash;"Did ye see anything looking like men going
      towards that ship a while ago?"</p>
  </div>
</div>

Forked CodePen: http://codepen.io/dougli/pen/Eeysg


Класно. Дякую, що поділились. Однією застереженням є те, що *селектор буде виконувати гірше, ніж прийнята відповідь. Це може не бути проблемою, але варто зазначити. stevesouders.com/blog/2009/06/18/simplifying-css-selectors
jessegavin

Дякую. Так, це, мабуть, буде гірше, але сьогодні правила CSS, ймовірно, не сильно впливають на речі. Ми, мабуть, можемо покращити це, вибравши > divнатомість. Calendar.perfplanet.com/2011/…
dougli

Просто і чудово. Для мене працює чудово.
Ловро

4

Найкращий результат для мене поки що:

дів має бути по центру:

position: absolute;
top: 50%;
transform: translateY(-50%);
margin: 0 auto;
right: 0;
left: 0;

Працював як шарм
m4heshd

3

Ви можете використовувати автоматичну маржу. З гнучким виглядом дива, здається, також по центру вертикально.

body,
html {
  height: 100%;
  margin: 0;
}
.site {
  height: 100%;
  display: flex;
}
.site .box {
  background: #0ff;
  max-width: 20vw;
  margin: auto;
}
<div class="site">
  <div class="box">
    <h1>blabla</h1>
    <p>blabla</p>
    <p>blablabla</p>
    <p>lbibdfvkdlvfdks</p>
  </div>
</div>

дисплей: флекс все ще практично експериментальна особливість; ще жоден браузер не підтримує його правильно
andreszs

1

Для мене найкращий спосіб зробити це:

.container{
  position: relative;
}

.element{
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

Перевага полягає не в тому, щоб робити висоту явною


0

Це моє дивовижне рішення для divдинамічної (відсоткової) висоти.

CSS

.vertical_placer{
  background:red;
  position:absolute; 
  height:43%; 
  width:100%;
  display: table;
}

.inner_placer{  
  display: table-cell;
  vertical-align: middle;
  text-align:center;
}

.inner_placer svg{
  position:relative;
  color:#fff;
  background:blue;
  width:30%;
  min-height:20px;
  max-height:60px;
  height:20%;
}

HTML

<div class="footer">
    <div class="vertical_placer">
        <div class="inner_placer">
            <svg> some Text here</svg>
        </div>
    </div>
</div>  

Спробуйте це самостійно.


0

Ви можете використовувати гнучкий дисплей, такий як код нижче:

.example{
  background-color:red;
  height:90px;
  width:90px;
  display:flex;
  align-items:center; /*for vertically center*/
  justify-content:center; /*for horizontally center*/
}
<div class="example">
    <h6>Some text</h6>
</div>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.