Як вирівняти вміст div до нижнього


1163

Скажіть, у мене є такий CSS та HTML-код:

#header {
  height: 150px;
}
<div id="header">
  <h1>Header title</h1>
  Header content (one or multiple lines)
</div>

Розділ заголовка має фіксовану висоту, але вміст заголовка може змінюватися.

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

Отже, якщо є лише один рядок тексту, це було б так:

-----------------------------
| Назва заголовка
|
|
|
| вміст заголовка (в результаті виходить один рядок)
-----------------------------

І якби було три рядки:

-----------------------------
| Назва заголовка
|
| вміст заголовка (що так
| багато речі, що це ідеально
| проміжки на три лінії)
-----------------------------

Як це можна зробити в CSS?

Відповіді:


1322

Відношення + абсолютне позиціонування - найкраща ставка:

#header {
  position: relative;
  min-height: 150px;
}

#header-content {
  position: absolute;
  bottom: 0;
  left: 0;
}

#header, #header * {
  background: rgba(40, 40, 100, 0.25);
}
<div id="header">
  <h1>Title</h1>
  <div id="header-content">Some content</div>
</div>

Але ви можете зіткнутися з проблемами з цим. Коли я спробував це, у мене виникли проблеми із меню, що випадає, що відображається нижче вмісту. Це просто не красиво.

Чесно кажучи, для питань вертикального центрування та, будь-яких проблем з вертикальним вирівнюванням елементів, не встановлена ​​висота, простіше просто використовувати таблиці.

Приклад: Чи можна зробити цей HTML-макет без використання таблиць?


4
Я насправді знайшов це рішення, перш ніж запитати тут, але якось забув додати позицію: відносний; до розділу заголовка, а вміст зберігається в нижній частині сторінки. Спасибі
kristof

15
Ви можете керувати своєю спадною позицією за допомогою властивості z-index, щоб вивести її на передню. Пам'ятайте, що властивість z-index працює з елементами, розташованими відносно або абсолютно. Крім того, неправильно семантично говорити, щоб використовувати таблицю для досягнення результатів компонування.
Алехандро Гарсія Іглесіас

1
Що стосується текстового вмісту, як описано в початковій проблемі, # зміст заголовка дійсно повинен бути pелементом, або, принаймні,span
Джош Берджесс

2
Не використовуйте таблиці для нетабличних даних! Замість цього використовуйте властивості відображення CSS display: table-cellабо table-row, або table. Вам більше не потрібно використовувати таблиці для чистого планування.
Джеремі Моріц

1
Позиція заголовка відносно чого?
stack1

158

Використовуйте позиціонування CSS:

/* Creates a new stacking context on the header */
#header {
  position: relative;
}

/* Positions header-content at the bottom of header's context */
#header-content {
  position: absolute;
  bottom: 0;
}

Як зазначав Клетус , вам потрібно визначити вміст заголовка, щоб зробити цю роботу.

<span id="header-content">some header content</span>

<div style="height:100%; position:relative;">
    <div style="height:10%; position:absolute; bottom:0px;">bottom</div>
</div>

4
fyi ... це призвело до того, що мій вміст width = '100%'заголовка
збільшив

2
@dsdsdsdsd Ви також можете це виправити, додавши display: block до # header-content.
Патрік МакЕлхані

1
@dsdsdsdsd Причина полягає в тому, що <span>елементи мають display: inline;за замовчуванням, які не займають повну ширину контейнера. Найбільш підходящим виправленням буде змінити проміжок на a <div>, який є блоковим елементом за замовчуванням.
BadHorsie

1
Або один з <h1> - <h6>, який також блокується за замовчуванням і ідентифікує текст як заголовок, що корисно для пошукових систем, допоміжних технологій та людей, які читають код.
Патрік МакЕлхані

Не працює, коли вміст на дні має змінну висоту, змушує його виходити за межі контейнера.
Мозфет

126

Якщо ви не турбуєтесь про застарілі веб-переглядачі, використовуйте флексбокс.

Батьківському елементу потрібен тип відображення, встановлений для згинання

div.parent {
  display: flex;
  height: 100%;
}

Потім ви встановлюєте дочірній елемент вирівнювання-self на flex-end.

span.child {
  display: inline-block;
  align-self: flex-end;
}

