Position: Sticky' Not Working When 'Height' Is Defined

position: sticky' not working when 'height' is defined

The issue here is with height, but not the height you thought about. Let's first start by the definition of the sticky position:

A stickily positioned element is an element whose computed position
value is sticky. It's treated as relatively positioned until its
containing block crosses a specified threshold (such as setting top to
value other than auto) within its flow root (or the container it
scrolls within), at which point it is treated as "stuck" until meeting
the opposite edge of its containing block.

The important part here is the last sentence which explain that the position sticky will end when the element reach the edge of its containing block and in your case the containing block of the sticky element is the body and you set the body to be height:100% and you are having an overflow of content.

So when setting the height of main to be 92% and the footer to be 8%, you already made the footer at the oppsite edge of its containing block. Here is an illustration where I added a background color to the body so you can clearly see this:

html,body {  height: 100%;  margin: 0;}html {  background:white;}body {  background:blue;}
#main { height: 92%;}#landing { display: flex; align-items: center; justify-content: center; height: 100%; text-align: center;}#landingContent { width: 20vw;}#footerNav { height: 8%; display: flex; align-items: center; position: sticky; top: 0px; background:red; color:#fff;}
<div id="main">    <div id="landing">        <div id="landingContent">            <h1 class="logo">Logo</h1>            <p id="landingParagraph">Lorem ipsum, paragraph content, etc etc.</p>            <button>Button</button>        </div>    </div></div><div id="footerNav">    <div id="footerNavContent">        <h1 class="logo">Logo</h1>    </div></div><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p><p>Hello</p>

position: sticky breaks for tall content

Position: sticky will only float over child elements and without a parent div it wont float over "content".

You can find a good explanation of how it works from this medium article

Position sticky not taking effect

The sticky element in your fiddle has no height setting - use a set height to avoid that, then the sticky position works:

https://jsfiddle.net/rocz5nL1/

How does the position: sticky; property work?

Sticky positioning is a hybrid of relative and fixed positioning. The element is treated as relative positioned until it crosses a specified threshold, at which point it is treated as fixed positioned.

...

You must specify a threshold with at least one of top, right, bottom, or left for sticky positioning to behave as expected. Otherwise, it will be indistinguishable from relative positioning.
[source: MDN]

So in your example, you have to define the position where it should stick in the end by using the top property.

html, body {
height: 200%;
}

nav {
position: sticky;
position: -webkit-sticky;
top: 0; /* required */
}

.nav-selections {
text-transform: uppercase;
letter-spacing: 5px;
font: 18px "lato", sans-serif;
display: inline-block;
text-decoration: none;
color: white;
padding: 18px;
float: right;
margin-left: 50px;
transition: 1.5s;
}

.nav-selections:hover {
transition: 1.5s;
color: black;
}

ul {
background-color: #B79b58;
overflow: auto;
}

li {
list-style-type: none;
}
<nav>
<ul align="left">
<li><a href="#/contact" class="nav-selections" style="margin-right:35px;">Contact</a></li>
<li><a href="#/about" class="nav-selections">About</a></li>
<li><a href="#/products" class="nav-selections">Products</a></li>
<li><a href="#" class="nav-selections">Home</a></li>
</ul>
</nav>

Why is my css attribute position sticky not working?

So, your code is difficult to debug, because it has been written in a complex way. I provided some guidance on how you can refactor the code, which will make it easier to fix.

First, update your HTML to use classes (where appropriate), so that your CSS rules can reference classes instead of DOM elements. For example, you can update your header to be something like:

...

<div class="header-container">
<h1><a class="logo-link" href="#">Tour</a></h1>
<ul class="nav-menu">
<li><a class="link" href="#">Home</a></li>
<li><a class="link" href="#">About us</a></li>
<li><a class="link" href="#">Social Media</a></li>
<li><a class="link" href="#">Comment</a></li>
<li><a class="link" href="#">Share</a></li>
</ul>
</div>
<div class="explore-btn">Explore</div>

...

Then your CSS becomes something like:

...

.header-container {
padding: 3rem;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 1.6rem;
font-family: 'Roboto', sans-serif;
}

.nav-menu {
display: flex;
margin-top: auto;
}

.link {
padding: 2rem;
font-weight: bold;
color: rgba(1, 1, 1, .9);
}

.link:link {
text-decoration: none;
}

.link:visited {
text-decoration: none;
}

.link:hover {
text-decoration: none;
color: rgba(1, 1, 1, .8);
}

.link:focus {
text-decoration: none;
color: rgba(1, 1, 1, .5);
}

.logo-link {
color: rgba(1, 1, 1, 1);
font-weight: bolder;
font-size: 4rem;
}

