Making two divs stick to the top of page after scrolled past - html

I've been trying to make two divs stick to the top of the page after the user scrolled past these divs. Both divs are positioned at the same hight. This is what I have been using from other stackoverflow answers:
Html:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript">
function sticky_relocate() {
var window_top = $(window).scrollTop();
var div_top = $('#sticky-anchor').offset().top;
if (window_top > div_top)
$('#blockleft').addClass('sticky')
else
$('#blockleft').removeClass('sticky');
}
$(function() {
$(window).scroll(sticky_relocate);
sticky_relocate();
});
</script>
</head>
<body>
<div id="header"></div>
<div id="sticky-anchor"></div>
<div class="container">
<div id="blockleft"></div>
<div id="blockright"></div>
<div id="content"></div>
</div>
</body>
Css:
body {
margin: 0;
padding: 0;
}
#header {
height:200px;
background-color:#666;
}
#blockleft {
width:100px;
height:500px;
margin-top:10px;
background-color:#090;
float:left;
}
#blockright {
width:100px;
height:500px;
margin-top:10px;
background-color:#0F3;
float:right;
}
#content {
width:500px;
height:2000px;
background-color:#0CF;
margin:auto;
}
.container {
width:800px;
margin:auto;
}
.sticky {
position: fixed;
top: 0;
}
The script is working fine on one div, but when using the script twice it automatically moves the right div to the left and this one is not sticking to the top of the page.
I was hoping someone could help me out with this one.
Edit: Recreated the problem in a new document

Since the divs lose float property when we make it position:fixed, they both overlap with each other. In order to make them in their position, we need to apply right distance for the right div. To fix this, replace your script code as follows.
<script type="text/javascript">
function sticky_relocate() {
var containerWidth = $(".container").outerWidth(true);
var window_top = $(window).scrollTop();
var div_top = $('#sticky-anchor').offset().top;
if (window_top > div_top)
{
$('#blockleft').addClass('sticky');
$('#blockright').addClass('sticky');
$('#blockright').css("right", (containerWidth-800)/2 + "px");
}
else
{
$('#blockleft').removeClass('sticky');
$('#blockright').removeClass('sticky');
}
}
$(function() {
$(window).scroll(sticky_relocate);
sticky_relocate();
});
</script>
The code $('#blockright').css("right", (containerWidth-800)/2 + "px"); calculates the right distance value for the right div and adds css property right:XXXpx to that div while scrolling. The code var containerWidth = $(".container").outerWidth(true); fetches the width of the container div with its margin value (since margin is made auto, we need definite number for calculation)

Related

Display a Search bar on header on scroll HTML/CSS

I have a search bar which would like to display onto the header on scroll, a great example is like the one on this site: https://www.indiamart.com/
Approach 1 - A simple way to do this would be to detect a scroll & add and remove a class that contains display: none;
You can have an event listener -
window.addEventListener('scroll', function() {
if( window.scrollY !== 0) {
document.getElementById('searchBar').classList.add('scrolled');
} else {
document.getElementById('searchBar').classList.remove('scrolled');
}
});
With the CSS -
.noScroll
{
background: yellow;
position:fixed;
height: 50px; /*Whatever you want*/
width: 100%; /*Whatever you want*/
top:0;
left:0;
display:none;
}
/*Use this class when you want your content to be shown after some scroll*/
.scrolled
{
display: block !important;
}
.parent {
/* something to ensure that the parent container is scrollable */
height: 200vh;
}
And the html would be -
<div class="parent">
<div class ='noScroll' id='searchBar'>Content you want to show on scroll</div>
</div>
Here's a JSFiddle of the same - https://jsfiddle.net/kecnrh3g/
Approach 2 -
Another simple approach would be
<script>
let prevScrollpos = window.pageYOffset;
window.onscroll = function() {
let currentScrollPos = window.pageYOffset;
if (prevScrollpos > currentScrollPos) {
document.getElementById('searchBar').style.top = '-50px';
} else {
document.getElementById('searchBar').style.top = '0';
}
prevScrollpos = currentScrollPos;
}
</script>
with the html -
<div class="parent">
<div id ='searchBar'>Content you want to show on scroll</div>
</div>
and css
#searchBar {
background: yellow;
position: fixed;
top: 0;
left: 0;
height: 50px;
width: 100%;
display: block;
transition: top 0.3s;
}
.parent {
height: 200vh;
}
Here's a JSFiddle of the same - https://jsfiddle.net/0tkedcns/1/
From the same example, the idea is only to show/hide once user scroll the page using inline css display property, you can do the same or at least provide a code sample so we can help you!
HTML
<div class="search-bar">
<div class="sticky-search">
Sticky Search: <input type="text" value="search" />
</div>
</div>
CSS
.sticky-search {
display:none;
position:fixed;
top:0px;
left:0px;
right:0px;
background:blue;
padding:10px;
}
JS
var searchHeight = $(".search-bar").outerHeight();
var offset = $(".search-bar").offset().top;
var totalHeight = searchHeight + offset;
console.log(totalHeight);
$(window).scroll(function(){
if($(document).scrollTop() >= totalHeight) {
$('.sticky-search').show();
} else {
$('.sticky-search').hide();
}
});