Ось ресурс, який я вивчав: http://css-tricks.com/snippets/css/a-guide-to-flexbox/


@bafromca, дві причини, які не працюють. 1: Використовуйте "align-self" замість вирівнювання елементів (з моєї вини, я відредагував своє початкове повідомлення). 2: 100% висота не буде працювати, якщо батько не має висоти.
Лі Ірвін

Не працювало для мене, я хочу, щоб це було на дні контейнера, а не в кінці предметів у контейнері.
Мозфет

У 2020 році це повинно бути правильна відповідь: caniuse.com/#feat=flexbox
tonygatta

119

Я використовую ці властивості, і це працює!

#header {
  display: table-cell;
  vertical-align: bottom;
}

42
Не підтримується в IE8 і раніше. Він підтримується в IE9.
random_user_name

23
@cale_b За caniuse.com це РОБИТЬ роботу в IE8.
Zach Lysobey

5
@ZachL Happenstance - я підтримую застарілий додаток в IE8 для корпоративного клієнта, і це насправді працює.
Даніель Сабо

4
@fguillen: тестується також у Chrome (v31). Там теж працює.
Даніель Сабо

5
table-cellламає багато речей. Як і сітка Bootstrap. col-md-12більше не дасть вам 100% ширину.
Ной

65

Протягом деякого часу, бороючись із цим самим питанням, я нарешті придумав рішення, яке відповідає всім моїм вимогам:

  • Не вимагає, щоб я знав висоту контейнера.
  • На відміну від відносних + абсолютних рішень, вміст не плаває у своєму власному шарі (тобто нормально вбудовується у контейнер div).
  • Працює в браузерах (IE8 +).
  • Простий у виконанні.

Рішення бере лише один <div>, який я називаю "вирівнювачем":

CSS

.bottom_aligner {
    display: inline-block;
    height: 100%;
    vertical-align: bottom;
    width: 0px;
}

html

<div class="bottom_aligner"></div>
... Your content here ...

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

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

CSS:

.outer-container {
  border: 2px solid black;
  height: 175px;
  width: 300px;
}

.top-section {
  background: lightgreen;
  height: 50%;
}

.bottom-section {
  background: lightblue;
  height: 50%;
  margin: 8px;
}

.bottom-aligner {
  display: inline-block;
  height: 100%;
  vertical-align: bottom;
  width: 3px;
  background: red;
}

.bottom-content {
  display: inline-block;
}

.top-content {
  padding: 8px;
}

HTML:

<body>
  <div class="outer-container">
    <div class="top-section">
      This text
      <br> is on top.
    </div>
    <div class="bottom-section">
      <div class="bottom-aligner"></div>
      <div class="bottom-content">
        I like it here
        <br> at the bottom.
      </div>
    </div>
  </div>
</body>

Вирівняйте нижній вміст


Майже ідеально :), але це не дозволяє автоматичні розриви ліній.
Гастон Санчес

