I have followed this tutorial on W3schools to create a fixed header on scroll. So the navbar starts at the bottom of the page, and upon scrolling once the navbar reaches the top of the page, it sticks there.
W3Schools How to Create a Fixed Header on scroll
I successfully implemented these instructions from W3schools with the Materialize side navigation menu, meant to be used with the Materialize Scrollspy effect. It is working great so far except for two issues I can't seem to figure out.
Once the navigation menu reaches the top of the screen and it transitions to being sticky, there is a very small jump in it's position. I have altered some settings, but I can't seem to stop that jump. Why is it happening and how can I make it appear smooth?
When I use Scrollspy to scroll to a different section of the site, and then refresh the page, the side navigation menu disappears until I start scrolling the page again. I am using window.onscroll, so I am guessing that is why it's happening. But I notice it does not happen with the W3Schools example, so I'm wondering if I have something set up wrong?
Here is a link to my portfolio website where I'm having these issues:
My portfolio website.
Here is the code:
// execute navFunction on scroll
window.onscroll = function(){navFunction()};
// get navbar
const navBar = document.getElementById("contents-wrapper");
// get offset position of navbar
const sticky = navBar.offsetTop;
// reach scroll position - add sticky, leave scroll position - remove sticky
function navFunction() {
if (window.pageYOffset >= sticky) {
navBar.classList.add("sticky")
} else {
navBar.classList.remove("sticky");
}
}
#contents-wrapper {
overflow: hidden;
float: right;
}
.sticky {
position: fixed;
top: 0;
left: 77.5%;
width: 100%;
}
.sticky + .content {
padding-top: 60px;
}
<!--Parallax-->
<div class="parallax-container z-depth-1 hide-on-small-only" style="height: 650px">
<div class="parallax"><img src="assets/images/flower.jpg"></div>
<div class="overlay1">I'm Jennifer Faye</div>
<div class="overlay2">A full stack web developer with an eye for design.</div>
</div>
<div id="pic-section">
<div class="container">
<div class="row">
<div class="col s12 m4 l2">
<img id="jen" class="z-depth-1 circle" src="assets/images/Jen.jpg">
</div>
<div class="col s12 m4 l8">
<p id="blurb">I am passionate about developing well designed websites; both aesthetically,
and with attention to user experience and mobile responsiveness.
</p>
</div>
<div class="col s12 m4 l2">
<!--table of contents pinned navigation-->
<div id="contents-wrapper">
<div class="col hide-on-small-only m3 l2">
<ul class="section table-of-contents">
<li>Home</li>
<li>About</li>
<li>Projects</li>
<li>Skills</li>
<li>Contact</li>
<li><a href="https://docs.google.com/document/d/1s9vhyk3Z4IUGwLp1fxUAPLAbVsfRia0cHx67qVqZRKE/edit?usp=sharing"
target="_blank">Resume</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
I solved the problem of the little jump. I had float it to the left instead of to the right, then I made the grid l1 instead of l2. Works perfectly now. I'm still trying to figure out the other issue though.
Adding this seems to have solved my second issue:
$(document).ready(function(){
$(this).scrollTop(0);
});
Related
At the moment the div(.name) that I would like to be in position:fixed is perambulating all over my page and divs everywhere. I don't want to put a background and z-index to all divs in the page, just not to see the fixed one, which should be limited only at its row - the header one; at some places I have a space between two rows so even if I put z-index and position: relative(playing with max-height as well, without any success), I see the fixed div between the rows. So what can I do so the fixed one to be scrolled only inside of its row - header and to disappear when the header disappear from the viewport. Thank you guys in advance!
.name {
margin - top: 5 %;
position: fixed;
}
<div class="row header">
<div class="col-xl cover">
<div class="row justify-content-md-center">
<div class="col col-lg-2"></div>
<div class="col-md-auto name" id="nameScroll">
Something here
</div>
<div class="col col-lg-2"></div>
</div>
</div>
</div>
correct me if I am wrong, but, your problem is that you want to scroll a div within a row, you may try, overflow: auto, over the parent div.
link of position property for some guidance as how it works -
https://www.w3schools.com/cssref/pr_class_position.asp
I have two sticky navbars, the first white one from Wordpress with its own sticky function, and the black one below is html/css-only (no bootstrap), and it has a strange movement on mobile, it's hard to explain so let me show you:
When I first load the page, it looks good like this:
But when I scroll down, even if just a little bit, the black navbar kind of bounces suddenly and very quickly and makes the content "jump". I have no idea why this is happening since there is no bug when loading the webpage from a computer! It's only a matter of mobile phones. :S
jQuery(window).scroll(function () {
if (jQuery(window).scrollTop() > 0) {
jQuery('#navbar_reservas').addClass('navbar-fixed');
}
if (jQuery(window).scrollTop() <= 0) {
jQuery('#navbar_reservas').removeClass('navbar-fixed');
}
});
CSS
.navbar-fixed {
top: 60px;
z-index: 1000;
position: fixed;
width: 100%;
}
HTML
<div id="navbar_reservas">
<div id="reservas_left">
<div class="nav-item_reservas" id="inner_reservas_left">
<a id="dudas" href="tel:55555555">
¿Dudas?
<br />555 555 555 </a>
</div>
</div>
<div id="reservas_right">
<div class="dropdown_reservas nav-item_reservas" id="inner_reservas_right">
<div class="dropbtn">
TOTAL
<br /><span id="totalprice">0,00€</span>
<i class="material-icons">arrow_drop_down</i>
</div>
</div>
</div>
<div class="dropdown-content_reservas" id="myDropdown">
<ul id="dropul" class="unoul">
<li id="drop2"></li>
<li id="drop3"></li>
<li id="drop4"></li>
<li id="drop5"></li>
<li id="drop6"></li>
</ul>
</div>
</div>
From what I can see you only add the position: fixed when scrollTop is not 0. That will create a new stacking context when the class is applied. That means it'll no longer be "visible" to the elements around it in terms of positioning. And as such the content below it will jump up to fill the gap.
If you know the height of the navbar already, there is a really simple solution:
When the navbar do not have the navbar-fixed class, apply position: absolute on it so it's always in its own stacking context. Then add the height of the navbar as top padding/margin to the content below it.
If you do not know the height:
You'll need to do the same as above, but calculate the height of it with JavaScript on load. If it changes height on say resize or you have some dynamically changing content, you'll need to make sure to update the height used for the above method when those events happen.
If you can work with relatively new code:
There is a CSS property for all this! position: sticky combined with top: 0 Will make the navbar stick to the top of the screen when it otherwise would scroll up behind the viewport.
However, browser support isn't very impressive:
http://caniuse.com/#feat=css-sticky
I have a simple html code where I have a left menu. I want to scroll content on click of menu within the same page. Also I don't want to scroll menu.
The problem is, I am using AngularJS so compiler is confused between routing and segment logic.
Here is my menu:
<div class="container">
<div style="float: left;width:150px;">
<ul class="list-group">
<li class="list-group-item">overview</li>
<li class="list-group-item">Clinical features</li>
<li class="list-group-item">Diagnosis</li>
<li class="list-group-item">Testing laboratories</li>
<li class="list-group-item">Result interpretation</li>
</ul>
</div>
<div class="col-md-10" id="clinical">
<div class="row">
<div class="col-md-2">Result interpretation</div>
<div class="col-md-10">
<p style="text-align: right;">Back To Top</p>
</div>
</div>
<hr>
<p>Hey this is just to test.</p>
</div>
</div>
This is not a problem specific to AngularJS or anything else. It's just a tiny CSS problem:
You're aligning your menu using float: left, which will cause it to appear on the left border but it won't follow you down when scrolling (as you've noticed).
The solution is pretty simple, just attach your menu in a different way. There are many different ways to do this, also depending on whether you're using any JavaScript library (like Bootstrap), but the most simple approach would be pinning the menu using CSS:
.menubar {
/* A fixed alignment will ignore scroll bar positions */
position: fixed;
/* Stretch the bar by forcing offsets and a width */
top: 0;
left: 0;
bottom: 0;
width: 150px;
}
Last but not least you'll have to move your content so it's not hidden by the menu bar (which would otherwise overlap):
.content {
padding-left: 150px; /* of course this could use positioning as well */
}
You can try the whole thing in this jsFiddle.
From your question it's not clear whether you're also looking for soft scrolling, but for that you'll most likely want some additional JavaScript library - or you could just use some library that provides everything for you (including menu bar CSS etc.), like Bootstrap or UI Kit.
My website consists of a navigation bar (class .nav-primary), a widget box (id #mw-panel) and an article. Recently, I tried to move the widget box up to the top, by applying the following changes to my CSS file:
.mw-panel{top: 50px;}
The problem with this option was, that my element was fixed to a specific position. Instead I wanted the widget element to be exactly 100px under the menu bar (and moving when I am scrolling down the page). Instantly, I knew that JavaScript would be the correct way to solve this problem.
Because I had no success, I asked the StackOverflow community, which helped me a lot.
The JavaScript code in the JS section of the attached code snippet, was partially done by me, but it does not work as it should.
Can someone explain me what I need to change to get this JS code working? Again, #mw-panel has to be positioned exactly 100px beneath .nav-primary.
var menu = document.getElementsByClassName("nav-primary")[0];
var widget = document.getElementById("mw-panel");
var difference = widget.offsetTop - menu.offsetBottom;
if (difference > 100) {
document.getElementById("mw-panel").style.top = (menu.offsetBottom + 100) + "px";
}
.content .entry {
margin-top: 40px;
padding-bottom: 400px;
}
<body class="full-width-content">
<link rel="stylesheet" id="child-theme-css" href="http://vocaloid.de/wp-content/themes/Vuturize/style.css" type="text/css" >
<div class="site-container">
<nav class="nav-primary">
<div class="wrap">
<ul class="menu genesis-nav-menu menu-primary">
<li class="menu-item">Home
</li>
<li class="menu-item">News
</li>
<li class="menu-item">Ranking
</li>
</ul>
</div>
</nav>
</div>
<div class="site-inner">
<div class="content-sidebar-wrap">
<main class="content">
<article class="page entry">
<div>
<h1>Test Article</h1>
</div>
</article>
</main>
</div>
</div>
<div id="mw-panel">
<div>
<h3>Navigation</h3>
<div>
<ul>
<li>Letzte Änderungen
</li>
</ul>
</div>
</div>
<h3>Werkzeuge</h3>
<div>
<ul>
<li>Datei hochladen
</li>
<li>Spezialseiten
</li>
</ul>
</div>
</div>
</body>
There's No such property as offsetBottom. Redo your code ONLY considering offsetTop + offsetHeight to get bottom number.
Example:
var menu = document.getElementsByClassName("nav-primary")
var TrueOffset=menu[0].offsetTop+menu[0].offsetHeight;
You're getting the error because there is no offsetBottom property.
Do console.log(menu) in chrome to see the objects available properties
**Update:
Add this to your css:
.mw-panel{
position: absolute;
}
Here it is in action
Updated code in action
After re-reading your question, I missed one key detail: you're trying to do this JavaScript. This is your problem.
If I understand correctly, you have three items: a nav, an article, and a widget box. You want the widget box to stand 100px below the nav, and then move with the page when you scroll.
if this is the case (if not, correct me), then there's only a few things you need to do:
Keep your nav the way it is. Good job here.
I'm assuming you want the widget next to the article (on the left?). So you'll need to make two columns (some sort of containers, each height: 100%). Your widget container will have the property position: fixed; and the article will have position: static; (or relative, you decide).
Each container will have a width, you might choose 30% for the widget container and 70% for the article, for example.
Now you have two columns, one will move with the page as you scroll.
Here are some links to get you started:
Best Way to do Columns in HTML/CSS
https://css-tricks.com/guide-responsive-friendly-css-columns/
http://www.456bereastreet.com/lab/developing_with_web_standards/csslayout/2-col/
When the user scrolldown with the mousewheel, I'd like the page go down untill exactly the begining of the next element. Like :
<section class="One">
...
</section>
<section class="Two">
...
</section>
<section class="Three">
...
</section>
When you enter the website, you'll be at the start page, when you scrolldown 1x, I'd like the page scroll untill the begining of section 2 and so on...
Imagine the sections like, home / about / contact
I tried this, but in this example, I have to write the exactly name of the elements and I would have to write one of this for each section... Is there a different way to do so ?
window.onload=function myScroll() {
x = document.getElementById("chat");
h = x.clientHeight;
x.scrollTop = h;
}
<div id="chat" style="width: 100%; height: 70px; overflow: scroll;
border: 1px solid grey">
This can be quite complicated due to the fact that this involves scrolling, catching the mouse wheel events, delay in animations, cross browser usage, swipe and touch events. Fortunately, there are plugins available to make your life easier. One of the most popular ones is Full Page.
Some of the features include:
Usage over old browsers with no CSS3 support.
Add a live menu.
Slide throw the page using the keyboard arrows.
Add horizontal sliders.
Mobile and Tablet detection enabling the scrolling on them.
Usage:
Each section will be defined with a div containing the section class.
<div class="section">
<div class="slide"> Slide 1 </div>
<div class="slide"> Slide 2 </div>
<div class="slide"> Slide 3 </div>
<div class="slide"> Slide 4 </div>
</div>
All you need to do is call the plugin inside a $(document).ready function:
jQuery:
$(document).ready(function() {
$('#fullpage').fullpage();
});
Demo