Для чистого решения CSS прокрутите после 2-го <hr>
. Первый - первоначальный ответ (дан еще в 2016 году)
Главный недостаток вышеупомянутых решений - фиксированная высота нижнего колонтитула.
И это просто не врезается в реальный мир, где люди используют миллионы устройств и имеют плохую привычку вращать их, когда вы меньше всего этого ожидаете, и ** Poof! ** там идет содержание вашей страницы за нижний колонтитул!
В реальном мире вам нужна функция, которая вычисляет высоту нижнего колонтитула и динамически корректирует содержимое страницы padding-bottom
в соответствии с этой высотой. И вам нужно запустить эту крошечную функцию для страницы load
и resize
событий, а также для нижнего колонтитула DOMSubtreeModified
(на случай, если ваш нижний колонтитул динамически обновляется асинхронно или содержит анимированные элементы, которые изменяют размер при взаимодействии с ним).
Вот подтверждение концепции с использованием jQuery v3.0.0
и Bootstrap v4-alpha
, но нет причины, по которой он не должен работать на более низких версиях каждой из них.
jQuery(document).ready(function($) {
$.fn.accomodateFooter = function() {
var footerHeight = $('footer').outerHeight();
$(this).css({
'padding-bottom': footerHeight + 'px'
});
}
$('footer').on('DOMSubtreeModified', function() {
$('body').accomodateFooter();
})
$(window).on('resize', function() {
$('body').accomodateFooter();
})
$('body').accomodateFooter();
window.addMoreContentToFooter = function() {
var f = $('footer');
f.append($('<p />', {
text: "Human give me attention meow flop over sun bathe licks your face wake up wander around the house making large amounts of noise jump on top of your human's bed and fall asleep again. Throwup on your pillow sun bathe. The dog smells bad jump around on couch, meow constantly until given food, so nap all day, yet hiss at vacuum cleaner."
}))
.append($('<hr />'));
}
});
body {
min-height: 100vh;
position: relative;
}
footer {
background-color: rgba(0, 0, 0, .65);
color: white;
position: absolute;
bottom: 0;
width: 100%;
padding: 1.5rem;
display: block;
}
footer hr {
border-top: 1px solid rgba(0, 0, 0, .42);
border-bottom: 1px solid rgba(255, 255, 255, .21);
}
<link href="http://v4-alpha.getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="http://v4-alpha.getbootstrap.com/examples/starter-template/starter-template.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.2.0/js/tether.min.js"></script>
<script src="http://v4-alpha.getbootstrap.com/dist/js/bootstrap.min.js"></script>
<nav class="navbar navbar-toggleable-md navbar-inverse bg-inverse fixed-top">
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">Navbar</a>
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#">Disabled</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="http://example.com" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu" aria-labelledby="dropdown01">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="text" placeholder="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
<div class="container">
<div class="starter-template">
<h1>Feed that footer - not a game (yet!)</h1>
<p class="lead">You will notice the body bottom padding is growing to accomodate the height of the footer as you feed it (so the page contents do not get covered by it).</p><button class="btn btn-warning" onclick="window.addMoreContentToFooter()">Feed that footer</button>
<hr />
<blockquote class="lead"><strong>Note:</strong> I used jQuery <code>v3.0.0</code> and Bootstrap <code>v4-alpha</code> but there is no reason why it shouldn't work with lower versions of each.</blockquote>
</div>
</div>
<footer>I am a footer with dynamic content.
<hr />
</footer>
Изначально я разместил это решение здесь, но понял, что оно может помочь большему количеству людей, если оно будет опубликовано под этим вопросом.
Примечание: я намеренно обернул его $([selector]).accomodateFooter()
как плагин jQuery, чтобы его можно было запускать на любом элементе DOM, так как в большинстве макетов это не тот $('body')
, bottom-padding
который нуждается в настройке, а какой-то элемент обертки страницы с position:relative
(обычно непосредственным родителем footer
) ,
Позднее редактирование (3+ года после первоначального ответа):
На данный момент я больше не считаю приемлемым использование JavaScript для размещения динамического нижнего колонтитула в нижней части страницы. Это может быть достигнуто только с помощью CSS, используя flexbox, молниеносно, кросс-браузер.
Вот:
// Left this in so you could inject content into the footer and test it:
// (but it's no longer sizing the footer)
function addMoreContentToFooter() {
var f = $('footer');
f.append($('<p />', {
text: "Human give me attention meow flop over sun bathe licks your face wake up wander around the house making large amounts of noise jump on top of your human's bed and fall asleep again. Throwup on your pillow sun bathe. The dog smells bad jump around on couch, meow constantly until given food, so nap all day, yet hiss at vacuum cleaner."
}))
.append($('<hr />'));
}
.wrapper {
min-height: 100vh;
padding-top: 54px;
display: flex;
flex-direction: column;
}
.wrapper>* {
flex-grow: 0;
}
.wrapper>main {
flex-grow: 1;
}
footer {
background-color: rgba(0, 0, 0, .65);
color: white;
width: 100%;
padding: 1.5rem;
}
footer hr {
border-top: 1px solid rgba(0, 0, 0, .42);
border-bottom: 1px solid rgba(255, 255, 255, .21);
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<div class="wrapper">
<nav class="navbar navbar-expand-lg navbar-light bg-light fixed-top">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
<main>
<div class="container">
<div class="starter-template">
<h1>Feed that footer - not a game (yet!)</h1>
<p class="lead">Footer won't ever cover the body contents, as its not fixed. It's simply placed at the bottom when the page should be shorter using `min-height:100vh` on container and using flexbox to push it down.</p><button class="btn btn-warning" onclick="addMoreContentToFooter()">Feed that footer</button>
<hr />
<blockquote class="lead">
<strong>Note:</strong> This example uses current latest versions of jQuery (<code>3.4.1.slim</code>) and Bootstrap (<code>4.4.1</code>) (unlike the one above).
</blockquote>
</div>
</div>
</main>
<footer>I am a footer with dynamic content.
<hr />
</footer>
</div>