Issue
I'm looking to create a position:sticky sidebar that has a header and footer, always visible and the middle content of the sidebar is scrolled. The page will have a variable height overall header.
I plan on using the Bootstrap 5 grid to setup the structure of the page.
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/css/bootstrap.min.css">
<style>
body {
background-color: #f1f1f1;
margin: 15px 0;
}
header {
margin-bottom: 15px;
}
.block {
background-color: #fff;
border: 1px solid #ccc;
padding: 15px;
}
.sidebar .block {
width: 100%;
max-height: 100vh;
height: calc(100vh - 295px);
min-height: calc(100vh - 295px);
overflow-y: auto;
}
.sticky {
position: sticky;
top: 15px;
}
.header,
.footer {
height: 50px;
text-align: center;
color: #fff;
background-color: #000;
}
</style>
</head>
<body>
<div class="container-fluid">
<header>
<div class="block">
hi, my height can change.
</div><!--/.block -->
</header>
<div class="row">
<div class="col-sm-9">
<div class="block">
dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />
</div><!--/.block -->
</div><!--/.col -->
<div class="col-sm-3">
<div class="sticky sidebar">
<div class="header">HEADER</div>
<div class="block">
1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40
</div><!--/.block -->
<div class="footer">FOOTER</div>
</div><!--/.wrapper -->
</div><!--/.col -->
</div><!--/.row -->
</div><!--/.container-fluid -->
</body>
</html>
https://jsfiddle.net/y9ufqmjw/
See screenshot below at my first stab at it. When you are at the top I want the sidebar to fill the entire content area, regardless the size of the sidebar and the content area in the middle to scroll: Preview of sidebar top of page
When you scroll on the page I want the sidebar to fill in entire column height (as the header scrolls off, the sidebar should fill the entire column. Preview of sidebar bottom of the page
Solution
You can achieve this with jQuery.
See the snippet below.
$.fn.isInViewport = function() {
var elementTop = $(this).offset().top;
var elementBottom = elementTop + $(this).outerHeight();
var viewportTop = $(window).scrollTop();
var viewportBottom = viewportTop + $(window).height();
return elementBottom > viewportTop && elementTop < viewportBottom;
};
$(document).ready(function() {
$(window).on('resize scroll', function() {
if ($('header').isInViewport()) {
$('.sidebar .block').css('height', 'calc(100vh - 180px)');
} else {
$('.sidebar .block').css('height', 'calc(100vh - 130px)');
}
});
});
body {
background-color: #f1f1f1;
margin: 15px 0;
}
header {
margin-bottom: 15px;
}
.block {
background-color: #fff;
border: 1px solid #ccc;
padding: 15px;
}
.sidebar .block {
width: 100%;
max-height: 100vh;
height: calc(100vh - 180px);
min-height: calc(100vh - 195px);
overflow-y: auto;
transition: all 0.2s ease-in-out;
}
.sticky {
position: sticky;
top: 15px;
}
.header,
.footer {
height: 50px;
text-align: center;
color: #fff;
background-color: #000;
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js" integrity="sha512-aVKKRRi/Q/YV+4mjoKBsE4x3H+BkegoM/em46NNlCqNTmUYADjBbeNefNxYV7giUp0VxICtqdrbqU7iVaeZNXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body>
<div class="container-fluid">
<header>
<div class="block">
hi, my height can change.
</div>
<!--/.block -->
</header>
<div class="row">
<div class="col-sm-9">
<div class="block">
dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br
/>dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br
/>dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br
/>dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br
/>dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br />dd<br
/>dd<br />dd<br />dd<br />dd<br />
</div>
<!--/.block -->
</div>
<!--/.col -->
<div class="col-sm-3">
<div class="sticky sidebar">
<div class="header">HEADER</div>
<div class="block">
1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40
</div>
<!--/.block -->
<div class="footer">FOOTER</div>
</div>
<!--/.wrapper -->
</div>
<!--/.col -->
</div>
<!--/.row -->
</div>
<!--/.container-fluid -->
</body>
</html>
Answered By - Cervus camelopardalis
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.