Как выровнять содержимое div снизу


1165

Скажем, у меня есть следующий код CSS и HTML:

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

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

Я бы хотел, чтобы содержимое заголовка было выровнено по вертикали к нижней части раздела заголовка, поэтому последняя строка текста «прилипает» к нижней части раздела заголовка.

Так что, если есть только одна строка текста, это будет выглядеть так:

-----------------------------
| Заголовок заголовка
|
|
|
| содержимое заголовка (в результате в одну строку)
-----------------------------

И если бы было три строки:

-----------------------------
| Заголовок заголовка
|
| содержимое заголовка (что так
| много чего идеально
| охватывает три строки)
-----------------------------

Как это можно сделать в CSS?

Ответы:


1324

Относительное + абсолютное позиционирование - ваша лучшая ставка:

#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
Я действительно нашел это решение, прежде чем спрашивать здесь, но почему-то забыл добавить позицию: относительный; до заголовка div, и контент продолжал приземляться внизу страницы. Спасибо
Кристоф

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

1
В случае текстового содержимого, как описано в исходной задаче, # header-content действительно должен быть pэлементом или, по крайней мере,span
Josh Burgess

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
к вашему сведению ... это привело к тому, что содержимое моего заголовка сократилось по ширине, поэтому мне пришлось добавить width = '100%'к содержимому заголовка
dsdsdsdsd

2
@dsdsdsdsd Вы также можете это исправить, добавив display: block к # header-content.
Патрик МакЭлхани

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

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

Не работает, когда содержимое снизу имеет переменную высоту, заставляет его выходить за пределы контейнера.
Мозфет

126

Если вы не беспокоитесь о старых браузерах, используйте flexbox.

Родительскому элементу необходимо установить тип отображения для flex

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

Затем вы устанавливаете дочерний элемент align-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» вместо align-items (моя ошибка, я отредактировал свой оригинальный пост). 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.
Зак Лисобей

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

Этот трюк работает, создавая высокий, тощий div, который выдвигает базовую линию текста к нижней части контейнера.

Вот полный пример, который достигает того, о чем просил ОП. Я сделал "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

Я думаю, что марин: 8px должно быть наценкой: 8px
Грэм Перрин

2
Это также работает, если поместить в ::beforeправило, которое устраняет необходимость в дополнительном элементе. Мы использовали flex в конце, но это полезно, когда вы не можете.
Sheepy

Это действительно хорошее решение. Это работает только в том случае, если heightдля поля / контейнера и его родительских элементов установлено значение (px,% или что-либо еще).
BairDev

38

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

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;. Это решение отлично сработало для моего случая!
Свен

1
Внутри реагируют компоненты, это правильное решение. Принятое решение не удается.
Солей - Матье Прево

1
Это единственное решение, которое действительно работает для меня. Возможно, это связано с React, как упомянул @Soleil ... Я не эксперт по CSS, поэтому я не совсем уверен.
БК

Отлично работает в компоненте реакции
user1155773

25

Элементы inline или inline-block могут быть выровнены по низу элементов уровня блока, если высота строки родительского / блочного элемента больше, чем у встроенного элемента. *

разметка:

<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
Обратите внимание, что flexbox не очень хорошо поддерживается в старых браузерах.
AnthonyB

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

3
@ Тиш, ты абсолютно прав, мы, как разработчики, должны использовать приличные и современные технологии. Но я бы просто предупредил об этой проблеме совместимости, чтобы не удивляться.
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 значение auto, чтобы перенести оставшийся контент вниз:

#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! Грасиас
Грейс Николь

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

@Match, он держит нижний колонтитул в нижней части контейнера.
Адитья Понкше

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, имея в виду, что весь текст 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

если бы вы могли установить высоту оберточного div содержимого (# header-content, как показано в ответе другого), вместо всего #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

Кажется, работает:

HTML: я внизу

CSS:

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

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

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


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
Это вызывает изменение размера верхнего div. Который работает для основных макетов текста, но не работает, когда вещи имеют фоны, цвета и размеры, чтобы уважать.
Мозфет

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 все превосходят - и я хочу и могу это утверждать ;-)
Зак Лисобей

-3

Идеальный кросс-браузерный пример, вероятно, вот этот:

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

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

Ниже приведен полностью рабочий минимальный пример. Обратите внимание, что не требуется хитрость для вложения div. Многие BR просто заставляют появиться полосу прокрутки:

<!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 />теги ...
Амос М. Карпентер,

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 )
undeniablyrob
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.