How to change data visible range to % percent

I am using this for my header that changes in a one page scroll up and down page. I noticed that it's not responsive so i am asking you if you maybe know a way to make that responsive. Like changing the 0-690 into a percentage so that it will work on mobile and also on a tv screen.
HTML
<div class="header header-1" data-visible-range="0-690">Portfolio</div>
<div class="header header-2" data-visible-range="691-2100">Services</div>
<div class="header header-3" data-visible-range="2101-">Contact</div>
CSS
.header-1 {
background-color:dimgray;
display: block;
}
.header-2 {
background-color:dimgray;
}
.header-3 {
background-color:dimgray;
}
.header {
position: fixed;
top: 0;
left: 0;
height:8vmax;
width: 100%;
display: none;
visibility:hidden;
transition: visibility .4s, opacity .4s ease-in-out;opacity:0;
font-size:4vmax;padding:1.58vmax;color:white;
}
What if, instead of basing it off pixels, you just checked to see if an element hit the top of the page, and then changed the header?
We'll call these elements "triggers." See my code below for an example of how they work.
let updateHeader = () => {
let scrollTop = $(window).scrollTop(),
triggerTitle = "Hi";
$('.trigger').each((i, el) => {
let topPos = $(el).offset().top,
distance = topPos - scrollTop;
if (distance < 0)
triggerTitle = $(el).data('title');
});
$('header h2').text(triggerTitle);
}
$(window).scroll(updateHeader);
$(window).on('touchmove', updateHeader);
body {
margin: 0;
}
#container {
height: 1000px;
}
header {
width: 100%;
position: fixed;
top: 0;
background-color: red;
}
p {
margin: 200px 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<header><h2>Hi</h2></header>
<p class="trigger" data-title="section1">
trigger1
</p>
<p class="trigger" data-title="section2">
trigger2
</p>
<p class="trigger" data-title="section3">
trigger3
</p>
</div>
As you scroll down the page, each trigger hits the top of the page, and the text in the header will change to the the value of the latest trigger's data-title. You could position these triggers appropriately above each of your website's sections, so that, no matter what size the screen, the header should update at the right time. Here's a codepen.
EDIT
Try this JS instead for maximum compatibility (no es6 involved).
function updateHeader() {
var scrollTop = $(window).scrollTop(),
triggerTitle = "Hi";
$('.trigger').each(function(i, el) {
var topPos = $(el).offset().top,
distance = topPos - scrollTop;
if (distance < 0)
triggerTitle = $(el).data('title');
});
$('header h2').text(triggerTitle);
}
$(window).scroll(updateHeader);
$(window).on('touchmove', updateHeader);

Dont know why i cant center web

So, in web-programming class (a few weeks ago) we started a project to make our own website. Now, most things are going fine, though I tried to center my page it didnt work. I don't know why it doesn't work either, I'm thinking it might be something in the codes that might block/counter it, but I don't know. I basically want the whole html centered. I used an ID which I named "wrap" on the div tag after the bgcolor tag as you will see.
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Norskandi</title>
<link rel="stylesheet" type="text/css" href="css/norskandi.css">
<style type="text/css">
</style>
</head>
<body bgcolor="#4A96AD">
<div id="wrap">
<IMG STYLE="WIDTH:1400px; HEIGHT:80px" src="../bilder/3_11.png">
Contact
About
<script type="text/javascript">
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
// Close the dropdown menu if the user clicks outside of it
/*window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}*/
function geography() {
document.getElementById("geography").classList.toggle("show");
}
// Close the dropdown menu if the user clicks outside of it
/*window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content1");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}*/
function anthems() {
document.getElementById("anthems").classList.toggle("show");
}
// Close the dropdown menu if the user clicks outside of it
/*window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content2");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}*/
</script>
<div class="dropdown">
<button onmouseover="myFunction()" class="dropbtn">History</button>
<div id="myDropdown" class="dropdown-content">
Sweden
Norway
Denmark
</div>
</div>
<div class="dropdown1">
<button onmouseover="geography()" class="dropbtn">Geography</button>
<div id="geography" class="dropdown-content1">
Sweden
Norway
Denmark
</div>
</div>
<div class="dropdown2">
<button onmouseover="anthems()" class="dropbtn">Anthems</button>
<div id="anthems" class="dropdown-content2">
Sweden
Norway
Denmark
</div>
</div>
</div>
</body>
</html>
CSS:
#wrap{
width: 800px;
margin-right: auto;
margin-left: auto;
height: auto;
}
Like #Juan-Ferres here is a JSFiddle that may help you. Another great resource is Bootstrap and look at the class container in their examples. As a few have pointed out though the key is margin: 0 auto or something like margin: 10px 10px 10px 10px but then you need to be more exacting with your width.
Try justify-content: center in you CSS code
Your #wrap div is being centered on the site. However, for resolutions smaller than 800px, you will see it overflows horizontally.
You may think it's not centered due to your img tag having an inline style of width: 1400px which makes it extend beyond the actual container div.
Here's a fiddle with that tag removed (try not to use inline styles on your HTML for proper separation of concerns as in, CSS in css files, and HTML in html files). https://jsfiddle.net/dm3bmpas/
I've also replaced width: 800px for max-width: 800px and width: 100% so your container takes up to 800px on resolutions big enough but for smaller resolutions it takes all the available width; this is a common responsive pattern.
Finally, just in case, if you want your text to be centered inside your div, the rule you're looking at is text-align: center on your #wrap div.
Try this css
#wrap{
width: 800px;
margin:0px auto;
}

