Problem positioning top 2 DIVs when scrolling - html

I am trying to make a webapp what has a 3 sections.
1 - A search bar.
2 - a navigation menu.
3 - The main content.
Ideally how I want it work is when the main content is scrolled down the search bar scrolls up out of site and the navigation goes to the top with the main content scrolling behind everything. But when scrolled up by any amount both the search bar and navigation scroll smoothly back to starting position and the main content remains where it is currently scrolled to.
I have tried it with sticky positioning and using jquery to detect scroll up and down but it all goes a little wierd. I also tried checking scroll just on main element and moving the other 2 accordingly but it was very jumpy, I hope I have explained it clearly.
The code is :
body {
margin:0;
padding:0;
min-height:200vh;
border:2px solid;
}.
search {
height:50px;
background:red;
position:sticky;
top:-50px;
transition: all .2s ease-in-out;
}
.navbar {
height:50px;
background:blue;
position:sticky;
top:0px;
transition: all .2s ease-in-out;
}
.main {
height:100vh;
background:green;
position:sticky;
top:50px;
transition: all .2s ease-in-out;
}
<script src="https://code.jquery.com/jquery.js"></script>
<div id="search" class="search"></div>
<div id="navbar" class="navbar"></div>
<div id="main" class="main"></div>
Now when ran in a browser all 3 elements show but not in example?
I have tried adding this JS but no good? This is driving me mad as I am sure it is quite simple but I just can not figure it out, any help or advice would be greatly appreciated.
var position = $(window).scrollTop();
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if(scroll > position) {
console.log('scrollDown');
document.getElementById("navbar").style.top = "0px";
document.getElementById("navbar").style.position = "sticky";
} else {
console.log('scrollUp');
document.getElementById("navbar").style.top = "50px";
document.getElementById("navbar").style.position = "fixed";
}
position = scroll;
});

Is it ok to add 1 - A search bar. 2 - a navigation menu in one div? I tried with adding these two elements in one div.
Also note that if you add CSS on search bar the height of navbar will be changed. So update that height in JS.
var prevScrollpos = window.pageYOffset;
window.onscroll = function() {
var currentScrollPos = window.pageYOffset;
if (prevScrollpos > currentScrollPos) {
document.getElementById("navbar").style.top = "0";
} else {
document.getElementById("navbar").style.top = "-80px";
}
prevScrollpos = currentScrollPos;
}
body {
margin: 0;
background-color: #f1f1f1;
font-family: Arial, Helvetica, sans-serif;
}
#navbar {
background-color: #333;
position: fixed;
top: 0;
width: 100%;
display: block;
transition: top 0.3s;
}
#navbar a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 15px;
text-decoration: none;
font-size: 17px;
}
#navbar a:hover {
background-color: #ddd;
color: black;
}
<div id="navbar">
<div class="search">
<form>
<input type="serch">
<input type="submit" vlaue="search"></button>
</form>
</div>
<div class="navbar-links">
Home
News
Contact
</div>
</div>
<div style="padding:15px 15px 1500px;font-size:30px;margin-top:30px;">
<p><b>This example demonstrates how to hide a navbar when the user starts to scroll the page.</b></p>
<p>Scroll down this frame to see the effect!</p>
</div>

Related

How to synchronize side-panel height to dynamic height?

My side-panel height is not expanding when my div content's get bigger. I've given the height to 100% it's working fine for mobile view but for the desktop view, sometimes my sidebar's height is not increasing as it's fixed. But I want this height to be dynamic with content of my div. This is my whole code : JSFiddle
Here you can see, if you click the navbar, it's open the bar, and down below you will see side-bar and div content are not in the same height. This is the problem I'm getting :
I want side bar to expand. How can I resolve this? All I can say that I've to change this css class's height but how ?:
.sidepanel {
height: 100%;
width: 0;
position: absolute;
z-index: 1;
left: 0;
background-color: #221F20;
overflow-x: hidden;
padding-top: 40px;
transition: 0.3s;
}
if you add position: relative to your body, your problem should be solved.
$(document).ready(function() {
//sidepanel navigation
$(".toggleButton").on("click", function() {
if ($(".sidepanel").css("width") == "0px") {
var mainWidth = $("#main").width() - 256;
$(".sidepanel").css("width", `15%`);
$("#main").css("margin-left", `15%`);
$("#main").css("width", `85%`);
} else {
$(".sidepanel").css("width", "0%");
$("#main").css("margin-left", "0%");
$("#main").css("width", "100%");
}
});
//menu item navigation
$(".menuItem").on("click", function() {
// if this menuitem is collapsed
if ($(this).next().css("height") == "0px") {
// turning off all other menu items except for this
$(".menuItem").not($(this)).next("div").css("height", "0px");
$(".menuItem").not($(this)).removeClass("openAnchor");
$(".menuItem").not($(this)).addClass("collapsedAnchor");
// turning off all sub menu items except for this
$(".subMenuItem").next("div").css("height", "0px");
$(".subMenuItem").removeClass("openAnchor");
$(".subMenuItem").addClass("collapsedAnchor");
// substituting collapsed class for open class
$(this).removeClass("collapsedAnchor");
$(this).addClass("openAnchor");
var numberOfChildren = $(this).next("div").find("> a").length;
var height = 37 * numberOfChildren;
$(this).next("div").css("height", `${height}px`);
} else {
$(this).removeClass("openAnchor");
$(this).addClass("collapsedAnchor");
$(this).next("div").css("height", "0px");
}
});
// sub menu item navigation
$(".subMenuItem").on("click", function() {
// if this menuitem is collapsed
if ($(this).next().css("height") == "0px") {
// accesing sibling open anchor
var openAnchorChildNumber = $(this).parent().find(".openAnchor").first().next("div").find("> a").length;
var heightToDeduce = 37 * openAnchorChildNumber;
console.log(heightToDeduce);
// turning off all other sub menu items except for this
$(".subMenuItem").not($(this)).next("div").css("height", "0px");
$(".subMenuItem").not($(this)).removeClass("openAnchor");
$(".subMenuItem").not($(this)).addClass("collapsedAnchor");
// substituting collapsed class for open class
$(this).removeClass("collapsedAnchor");
$(this).addClass("openAnchor");
var numberOfChildren = $(this).next("div").find("> a").length;
var height = 37 * numberOfChildren;
$(this).next("div").css("height", `${height}px`);
var parentHeight = $(this).parent().height() + height - heightToDeduce;
$(this).parent().css("height", `${parentHeight}px`);
} else {
$(this).removeClass("openAnchor");
$(this).addClass("collapsedAnchor");
$(this).next("div").css("height", "0px");
var numberOfChildren = $(this).next("div").find("> a").length;
var height = 37 * numberOfChildren;
var parentHeight = $(this).parent().height() - height;
$(this).parent().css("height", `${parentHeight}px`);
}
});
});
body {
position: relative;
}
/* The sidepanel menu */
.sidepanel {
height: 100%; /* Specify a height */
width: 0; /* 0 width - change this with JavaScript */
position: absolute; /* Stay in place */
z-index: 1;
left: 0;
background-color: #221F20; /* Black*/
overflow-x: hidden; /* Disable horizontal scroll */
padding-top: 40px; /* Place content 60px from the top */
transition: 0.3s;
}
.sidepanel .collapsedAnchor::after {
font-family: 'Font Awesome 5 Free';
float: right;
font-weight: 900;
content: "\f054";
}
.sidepanel .openAnchor::after {
font-family: 'Font Awesome 5 Free';
float: right;
font-weight: 900;
content: "\f078";
}
/* The sidepanel links */
.sidepanel a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #B7B6B8;
display: block;
transition: 0.3s;
font-size: 13px;
}
/* When you mouse over the navigation links, change their color */
.sidepanel a:hover {
color: #FFFFFF;
}
/* Position and style the close button (top right corner) */
.sidepanel .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
a.menuItem i.fa{
font-size: 15px;
}
#main {
transition: margin-left 0.5s;
padding: 16px;
}
#media screen and (max-height: 450px) {
.sidenav {
padding-top: 15px;
}
.sidenav a {
font-size: 18px;
}
}
.sidepanel .subMenus {
padding-left: 3%;
/* position: fixed; */
overflow-y: hidden;
transition: 0.5s;
}
.subMenus a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s;
font-size: 13px;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="navbar" >
<i class="fa fa-align-left" style="color: #000;"></i>
<p>
user
</p>
</div>
<div class="sidepanel">
<!-- General panel -->
<i class="fas fa-file-alt sidepanel-icon"></i> General
</div>
<div class="container-fluid px-5 mt-2" id="main">
<div class="row py-4">
<div class="col-md-6 page-title-div">
<div class="page-header">
<h2>HTML</h2>
</div>
</div>
</div>
<div class="row card py-4 rounded">
<div class="col-md-6 page-title-div">
<div>
<p>In HTML, there are two main types of lists:
unordered lists (<ul>) - the list items are marked with bullets
ordered lists (<ol>) - the list items are marked with numbers or letters
The CSS list properties allow you to:
Set different list item markers for ordered lists
Set different list item markers for unordered lists
Set an image as the list item marker
Add background colors to lists and list items
</p>
</div>
</div>
</div>
</div>
position should be fixed.
top 0 property solved the space issue.
added toggle inside the nav to toggle it when it opens, you only need to restyle the toggle that is inside the nav if you wish.
.sidepanel {
height: 100%;
top: 0;
width: 0;
position: fixed;
z-index: 9999;
left: 0;
background-color: #221F20;
overflow-x: hidden;
padding-top: 40px;
transition: 0.3s;
}
<div class="navbar" >
<i class="fa fa-align-left" style="color: #000;"></i>
<p>
user
</p>
</div>
<div class="sidepanel">
<i class="fa fa-align-left" style="color: #000;"></i>
<!-- General panel -->
<i class="fas fa-file-alt sidepanel-icon"></i> General
</div>
<div class="container-fluid px-5 mt-2" id="main">
<div class="row py-4">
<div class="col-md-6 page-title-div">
<div class="page-header">
<h2>HTML</h2>
</div>
</div>
</div>
<div class="row card py-4 rounded">
<div class="col-md-6 page-title-div">
<div>
<p>In HTML, there are two main types of lists:
unordered lists (<ul>) - the list items are marked with bullets
ordered lists (<ol>) - the list items are marked with numbers or letters
The CSS list properties allow you to:
Set different list item markers for ordered lists
Set different list item markers for unordered lists
Set an image as the list item marker
Add background colors to lists and list items
</p>
</div>
</div>
</div>
</div>

stacking divs while pushing content down upon expanding an image?

I'm working on this banner ad that I posted here yesterday and I got my images fading properly, but I had everything positioned in an absolute manner, and I need to have it so that when my ad expands, it pushes whatever content below it down. Right now, when I press expand, it covers the image below it, rather than push it down even though the picture's positioning is relative.
Here's a link to my project on codepen.
And here's my CSS:
#banner{
position: relative;
min-height: 100px;
}
.hide {
transition: opacity .5s ease-in-out;
opacity: 0;
position:absolute;
}
.show {
transition: opacity .5s ease-in-out;
opacity: 1;
position: absolute;
z-index: 1;
}
#toggle, #toggle2{
cursor: pointer;
}
#toggle{
margin-left:-123px;
}
#toggle2{
position: relative;
}
#twitterIcon{
position: relative;
}
.videoDiv > video {
display:inline-block;
border: 1px solid;
font-size:0;
margin: 0;
padding:0;
}
.videoDiv{
font-size:0;
margin-left:413px;
padding-top:152px;
}
I've read that absolute positioning makes it this way, but I need the collapsed and expanded version to be absolute so that they're on top of one another. Is there anyway I can make it so that the Coach ad pushes the image of Ron Swanson down rather than covering it?
Here is a complete solution: http://codepen.io/anon/pen/mewMEO
The solution is to make the smaller banner absolute with a negative z-index so it is in fact behind the normally positioned large banner.
Also, I took the liberty of improving your JS code by making it more generic and adding support for multiple banners on the page.
HTML
<div class="banner collapsed">
<img class="preview-size" src="http://i.imgur.com/y6foj3Z.jpg"/>
<img class="full-size" src="http://i.imgur.com/CeUfSAX.jpg"/>
<div class="btn-expand">
<img id="toggle" src="http://i.imgur.com/axmdldH.png" />
</div>
<div class="btn-collapse">
<img src="http://i.imgur.com/5wZwdGz.png" />
<a href="https://twitter.com/intent/tweet?text=I%20LOVE%20the%20new%20%40coach%20swagger!">
<img id="twitterIcon" src="http://i.imgur.com/WxSsDpb.png" />
</a>
</div>
</div>
<div class="push">
<img src="http://i.imgur.com/sFNERNs.jpg" />
</div>
CSS
.banner {
position: relative;
width: 970px;
}
.banner img {
/* Get rid of that margin on the bottom of the images */
display: block;
}
.banner .btn-collapse img {
display: inline;
}
.banner .btn-expand {
position: absolute;
bottom: 0;
right: 0;
}
.banner .preview-size {
z-index: -1;
position: absolute;
}
.banner .btn-expand {
display: none;
}
.banner.collapsed .preview-size {
z-index: 0;
position: relative;
}
.banner.collapsed .preview-size,
.banner.collapsed .btn-expand {
display: block;
}
.banner.collapsed .full-size,
.banner.collapsed .btn-collapse {
display: none;
}
JS
(function() {
var bannerEls = document.getElementsByClassName('banner');
// Support multiple banners
for (var index = 0; index < bannerEls.length; index++) {
var currBannerEl = bannerEls[index];
var expandEl = currBannerEl.getElementsByClassName('btn-expand')[0];
var collapseEl = currBannerEl.getElementsByClassName('btn-collapse')[0];
registerBannerToggle(expandEl, currBannerEl);
registerBannerToggle(collapseEl, currBannerEl);
}
function registerBannerToggle(clickableEl, bannerEl) {
clickableEl.addEventListener('click', function(e) {
toggleCollapseState(bannerEl);
});
}
function toggleCollapseState(bannerEl) {
if (bannerEl.className.indexOf('collapsed') !== -1) {
bannerEl.className =
bannerEl.className.replace(/collapsed/g, '');
}
else {
bannerEl.className += ' collapsed';
}
}
})();
The reason you are not able to do this was intentional to deter advertisers from messing with the actual website content. To pull it off, you would have to keep the position relative for the add or manipulate the ".push" div using javascript.
I dont know much plain javascript so I changed it for jQuery if you don't mind
All I've done was get images height and set animate on them with click on #toggle/#toggle2
CODEPEN

Back to top of page link with iFrame?

I am trying to make a link that will take you to the top of your page when you click it. I already have a header and footer on each page. They are embedded using iFrame. Now, I am trying to put
<a name="top"></a>
on the header, and
on the footer. But when I add them, nothing happens when I click on the link. I tried adding target="_top" but that just opens the footer in a new tab.
Does anybody know how I can write the html so that it will take me to the top of the current page after clicking a link in the footer?
Change the <a> in the header to <a id="top">
See this fiddle.
Apply this code on the page where header and footer both are embedded.
JSFIDDLE
In head section apply this script
<script>
$(document).ready(function(){
//Check to see if the window is top if not then display button
$(window).scroll(function(){
if ($(this).scrollTop() > 100) {
$('.scrollToTop').fadeIn();
} else {
$('.scrollToTop').fadeOut();
}
});
//Click event to scroll to top
$('.scrollToTop').click(function(){
$('html, body').animate({scrollTop : 0},200);
return false;
});
});
</script>
.fixedscrolltotop
{
position: fixed;
bottom: 25%;
right: 0;
width: 149px;
color:black;
font-weight:bold;
text-align:center;
-webkit-box-flex:1;
}
.scrollToTop
{
width:80px;
height:80px;
text-align:center;
background: whiteSmoke;
font-weight: bold;
color: #444;
text-decoration: none;
position:fixed;
bottom:60px;
right:0px;
display:none;
background: url('http://tech.firstpost.com/wp-content/uploads/up-arrow-icon.png') no-repeat;
background-size: 100% 100%;
opacity: 0.5;
-webkit-box-flex:1;
}
.scrollToTop:hover
{
text-decoration:none;
opacity: 1;
-webkit-box-flex:1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="fixedscrolltotop">
<a href="" class="scrollToTop" title="Back To The Top">
</a>
</div>
Is this code appropriate if looking ahead for something else do let me know

How do I link to top of a section on the page minus the height of a fixed nav-bar?

When I click a link on my fixed navigation bar, it jumps to a specific section on the page, but the fixed nav-bar's height spills over. How can I subtract that height? Will this require javascript/jquery?
<div id="fixedNavWrapper">
<div id="navLinks">
<ul>
<li>ABOUT ME</li>
<li>PORTFOLIO</li>
</ul>
</div>
</div>
<section id="about" class="section">
<h2>ABOUT ME</h2>
</section>
.CSS:
#fixedNavWrapper {
position: fixed;
z-index: 1;
width: 100%;
top: 0;
left: 0;
}
#navLinks {
text-align: center;
width: 100%;
height: 57px;
background: #000000;
}
#navLinks ul {
list-style: none;
margin: 0;
padding: 5px;
display: inline-block;
}
#navLinks ul li {
margin: 0;
padding: 0;
display: inline;
}
#navLinks ul li a {
text-decoration: none;
display: block;
float: left;
padding: 0 65px;
height: 45px;
line-height: 45px;
}
I think that you can't do it with css. However you can use jQuery to do it. Quite easy:
HTML (add classes to li elements to identify them in your jQuery code):
<div id="fixedNavWrapper">
<div id="navLinks">
<ul>
<li class="about">ABOUT ME</li>
<li class="portfolio">PORTFOLIO</li>
</ul>
</div>
</div>
<section id="about" class="section">
<h2>ABOUT ME</h2>
</section>
JS (Use event .click to move your "body" to the correct position )
$('li.about').click(function(){
positionabout = $('#about').offset().top - $('#fixedNavWrapper').height(); // Position of #about - nav height = correct position
$("html, body").animate({scrollTop:positionabout}, '500', 'swing');
})
$('li.portfolio').click(function(){
positionport = $('#portfolio').offset().top - $('#fixedNavWrapper').height();
$("html, body").animate({scrollTop:positionport}, '500', 'swing');
})
a bit more general:
$('.navbar li a').click(function () {
var speed = 500;
var easing = 'swing';
var topMargin = 10;
var href = $(this).attr("href");
var name = href.substr(href.indexOf("#") + 1);
var $link = $("a[name='" + name + "']");
positionabout = $link.offset().top - $('.navbar').height() - topMargin;
$("html, body").animate({scrollTop: positionabout}, speed, easing);
return false;
});
My problem : link redirect to other page anchor - when I click on it Im redirect to the other page with my navbar of 10 rem.. so the problem is I could not see the full article because the navbar was above the article.
scroll-padding-top: 10rem;
Was the best answer for me.
Thanks #Becki6799
just add this to your .css file:
html
{scroll-padding-top: 5rem;}