Не працює, якщо зовнішній контейнер може прокручуватися (overflow-y: auto). :(
ecraig12345

Я здогадуюсь, що marin: 8px повинна бути маржа: 8px
Грем Перрін

2
Це також працює, якщо встановити ::beforeправило, яке усуває потребу в додатковому елементі. Ми використовували flex в кінці, але це корисно, коли ви не можете.
Sheepy

Це дійсно приємне рішення. Він працює лише в тому випадку, якщо встановлено heightкоробку / контейнер та його батьків (у px або% чи що завгодно).
BairDev

38

Сучасний спосіб зробити це було б за допомогою флексбоксу . Дивіться приклад нижче. Вам навіть не потрібно загортатись Some text...у будь-який тег HTML, оскільки текст, що безпосередньо міститься у контейнері flex, загорнутий у анонімний елемент flex.

header {
  border: 1px solid blue;
  height: 150px;
  display: flex;                   /* defines flexbox */
  flex-direction: column;          /* top to bottom */
  justify-content: space-between;  /* first item at start, last at end */
}
h1 {
  margin: 0;
}
<header>
  <h1>Header title</h1>
  Some text aligns to the bottom
</header>

Якщо є лише якийсь текст, і ви хочете вирівняти вертикально до дна контейнера.

section {
  border: 1px solid blue;
  height: 150px;
  display: flex;                   /* defines flexbox */
  align-items: flex-end;           /* bottom of the box */
}
<section>Some text aligns to the bottom</section>


2
Мені потрібен мій елемент, що вирівнюється внизу, щоб все ще знаходився в документообігу, що неможливо при використанні position:absolute;. Це рішення чудово працювало для моєї справи!
Swen

1
Всередині реагуючих компонентів це правильне рішення. Прийняте рішення не вдається.
Soleil - Mathieu Prévot

1
Це єдине рішення, яке насправді працювало на мене. Можливо, це стосується React, як згадував @Soleil ... Я не експерт CSS, тому я не зовсім впевнений.
BK

Відмінно працює у складі реакції
користувач1155773

25

Вбудовані або вбудовані елементи блоку можуть бути вирівняні внизу елементів рівня блоку, якщо висота лінії батьківського / блокового елемента більша, ніж у елемента вбудованого елемента. *

розмітка:

<h1 class="alignBtm"><span>I'm at the bottom</span></h1>

css:

h1.alignBtm {
  line-height: 3em;
}
h1.alignBtm span {
  line-height: 1.2em;
  vertical-align: bottom;
}

* переконайтесь, що ви перебуваєте в стандартному режимі


25
display: flex;
align-items: flex-end;

2
Зауважте, що флексбокс не підтримується в старих браузерах.
AnthonyB

11
@AnthonyB - визначити старий? Ми повинні змінити цей запис як розробники. Технологія рухається вперед, а старі просто не виживають. У IE9 та 10 є проблеми з flex, що я бачу, але вони були випущені відповідно у 2011 та 2012 роках ... це 2017. Ми повинні відпустити ці застарілі та зламані браузери. Якщо не для візуального задоволення, а для безпеки та загальних оновлень програмного забезпечення.
Тиш

3
@Tisch, ви абсолютно праві, що ми, як розробники, повинні використовувати пристойні та новітні технології. Але я б просто попередив про це питання сумісності, щоб не здивуватися.
AnthonyB

якщо вміст під знаком <h1>знаходиться всередині <p>або <div>я б використовував justify-content: space-between.
агапітокандемор

11

Ви можете просто досягти гнучкості

header {
  border: 1px solid blue;
  height: 150px;
  display: flex;                   /* defines flexbox */
  flex-direction: column;          /* top to bottom */
  justify-content: space-between;  /* first item at start, last at end */
}
h1 {
  margin: 0;
}
<header>
  <h1>Header title</h1>
  Some text aligns to the bottom
</header>


6

Якщо у вас є кілька елементів динамічної висоти, використовуйте значення відображення CSS таблиці та комірки таблиці:

HTML

<html>
<body>

  <div class="valign bottom">
    <div>

      <div>my bottom aligned div 1</div>
      <div>my bottom aligned div 2</div>
      <div>my bottom aligned div 3</div>

    </div>
  </div>

</body>
</html>

CSS

html,
body {
  width: 100%;
  height: 100%;
}
.valign {
  display: table;
  width: 100%;
  height: 100%;
}
.valign > div {
  display: table-cell;
  width: 100%;
  height: 100%;
}
.valign.bottom > div {
  vertical-align: bottom;
}

Я створив тут демонстрацію JSBin: http://jsbin.com/INOnAkuF/2/edit

Демонстраційний приклад також має приклад того, як вертикально вирівняти центр по одній техніці.


5

Ось ще одне рішення, що використовує flexbox, але без використання flex-end для вирівнювання низу. Ідея полягає в тому , щоб встановити margin-bottomна h1 в авто , щоб підштовхнути залишився вміст до дна:

#header {
  height: 350px;
  display:flex;
  flex-direction:column;
  border:1px solid;
}

#header h1 {
 margin-bottom:auto;
}
<div id="header">
  <h1>Header title</h1>
  Header content (one or multiple lines) Header content (one or multiple lines)Header content (one or multiple lines) Header content (one or multiple lines)
</div>

Ми також можемо зробити те ж саме з margin-top:autoтекстом, але в цьому випадку нам потрібно загорнути його всередину divабо span:

#header {
  height: 350px;
  display:flex;
  flex-direction:column;
  border:1px solid;
}

#header span {
 margin-top:auto;
}
<div id="header">
  <h1>Header title</h1>
  <span>Header content (one or multiple lines)</span>