stop scrolling inside fixed div

I have 2 divs (one is fixed, the other one is relative)
I was implementing a scrolling behavior inside the fixed one ... scrolling along with the page. What i want to do more is when the div inside fixed one is scrolled to the bottom this should stop scrolling, only the page should continue scroll.
I do not know if i was very clear so that's why i create a fiddle.
<style>
body {
background-color:#dddddd;
margin: 0;
}
#mainDiv{
top: 120px;
max-width: 1024px;
margin:0px auto;
background-color:#fff;
}
#leftDiv{
width: 30%;
float: left;
background-color: #DBEAED;
height: 300px;
top: 1em;
z-index: 999;
position: fixed;
overflow: hidden;
}
#rightDiv{
width: 68%;
padding-left: 2%;
float: right;
background-color: #FBE9DD;
}
#filters{
display: inline-block;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
window.onscroll = scrollFunction;
function scrollFunction() {
var doc = document.documentElement, body = document.body;
var top = (doc && doc.scrollTop || body && body.scrollTop || 0);;
$('#filters').css("margin-top", -top);
}
});
</script>
<div id="mainDiv">
<div id="leftDiv">
<div id="filters">
<p>XX 1</p><p>XX 2</p><p>XX 3</p><p>XX 4</p><p>XX 5</p><p>XX 6</p><p>XX 7</p><p>XX 8</p><p>XX 9</p><p>XX 10</p><p>XX 11</p><p>XX 12</p>
</div>
</div>
<div id="rightDiv">
Here is PLP page
<p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p>
<p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p>
<p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p>
</div>
</div>
Any help is more than welcome. Thanks !!!
ps. X12 should stick to the end of blue area.
If I undersand correctly, make it so that top has a maximum value of $('#filters').height()-$('#leftDiv').height(), which is as far as you want filters to scroll. Further, to make it be able to change directions gracefully, rather than set the margin of #filters equal to scroll top, we have to instead increment and decrement the value as we scroll
$(document).ready(function () {
window.onscroll = scrollFunction;
var filterMargin = 0;
maxTop = $('#filters').height() - $('#leftDiv').height();
lastTop = 0;
function scrollFunction() {
var doc = document.documentElement, body = document.body;
var top = (doc && doc.scrollTop || body && body.scrollTop || 0);
filterMargin = -parseInt($('#filters').css("margin-top"));
var diff = top - lastTop;
filterMargin += diff;
//make sure the margin value stops when the scrolling stops,
//otherwise the scrolling physically stops but the value keeps growing
filterMargin = filterMargin < 0 ? 0 : filterMargin;
filterMargin = filterMargin > maxTop ? maxTop : filterMargin;
console.log(top, maxTop, filterMargin, top - lastTop);
$('#filters').css("margin-top", -filterMargin + 'px');
lastTop = top;
}
});
Fiddle:
http://jsfiddle.net/nfp6fhg6/5/