Stick header after scrolling

I made a header navigation and it's halfway down the page. When you scroll, and it's on the top of the page I want it to stick, if you know what I mean.
I hope someone can tell me how I get this done. Demo JsFiddle
HTML
<header>menu</header>
CSS
body, html {
height: 2000px;
}
header {
position: absolute;
top: 300px;
background-color: black;
color: white;
width: 100%;
}
You are going to need some JavaScript.
Demo JsFiddle
HTML
<header>
<div class="logo">AWESOME HEADER!</div>
<div class="menu">Menu goes here - home - links - blah blah</div>
</header>
<div class="content">
<!-- your stuff -->
</div>
CSS
* { margin:0; padding:0; }
.logo {
font-size:40px;
font-weight:bold;
color:#a00;
font-style:italic;
}
.menu {
background:#a00;
color:#fff;
height:30px;
line-height:30px;
letter-spacing:1px;
width:100%;
}
.content { margin-top:10px; }
/* the trick */
.menu-padding { padding-top:40px; }
.sticky {
position:fixed;
top:0;
}
Javascript (JQuery)
$(document).ready(function () {
var menu = document.querySelector('.menu');
var origOffsetY = menu.offsetTop;
function scroll() {
if ($(window).scrollTop() >= origOffsetY) {
$('.menu').addClass('sticky');
$('.content').addClass('menu-padding');
} else {
$('.menu').removeClass('sticky');
$('.content').removeClass('menu-padding');
}
}
document.onscroll = scroll;
});
Take a look at this tutorial. It explains how to do it using either CSS or jQuery depending on what you want.
http://www.hongkiat.com/blog/css-sticky-position/