</div>


Perfecto! gracias
Грейс Ніколь

4

Для цього вам не потрібен абсолютний + відносний. Це дуже можливо, використовуючи відносне положення і для контейнера, і для даних. Ось як ви це робите.

Припустимо, висота ваших даних буде x. Ваш контейнер відносний, а нижній колонтитул також відносний. Все, що вам потрібно зробити - це додати до своїх даних

bottom: -webkit-calc(-100% + x);

Ваші дані завжди будуть знаходитись у нижній частині контейнера. Працює навіть якщо у вас є контейнер з динамічною висотою.

HTML буде таким

<div class="container">
  <div class="data"></div>
</div>

CSS буде таким

.container{
  height:400px;
  width:600px;
  border:1px solid red;
  margin-top:50px;
  margin-left:50px;
  display:block;
}
.data{
  width:100%;
  height:40px;
  position:relative;
   float:left;
  border:1px solid blue;
  bottom: -webkit-calc(-100% + 40px);
   bottom:calc(-100% + 40px);
}

Живий приклад тут

Сподіваюсь, це допомагає.


Чи можете ви пояснити, що bottom: -webkit-calc(-100% + x);робить?
матч

@mhatch він тримає колонтитул внизу контейнера.
Aditya Ponkshe

4

Ось гнучкий спосіб зробити це. Звичайно, він не підтримується IE8, як користувачеві потрібно було 7 років тому. Залежно від того, що вам потрібно підтримати, деякі з них можна усунути.

І все-таки було б добре, якби був спосіб зробити це без зовнішнього контейнера, просто текст повинен вирівняти себе в межах власного "я".

#header {
    -webkit-box-align: end;
    -webkit-align-items: flex-end;
    -ms-flex-align: end;
    align-items: flex-end;
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    height: 150px;
}

4

Дуже просте однолінійне рішення - додати до діва рядкову висоту, маючи на увазі, що весь текст div буде знижений.

CSS:

#layer{width:198px;
       height:48px;
       line-height:72px;
       border:1px #000 solid}
#layer a{text-decoration:none;}

HTML:

<div id="layer">
    <a href="#">text at div's bottom.</a>
</div>

майте на увазі, що це практичне і швидке рішення, коли ви просто хочете, щоб текст всередині Div знизився, якщо вам потрібно комбінувати зображення та інше, вам доведеться кодувати трохи складніший і чуйніший CSS


3

якщо ви можете встановити висоту обгортаючого вмісту вмісту (# заголовок-вміст, як показано у відповіді інших), замість всього #header, можливо, ви також можете спробувати такий підхід:

HTML

<div id="header">
    <h1>some title</h1>
    <div id="header-content">
        <span>
            first line of header text<br>
            second line of header text<br>
            third, last line of header text
        </span>
    </div>
</div>

CSS

#header-content{
    height:100px;
}

#header-content::before{
  display:inline-block;
  content:'';
  height:100%;
  vertical-align:bottom;
}

#header-content span{
    display:inline-block;
}

показати на кодені



3

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

https://jsfiddle.net/8sfeLmgd/1/

.myContainer {
  display: flex;
  height: 250px;
  flex-flow: column;
}

.filler {
  flex: 1 1;
}
<div class="myContainer">
  <div>Top</div>
  <div class="filler"></div>
  <div>Bottom</div>
</div>

Це реагує, як очікувалося, коли нижній вміст не фіксується за розміром також, коли контейнер не має фіксованого розміру.


3

Я розробив спосіб, який набагато простіше, ніж те, що було сказано.

Встановіть висоту заголовка div. Тоді всередині цього викладіть H1тег так:

float: left;
padding: 90px 10px 11px

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


1
Викличе вміст плавати над іншим вмістом при зміні розміру екранів із використанням чуйних макетів.
Мозфет

2

Я знайшов це рішення, засноване на шаблоні запуску за замовчуванням

/* HTML */

<div class="content_wrapper">
  <div class="content_floating">
    <h2>HIS This is the header<br>
      In Two Rows</h2>
    <p>This is a description at the bottom too</p> 
  </div>
</div>

/* css */

.content_wrapper{
      display: table;
      width: 100%;
      height: 100%; /* For at least Firefox */
      min-height: 100%;
    }