.explore-btn {
display: block;
position: absolute;
text-align: left;
bottom: 60vh;
left: 8vw;
}

.explore-btn .hidden {
display: none;
}

...

The following styles should be part of a base set of styles that you define alongside a standard stylesheet reset file:

* {
padding: 0;
margin: 0;
}

html body {
min-height: 100%;
height: 100%;
scroll-behavior: smooth;
}

...

The CSS in that JS file should be converted into utility classes which get toggled on/off using something like:

...

$(window).scroll(function() {
if (window.pageYOffset >= 120) {
$('.explore-btn').addClass('hidden');
} else {
$('.explore-btn').removeClass('hidden');
}
});

Notice that I don't use id selectors. Avoid them if you can, because they make your selectors brittle by being too specific. Also, avoid using HTML elements as selectors (except in your base rules), because you want to avoid your CSS from "bleeding" into other places in unintended ways. Defining specific classes on elements (that you intend to style) is a good way of managing scope.

If I see a style defined in your HTML, I know that it exists somewhere in your CSS. It should be a flat selector (if possible). Keep it simple. The only nested selector I use is the one where explore-btn toggles between hidden and visible. This is a good system.

If you find yourself repeating the same styles across multiple classes, then that's a sign that you should refactor it. Similarly, if you find yourself nesting selectors too deeply (e.g. nav ul li a), you probably want to define a special class for that element (e.g. .link). There's always exceptions, but you should aim for the simplest approach first.

Once you're done refactoring the code then save your code here: https://jsfiddle.net/ and ping me with a link. I can take another look.

UPDATE:

So, you can find an example of a sticky header here: https://jsfiddle.net/yj49tn6r/

Using your refactored code, all I needed to do was define a JQuery method that toggled the sticky class on the header-container:

 $(window).scroll(function () {
if (window.pageYOffset >= 120) {
$(".header-container").addClass("sticky");
} else {
$(".header-container").removeClass("sticky");
}
});

Then define the utility class itself:

.sticky {
position: fixed;
top: 0;
width: 100%
}

Why position sticky is not working in my code?

Its because you have overflow-x-hidden in parent . sticky doesn't work if parent overflow is hidden.

{!categorySearch && (
<div className="max-w-2xl mx-auto z-40 relative font-metropolis_semibold">
<div className="sticky top-0">
<div className=" z-40 bg-white w-full transition-all">
<div
id="logo"
className={
logo
? "px-md mt-10 font-medium"
: "px-md mt-10 font-medium animate"
}
>
<div className="overflow-x-hidden ">
<img
src={settings.logo_intro_image_url}
alt={settings.name}
className="max-w-full object-contain company-logo"
style={{ height: settings.logo_height }}
id="company-logo"
/>
</div>
</div>
<div
className={`${
logo
? "shadow-none border-none"
: "border-b-2 border-gray-200"
}`}
>
<TopOptions
showOption={showOption}
setShowOption={setShowOption}
addBorder={logo}
outlets={outlets}
languageLabels={languageLabels}
settings={selectedOutlet.settings}
/>
</div>
</div>
{Object.keys(bannerArray).length === 1 ? (
<div className="w-full px-md border-b-8 border-banner pb-md">
{bannerArray &&
bannerArray.map((banner, index) => {
return (
<>
<PosterSlider
key={index}
image={banner.image}
loadingBanners={loadingBanners}
isSingle={Object.keys(bannerArray).length === 1}
/>
</>
);
})}
</div>
) : (
<div className="max-h-full h-19.7 hide-scroll px-md flex overflow-x-auto gap-5p border-b-8 border-light-bg-gray">
{bannerArray &&
bannerArray.map((banner, index) => {
return (
<PosterSlider
key={index}
image={banner.image}
loadingBanners={loadingBanners}
isSingle={Object.keys(bannerArray).length === 1}
/>
);
})}
</div>
)}
<div className="flex flex-row justify-between items-center px-md my-25p">
<p className="font-metropolis_regular text-sm break-words">
{languageLabels.like_to_order}
</p>
<img
src={Search}
alt="search"
onClick={() => setCategorySearch(true)}
/>
</div>
<div className="grid grid-flow-row w-full grid-cols-2 place-items-center gap-10p px-md pb-20">
{categoryList.map((category) => {
// console.log(category);
return (
<Dishes
key={category.category_id}
category={category}
languageLabels={languageLabels}
loading={loadingCategories}
/>
);
})}
</div>
<BottomNavigation
languageLabels={languageLabels}
isLoyalty={settings.enable_reward_points_functionality}
/>
</div>
</div>
)}

CSS position sticky doesn't work properly when element is inside another

if your aside will always have a fixed height use negative top value and make the parent container sticky: