Reputation: 1396
Here is my Html. I want to fix my nav item on top on scrolling using html and css I tried a lot of things but I was not able to fix it. How can I build it without JavaScript or jQuery?
<div class="contain">
<p>
Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones
no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae
gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec
et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.
</p>
</div>
<nav>
<div class="navWide">
<div class="wideDiv">
<a href="#">Link 1</a>
<a href="#">Link 2</a>
<a href="#">Link 3</a>
</div>
</div>
<div class="navNarrow">
<i class="fa fa-bars fa-2x"></i>
<div class="narrowLinks hidden">
<a href="#">Link 1</a>
<a href="#">Link 2</a>
<a href="#">Link 3</a>
</div>
</div>
</nav>
<div class="contain">
<p>
Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones
no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae
gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec
et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.
</p>
</div>
My custom CSS using this. How can I fix my problem? It will be really helpful for me and others too why I want to complete this using CSS. I am making a small component using html and CSS, this is one more component and I got stuck here.
.contain{
height:100vh;
backgroud:#ccc;
}
nav {
background-color: #CCC;
overflow: hidden;
padding: 1em;
border-bottom: 1px solid #000;
}
nav a {
color: #000;
}
nav a:visited {
color: #000;
}
nav .navWide {
display: none;
margin: 0 auto;
}
nav .navWide .wideDiv {
text-align: center;
}
nav .navWide .wideDiv a {
text-decoration: none;
display: inline-block;
padding: 0 2em;
}
nav .navNarrow i {
float: left;
cursor: pointer;
color: #000;
}
nav .navNarrow .narrowLinks a {
text-decoration: none;
display: block;
float: left;
clear: left;
padding: 0.5em 0;
}
.hidden {
display: none;
}
/*Adjust breakpoint as desired to select when the "hamburger" menu is
replaced by just the links.*/
@media (min-width: 480px) {
nav .navWide {
display: block;
}
nav .navNarrow {
display: none;
}
}
Upvotes: 5
Views: 14995
Reputation: 76
You could use position: sticky;
on your nav, but note that it will not be supported on all browsers (for example IE 11). Here is the compatibility chart if you wanna take a look: https://caniuse.com/#feat=css-sticky
A safer fix is to set position: fixed;
to you nav, and give your content some top padding.
So your css will be as follows:
body {
margin: 0;
}
.contain{
height:100vh;
background:#ccc;
padding-top: 50px;
}
nav {
background-color: #CCC;
overflow: hidden;
padding: 1em;
border-bottom: 1px solid #000;
position: fixed;
top: 0px;
display: block;
width: 100%;
}
nav a {
color: #000;
}
nav a:visited {
color: #000;
}
nav .navWide {
display: none;
margin: 0 auto;
}
nav .navWide .wideDiv {
text-align: center;
}
nav .navWide .wideDiv a {
text-decoration: none;
display: inline-block;
padding: 0 2em;
}
nav .navNarrow i {
float: left;
cursor: pointer;
color: #000;
}
nav .navNarrow .narrowLinks a {
text-decoration: none;
display: block;
float: left;
clear: left;
padding: 0.5em 0;
}
.hidden {
display: none;
}
/*Adjust breakpoint as desired to select when the "hamburger" menu is
replaced by just the links.*/
@media (min-width: 480px) {
nav .navWide {
display: block;
}
nav .navNarrow {
display: none;
}
}
Upvotes: 4
Reputation: 853
As stated, the way to go is:
body {
height: 100vh;
overflow-y: auto
}
.nav {
position: sticky;
top: 20px;
}
As for 'not working in all browsers' that's a whole different story. If you really want to go through that, here's a good starting point:
You could use an onscroll eventListener to check the position of the nav, in relation to the screen, with getBoundingClientRect() - but it is much more expensive than the sticky implementation.
.makeItFixed {
position: fixed;
top: 0; left: 0;
};
var nav = document.getElementsByTgName('nav')[0];
window.addEventListener('scroll', function(){
if (nav.getBoundingClientRect().top <= 0) {
nav.classList.add('makeItFixed');
} else {
nav.classList.remove('makeItFixed');
}
});
This could use some proper optimization, including a debouncing interval, and eventually moving the getBoundingClientRect() outside of the check - it is an expensive operation as it causes a page reflow/layout with every call.
In the future, the intersectionObserver API will take over, but as you wanted it to work in 'all' browsers, this is out of the question.
Upvotes: 0
Reputation: 1875
You can actually use a simple
position: sticky;
top: 0;
Sticky behavior will apply once nav bar hits top position 0.
.contain{
height:100vh;
backgroud:#ccc;
}
nav {
background-color: #CCC;
overflow: hidden;
padding: 1em;
border-bottom: 1px solid #000;
position: sticky;
top: 0;
}
nav a {
color: #000;
}
nav a:visited {
color: #000;
}
nav .navWide {
display: none;
margin: 0 auto;
}
nav .navWide .wideDiv {
text-align: center;
}
nav .navWide .wideDiv a {
text-decoration: none;
display: inline-block;
padding: 0 2em;
}
nav .navNarrow i {
float: left;
cursor: pointer;
color: #000;
}
nav .navNarrow .narrowLinks a {
text-decoration: none;
display: block;
float: left;
clear: left;
padding: 0.5em 0;
}
.hidden {
display: none;
}
/*Adjust breakpoint as desired to select when the "hamburger" menu is
replaced by just the links.*/
@media (min-width: 480px) {
nav .navWide {
display: block;
}
nav .navNarrow {
display: none;
}
}
<div class="contain">
<p>
Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones
no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae
gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec
et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.
</p>
</div>
<nav>
<div class="navWide">
<div class="wideDiv">
<a href="#">Link 1</a>
<a href="#">Link 2</a>
<a href="#">Link 3</a>
</div>
</div>
<div class="navNarrow">
<i class="fa fa-bars fa-2x"></i>
<div class="narrowLinks hidden">
<a href="#">Link 1</a>
<a href="#">Link 2</a>
<a href="#">Link 3</a>
</div>
</div>
</nav>
<div class="contain">
<p>
Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones
no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae
gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec
et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.
</p>
</div>
Upvotes: 1