Div inside scroll area being scrolled away

I have a Scrollable area and buttons < > to make it scroll.
I need to have those button's span inside the main div (spinAreaDiv) without they getting scrolled away.
Q: What am I missing? (fiddle here)
I tried having the span with float, then they are inside spinAreaDivbut get scrolled away...
HTML
<div id="spinAreaDiv">
<span id="leftclick" class="left"> < </span>
<span id="rightclick" class="right"> > </span>
<div class="spin-bullets">
zzzZZzzz...zzzZZzzz...zzzZZzzz...zzzZZzzz...zzzZZzzz...zzzZZzzz...
zzzZZzzz...zzzZZzzz...zzzZZzzz...zzzZZzzz...zzzZZzzz...zzzZZzzz...
zzzZZzzz...zzzZZzzz...zzzZZzzz...zzzZZzzz...zzzZZzzz...zzzZZzzz...
zzzZZzzz...zzzZZzzz...zzzZZzzz...zzzZZzzz...zzzZZzzz...zzzZZzzz...
zzzZZzzz...zzzZZzzz...zzzZZzzz...zzzZZzzz...zzzZZzzz...zzzZZzzz...
</div>
JS:
spinAreaDiv = document.getElementById('spinAreaDiv');
scrollEff = new Fx.Scroll(spinAreaDiv, {
wait: false,
duration: 1000,
offset: {
'x': 0,
'y': 0
},
transition: Fx.Transitions.Quad.easeInOut
});
thumbLeft = document.getElementById('leftclick');
thumbRight = document.getElementById('rightclick');
thumbLeft.addEvent("click", function () {
scrollEff.start((spinAreaDiv.getScroll().x) - 400, 0);
});
thumbRight.addEvent("click", function () {
scrollEff.start((spinAreaDiv.getScroll().x) + 400, 0);
});
CSS:
#spinAreaDiv {
width:500px;
margin-left:10%;
overflow:auto;
height:60px;
background-color:grey;
}
span {
margin-top:20px;
background-color:red;
z-index:100;
}
span.right {position:absolute;right:0px;}
span.left {position:absolute;left: 0;}
.spin-bullets {
width:10000px;
height:35px;
padding-top:10px;
top:0px;
background-color:#066;
}
(Using Mootools Fx.Scroll)
I'm not familiar with "MooTools", but you could change the left/right offset on the buttons during scroll:
spinAreaDiv.addEvent('scroll', function(ev){
thumbLeft.style.left = spinAreaDiv.getScroll().x + 'px';
thumbRight.style.right = (-spinAreaDiv.getScroll().x) + 'px';
});
(test)
Also, you need to position your spinArea:
#spinAreaDiv {
position: relative;
}
It might be a better idea to move your scroll content into another DIV with the scroll width and height, and put the buttons there. Example.
Your span buttons should be standing outside of #spinAreaDiv or take reference of position from a parent that do not scroll.
http://jsfiddle.net/53AMT/1/.
if you wrap your slider in :anther div;
#myslider {
position:relative;
z-index:1;
width:500px;
margin:auto;
}
They can lay over it though.