.content_floating{
  display: table-cell;
  vertical-align: bottom;
  padding-bottom:80px;

}

2
#header {
    height: 150px;
    display:flex;
    flex-direction:column;
}

.top{
    flex: 1;
}   

<div id="header">
    <h1 class="top">Header title</h1>
    Header content (one or multiple lines)
</div>

#header {
    height: 250px;
    display:flex;
    flex-direction:column;
    background-color:yellow;
}

.top{
    flex: 1;
}
<div id="header">
    <h1 class="top">Header title</h1>
    Header content (one or multiple lines)
</div>


1
Це призводить до зміни розміру верхнього розділу. Що працює для базових макетів тексту, але не працює, коли речі мають поважати фони та кольори та розміри.
Мозфет

0

спробуйте:

div.myclass { margin-top: 100%; }

спробуйте змінити%, щоб виправити це. Приклад: 120% або 90% ... і т.д.


Відмінно працює з 1 набором вмісту, але його потрібно буде коригувати, якщо зміст змінено. Якщо це динамічний контент, то не використовуйте це!
Майк Граф

0

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

<div id="footer">
  some text here
</div>
#footer {
  padding: 0 30px;
  padding-top: 60px;
  padding-bottom: 8px;
}

1
Ваша перша декларація padding: 0 30pxтрохи зайва, ви також можете поставити padding: 30pxпотім інші 2 декларації.
Андрій

Абсолютно правда, проте я дотримуюся практики мого робочого місця.
Нікі Л. Гансен

6
Дійсно ?, це здається простою поганою практикою. Просто використовуйте скорочення або будьте явні скрізь. padding: 60px 30px 8px;, padding: 60px 30px 8px 30px;Чотири чітких padding-правил, або навіть @ пропозицію TheWaxMann є все вище - і я готовий і в змозі стверджувати , що один ;-)
Zach Lysobey

-3

Мабуть, ідеальний приклад крос-браузера тут:

http://www.csszengarden.com/?cssfile=/213/213.css&page=0

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

Далі йде повністю працюючий мінімальний приклад. Зауважте, що не потрібно вводити хитрощів із вставки. Багато БР просто змушують з'являтися смугу прокрутки:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #floater {
            background: yellow;
            height: 200px;
            width: 100%;
            position: fixed;
            bottom: 0px;
            z-index: 5;
            border-top: 2px solid gold;
        }

    </style>
</head>


<body>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>


    <div id="floater"></div>
</body>
</html>

Якщо вам цікаво, що ваш код може не працювати на IE, не забудьте додати тег DOCTYPE вгорі. Для цього важливо працювати над IE. Також це має бути перший тег, і над ним нічого не повинно з’являтися.


28
Оскільки ви оголошуєте свій документ строгим XHTML, вам слід також самостійно закрити свої <br />теги ...
Amos M. Carpenter

7
@ KarlKildén, якщо ви посилалися на коментар від aaamos, це, безумовно, не дурний коментар - подання вищезазначеного документа з його правильним content-typeзаголовком призведе до того, що браузер видасть помилку аналізу XML.
Бритва

7
Це погана практика! Використовуйте замість CSS!
m93a

-4

Здається, працює:

#content {
    /* or just insert a number with "px" if you're fighting CSS without lesscss.org :) */
    vertical-align: -@header_height + @content_height;

    /* only need it if your content is <div>,
     * if it is inline (e.g., <a>) will work without it */
    display: inline-block;
}

Використання менше робить вирішення головоломок CSS набагато більше схожим на кодування, ніж як ... Я просто люблю CSS. Це справжнє задоволення, коли ти можеш змінити весь макет (не порушуючи його :), просто змінивши один параметр.


-7

Рішення 2015 року

<div style='width:200px; height:60px; border:1px solid red;'>

    <table width=100% height=100% cellspacing=0 cellpadding=0 border=0>
        <tr><td valign=bottom>{$This_text_at_bottom}</td></tr>
    </table>

</div>

http://codepen.io/anon/pen/qERMdx

будь ласка


3
Макет таблиці для цього може бути проблематичним; Натомість рекомендується використовувати CSS. Властивість valign також не підтримується в HTML5. (див. w3schools.com/tags/att_td_valign.asp )
безперечно,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.