Можно ли блок со свойством position: sticky; растянуть до нижнего края окна?
Суть проблемы такая: нужно растянуть блок sticky-block со свойством position: sticky; до нижнего края области просмотра окна браузера, так что бы его нижняя граница при смещении верхней границы оставалась фиксированной по нижнему краю отображаемого окна (блок все время должен быть виден целиком и увеличиться на смещаемую разницу). Не могу сообразить как это сделать. Что то мне подсказывает, что это невозможно. Может быть есть возможность реализовать данную задумку без position: sticky;?
В примере блоку задана высота 50% рандомно.
*,*:before,*:after {
padding: 0;
margin: 0;
border: 0;
box-sizing: border-box;
}
h1 {font-size: 36px; margin: 0;}
.top-block {
box-sizing: border-box;
height: 3em;
border-bottom: 0.05em solid white;
background-color: blue;
position: fixed;
top: 0;
width: 100%;
z-index: 100;
}
.underheader {
position: relative;
height: 3em;
}
.wrapper {
display: flex;
width: auto;
margin: 0 auto;
}
.sidebar {
width: 20%;
background-color: #e4e4e4;
padding: 0.5em;
}
.main-section {
width: 80%;
background-color: #e4e4e4;
padding: 0;
margin: 0;
}
.headpost {
position: relative;
height: 7em;
background-color: yellow;
}
.post {
position: relative;
height: 30em;
background-color: green;
}
.bw {
background-color: red;
}
.aside-menu {
background-color: silver;
position: sticky;
top: 3.5em;
border-radius: 0.5em;
border: 0.2em solid white;
overflow: hidden;
height: 50%;
}
<body>
<header class="head">
<div class="top-block"></div>
<div class="underheader"></div>
</header>
<main>
<header>
<div class="headpost">
<h1>шапка</h1>
</div>
</header>
<section class="wrapper">
<aside class="sidebar">
<nav class="aside-menu">
<div class="sticky-block">
<h1>sticky</h1>
</div>
</nav>
</aside>
<section class="main-section">
<article class="post bw article" id="anchor-scrl-1-diseases">
<h1>первый</h1>
</article>
<article class="post article" id="anchor-scrl-2-diseases">
<h1>второй</h1>
</article>
<article class="post bw article" id="anchor-scrl-3-diseases">
<h1>третий</h1>
</article>
</section>
</section>
</main>
</body>
Ответы (4 шт):
как то так. попытался написать код на jquery, но он не рабочий...
(function($) {
$(document).ready(() => {
let sticky = $('.sticky-block'),
headfixed = $('.top-block'),
headpost = $('.headpost'),
activeSticky = $('.active-sticky-block');
$(window).on('scroll', function () {
sticky.height($(window).height() - headfixed.outerHeight() - headpost.outerHeight(););
activeSticky.height($(window).height() - headfixed.outerHeight(););
const position = $(this).scrollTop();
sticky(function () {
const top = $(this).offset().top + headfixed.outerHeight() + headpost.outerHeight();
if (position <= top) {
sticky.removeClass('active-sticky-block');
}
else if (position > top) {
sticky.addClass('active-sticky-block');
}
});
});
});
})(jQuery);
*,*:before,*:after {
padding: 0;
margin: 0;
border: 0;
box-sizing: border-box;
}
h1 {font-size: 36px; margin: 0;}
.top-block {
box-sizing: border-box;
height: 3em;
border-bottom: 0.05em solid white;
background-color: blue;
position: fixed;
top: 0;
width: 100%;
z-index: 100;
}
.underheader {
position: relative;
height: 3em;
}
.wrapper {
display: flex;
width: auto;
margin: 0 auto;
}
.sidebar {
width: 20%;
background-color: #e4e4e4;
padding: 0.5em;
}
.main-section {
width: 80%;
background-color: #e4e4e4;
padding: 0;
margin: 0;
}
.headpost {
position: relative;
height: 7em;
background-color: yellow;
}
.post {
position: relative;
height: 30em;
background-color: green;
}
.bw {
background-color: red;
}
.sticky-block {
background-color: silver;
position: sticky;
top: 3.5em;
border-radius: 0.5em;
border: 0.2em solid white;
overflow: hidden;
height: 10%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<header class="head">
<div class="top-block"></div>
<div class="underheader"></div>
</header>
<main>
<header>
<div class="headpost">
<h1>шапка</h1>
</div>
</header>
<section class="wrapper">
<aside class="sidebar">
<div class="sticky-block">
<h1>sticky</h1>
</div>
</aside>
<section class="main-section">
<article class="post bw article" id="anchor-scrl-1-diseases">
<h1>первый</h1>
</article>
<article class="post article" id="anchor-scrl-2-diseases">
<h1>второй</h1>
</article>
<article class="post bw article" id="anchor-scrl-3-diseases">
<h1>третий</h1>
</article>
</section>
</section>
</main>
</body>
Такой вариант нужен?
*,*:before,*:after {
padding: 0;
margin: 0;
border: 0;
box-sizing: border-box;
}
h1 {font-size: 36px; margin: 0;}
.top-block {
box-sizing: border-box;
height: 3em;
border-bottom: 0.05em solid white;
background-color: blue;
position: fixed;
top: 0;
width: 100%;
z-index: 100;
}
.underheader {
position: relative;
height: 3em;
}
.wrapper {
display: flex;
width: auto;
margin: 0 auto;
}
.sidebar {
width: 20%;
background-color: #e4e4e4;
padding: 0.5em;
}
.main-section {
width: 80%;
background-color: #e4e4e4;
padding: 0;
margin: 0;
}
.headpost {
position: relative;
height: 7em;
background-color: yellow;
}
.post {
position: relative;
height: 30em;
background-color: green;
}
.bw {
background-color: red;
}
.aside-menu {
background-color: silver;
position: sticky;
top: 3.5em;
border-radius: 0.5em;
border: 0.2em solid white;
overflow: hidden;
height: 50%;
max-height: calc(100vh - (48px + 20px));
}
<body>
<header class="head">
<div class="top-block"></div>
<div class="underheader"></div>
</header>
<main>
<header>
<div class="headpost">
<h1>шапка</h1>
</div>
</header>
<section class="wrapper">
<aside class="sidebar">
<nav class="aside-menu">
<div class="sticky-block">
<h1>sticky</h1>
</div>
</nav>
</aside>
<section class="main-section">
<article class="post bw article" id="anchor-scrl-1-diseases">
<h1>первый</h1>
</article>
<article class="post article" id="anchor-scrl-2-diseases">
<h1>второй</h1>
</article>
<article class="post bw article" id="anchor-scrl-3-diseases">
<h1>третий</h1>
</article>
</section>
</section>
</main>
</body>
Всем огромное спасибо за проявленный интерес и помощь в решении данной задачи. С помощью Ваших подсказок сейчас могу написать то, чего хочу добиться. Данный вариант корявый, блок плавно смещается не синхронно скролу, а по времени. По-другому самостоятельно написать код пока не могу. Помогите в написании кода для синхронного со скролом смещением блока. Страница с прелоадером и отображается только после загрузки скриптов, так что багов с преждевременным скролом быть не должно
$(window).scroll(function(){
if ($(this).scrollTop() > 108) {
$('.sticky-block').addClass('fixed');
}
else {
$('.sticky-block').removeClass('fixed');
}
});
*,*:before,*:after {
padding: 0;
margin: 0;
border: 0;
box-sizing: border-box;
}
h1 {font-size: 36px; margin: 0;}
.top-block {
box-sizing: border-box;
height: 3em;
border-bottom: 0.05em solid white;
background-color: blue;
position: fixed;
top: 0;
width: 100%;
z-index: 100;
}
.underheader {
position: relative;
height: 3em;
}
.wrapper {
display: flex;
width: auto;
margin: 0 auto;
}
.sidebar {
width: 20%;
background-color: #e4e4e4;
padding: 0.5em;
}
.main-section {
width: 80%;
background-color: #e4e4e4;
padding: 0;
margin: 0;
}
.headpost {
position: relative;
height: 7em;
background-color: yellow;
}
.post {
position: relative;
height: 30em;
background-color: green;
}
.bw {
background-color: red;
}
.sticky-block {
background-color: silver;
position: sticky;
top: 3.5em;
border-radius: 0.5em;
border: 0.2em solid white;
overflow: hidden;
height: 50%;
max-height: calc(100vh - 11em);
transition: .5s ease-in-out;
}
.sticky-block.fixed {
max-height: calc(100vh - 4em);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<header class="head">
<div class="top-block"></div>
<div class="underheader"></div>
</header>
<main>
<header>
<div class="headpost">
<h1>шапка</h1>
</div>
</header>
<section class="wrapper">
<aside class="sidebar">
<div class="sticky-block">
<h1>sticky</h1>
</div>
</aside>
<section class="main-section">
<article class="post bw article" id="anchor-scrl-1-diseases">
<h1>первый</h1>
</article>
<article class="post article" id="anchor-scrl-2-diseases">
<h1>второй</h1>
</article>
<article class="post bw article" id="anchor-scrl-3-diseases">
<h1>третий</h1>
</article>
</section>
</section>
</main>
</body>
Вот просто идея с requestAnimationFrame. Эта функция тоже асинхронная, но позволяет избежать потери кадров и повысить эффективность перерисовки.
var head = window.document.getElementById('head');
var side = window.document.getElementById('side');
window.requestAnimationFrame(function step() {
var offset = Math.max(0, head.offsetHeight - window.pageYOffset);
side.style.minHeight = 'calc(100vh - ' + offset + 'px)';
window.requestAnimationFrame(step);
});
html, body {
margin: 0; padding: 0;
}
* {
box-sizing: border-box;
}
#head {
padding: 20px;
border-radius: 20px;
min-height: 100px;
background-color: yellow;
}
#side {
position: sticky;
top: 0;
float: left;
width: 200px;
padding: 20px;
border-radius: 20px;
background-color: green;
}
#main {
margin-left: 200px;
height: 3000px;
padding: 20px;
border-radius: 20px;
background-color: red;
}
<div id="head">head</div>
<div id="side">side</div>
<div id="main">main</div>