How to prevent page scroll to the top while menu opened - javascript

There is a menu button on the page. When a user taps the button full-page menu opens. There is a problem - the main content page automatically scrolls to the top. Could you advise me on how to prevent it? I've already checked a similar question here How to disable scrolling in the background when the mobile menu is open?, but nor position:fixed or oveflow:hidden helped
const menuOpen = document.querySelector('.menu-open');
const menuClose = document.querySelector('.menu-close');
const body = document.querySelector('.root');
function lockScroll() {
body.classList.add('lock');
}
function unLockScroll() {
body.classList.remove('lock');
}
menuOpen.addEventListener('click', lockScroll);
menuClose.addEventListener('click', unLockScroll);
.lock {
position: fixed;
height: 100vh;
overflow-y: hidden;
}
.menu-open {
position: fixed;
top: 0;
right: 0;
cursor: pointer;
transition: all ease 0.6s;
border: 0;
background: none;
padding: 1rem 1rem 2rem 2rem;
}
.nav-container {
position: absolute;
left: -100%;
width: 100%;
height: 100vh;
background: #f5f5f1;
z-index: 5;
}
<header class="header">
<button type="button" class="menu-open"><img src="./images/menu.svg" alt=""></button>
<div class="nav-container">
<button type="button" class="menu-close"><img src="./images/close.svg" alt=""></button>
<div class="menu__wrapper">
<div class="socials">
<img src="./images/logo.png" alt="" class="logo" title="">
</div>
<nav class="menu">
<div class="menu__item">
<a class="menu__item-link">menu</a>
</div>
<div class="menu__item">
<a class="menu__item-link">menu</a>
</div>
<div class="menu__item">
menu
</div>
<div class="menu__item">
<a class="menu__item-link">menu</a>
</div>
<div class="menu__item">
<a class="menu__item-link">menu</a>
</div>
</nav>
</div>
</div>
</header>
doesn't help.

I think your main body elements are positioned static (or relative if defined?), untill you change it by overriding with position fixed.
A better behaviour would be to leave your nav container be positioned absolute on "menuOpen" and leave the remainder of elements in their already defined flow so your full screen simply overlay's the rest of the elements.

Related

How do I get a menu to go on top of everything?

I am trying to have a menu that takes up 100vh when the menu button is clicked. However, I also have a header at the top so the menu content is lower than it. How do I make the menu go on top of the header? I'm trying to do this without making the header display: none because I want it to be shown on the side - in the left over space from making the menu have a view width of 80vw.
header {
height: 3.4rem;
display: grid;
align-items: center;
z-index: 1;
}
.menu {
z-index: 2;
position: relative;
background-color: #000;
margin-left: 4rem;
}
.menu-container {
width: 80vw;
height: 100vh;
margin-left: 2.5rem;
margin-top: 2rem;
}
<header>
<div class="header-container">
<div class="left">
<img src="img/logo.jpg" alt="">
</div>
<div class="right">
<img src="img/user.png" alt="">
<i class="fa-solid fa-bars fa-xl"></i>
</div>
</div>
</header>
<nav class="menu">
<div class="menu-container">
<div class="top-menu">
Premium
Support
Download
<div class="menu-line"></div>
</div>
<div class="bottom-menu">
Account
Log out
</div>
<img src="img/logo.jpg" alt="">
</div>
</nav>
(I did not add all the CSS to do with the menu and header because the rest of it is irrelevant.)
How do I move the menu to go on top?
I think position: relative is not set properly, it should only be on a parent that contains both header and nav. And then set the following css :
.menu {
position: fixed;
top: 0;
left: 0;
height: 100vh;
width: 80vw;
}
Add margin and background if you want.
Now nav should be above header.
I believe the issue lies in the position and z-index of your .menu and header css. Try making the position: absolute for both absolute and change the z-index of menu to 1 and header to 2 so that it shows menu on top of header.
Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/z-index

Animate nav to move with another nav

I have a script in PHP where i'm defining the menus and navbars of the website. I have a top menu that when you scroll down the page, it gets fixed to the top of the page. I want to have a second menu on the left "glued" to the top menu. The way I have done it, it goes well when the top menu reaches the top of the page, it gets fixed with the left menu like I want. The problem is that if the top menu doesnt reach the top of the page (like if it's just a little bit of scroll), the left menu doesnt get stick to the top menu.
The top menu is the one that has "Inicio", "Instrucciones" etc. The left menu is the one that has "Nueva cata", "Nueva cerveza", etc.
This is the page at the beginning (0 scroll).
This is the page after the top menu reaches the top of the page (>200 scroll).
This is the page before the top menu reaches the top of the page (0 < scroll < 200).
As you can see in the third page, the left menu goes down with the scroll instead of going up with the top menu.
This is HTML:
<nav class="navbar navbar-expand-lg navbar-light bg-light" id="menu_arriba">
<div class="navbar-brand" style="width: 200px;"></div>
<a href="user.php" class="navbar-brand">
<p>Inicio</p>
</a>
<a href="instrucciones.php" class="navbar-brand">
<p>Instrucciones</p>
</a>
<a href="contacto.php" class="navbar-brand">
<p>Contacto</p>
</a>
<a href="faq.php" class="navbar-brand">
<p>FaQ</p>
</a>
<a href="ajax/logout.php" class="navbar-brand">
<p><i class="fas fa-sign-out-alt"></i> Salir</p>
</a>
</nav>
<nav id="menu_izq" class="sidenav">
<div></div>
<a href="nueva_cata.php">
<p>Nueva Cata</p>
</a>
<a href="nueva_cerveza.php">
<p>Nueva Cerveza</p>
</a>
<a href="cata.php">
<p>Mis catas</p>
</a>
<a href="mis_cervezas.php">
<p>Mis cervezas</p>
</a>
<a href="mis_amigos.php">
<p>Mis amigos</p>
</a>
</nav>
This is CSS:
#menu_izq {
height: 100%;
width: 200px;
position: fixed;
left: 0;
top: 252px;
z-index: 3;
background-color: #503522;
overflow-x: hidden;
padding-top: 20px;
}
#menu_arriba{
background-color: #503522;
width: 100%;
z-index: 1;
}
This is my JQuery:
$(window).scroll(function(){
var elementPosition = $('#menu_arriba').offset();
if($(window).scrollTop() >= elementPosition.top){
$('#menu_arriba').css('position','fixed').css('top','0');
$("#menu_izq").css('position','fixed').css('top', '35');
} else {
$('#menu_arriba').css('position','initial');
}
if(elementPosition.top <= 200){
$('#menu_arriba').css('position','initial').css('top', '200');
$("#menu_izq").css('top', '250');
}
});
I know the problem is in the JQuery method but i don't get to write what I want. Thank you very much.
----- EDIT
The way I'm doing my website is with a menus.php where I write the top and left menu like this
<?php function izquierda() { ?>
<nav id="menu_izq" class="sidenav">
<div></div>
<p>Nueva Cata</p>
<p>Nueva Cerveza</p>
<p>Mis catas</p>
<p>Mis cervezas</p>
<p>Mis amigos</p>
</nav>
<?php } ?>
<?php function arriba() { ?>
<nav class="navbar navbar-expand-lg navbar-light bg-light"
id="menu_arriba">
<div class="navbar-brand" style="width: 200px;"></div>
<p>Inicio</p>
<a href="instrucciones.php" class="navbar-brand"><p>Instrucciones</p>
</a>
<p>Contacto</p>
<p>FaQ</p>
<div class="navbar-brand" style="width: 450px;"></div>
<a href="ajax/logout.php" class="navbar-brand"><p><i class="fas fa-sign-
out-alt"></i> Salir</p></a>
</nav>
So in the actual pages of the website, i just write:
<?php echo banner(); ?>
<?php echo arriba(); ?>
<?php echo izquierda(); ?>
<div class="main">
// HERE GOES THE CONTENT OF THE PAGE
</div>
I edit this to make you know that the reason of menu_izq is position: fixed is because like that, it shows the content of the page to the right of the left menu, and in position: sticky||relative, the content is shown at the end of the menu. I need to find a solution without changing (I think) the position: fixed of the menu_izq (left menu).
Looks like you are using Bootstrap. Currently, your left nav is initially set to position: fixed, I recommend using position: relative to your left nav initially so that positioning your nav elements can be relative to the height of the background image. Using Bootstrap, this solution wraps the left nav & the content in a flex container so that the content can be positioned relative to this container easily, since later on the navs are going to get position: fixed.
Basically on the script, just detect if the top of the scroll bar's Y position is already past the height of the background image element. If it is, assign the fixed position to the nav elements and adjust the content's position as needed relative to the container wrapping the left nav & the content. Check the CSS properties involving .navs-are-fixed to see how the navs are assigned the fixed position.
$(window).scroll(function() {
// innerHeight is used to include any padding
var bgImgHeight = $('.some-bg-img').innerHeight();
// if the the scroll reaches the end of the background image, this is when you start to assign 'fixed' to your nav elements
if ($(window).scrollTop() >= bgImgHeight) {
$('body').addClass("navs-are-fixed");
} else {
$('body').removeClass("navs-are-fixed");
}
});
#menu_izq {
height: 100%;
width: 200px;
position: relative;
left: 0;
top: 0;
z-index: 3;
background-color: #503522;
overflow-x: hidden;
padding-top: 20px;
}
#menu_arriba {
background-color: #503522;
width: 100%;
z-index: 1;
position: relative;
top: 0;
}
body {
background-color: #ffc75a !important;
height: 300vh; /* sample arbitrary value to force body scrolling */
}
.some-bg-img {
background: url(https://via.placeholder.com/1920x200.png?text=Sample%20Background%20Image);
height: 200px;
background-repeat: no-repeat;
background-size: cover;
background-position: bottom;
}
.navs-are-fixed #menu_arriba {
position: fixed;
}
.navs-are-fixed #menu_izq {
position: fixed;
top: 72px; /* the height of your top nav */
}
.navs-are-fixed .some-sample-content {
position: absolute;
top: 72px; /* the height of your top nav */
left: 200px; /* the width of your left nav */
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<body>
<div class="some-bg-img"></div>
<nav class="navbar navbar-expand-lg navbar-light bg-light" id="menu_arriba">
<div class="navbar-brand"></div>
<a href="user.php" class="navbar-brand">
<p>Inicio</p>
</a>
<a href="instrucciones.php" class="navbar-brand">
<p>Instrucciones</p>
</a>
<a href="contacto.php" class="navbar-brand">
<p>Contacto</p>
</a>
<a href="faq.php" class="navbar-brand">
<p>FaQ</p>
</a>
<a href="ajax/logout.php" class="navbar-brand">
<p><i class="fas fa-sign-out-alt"></i> Salir</p>
</a>
</nav>
<div class="d-flex h-100 w-100 position-absolute">
<nav id="menu_izq" class="sidenav">
<div></div>
<a href="nueva_cata.php">
<p>Nueva Cata</p>
</a>
<a href="nueva_cerveza.php">
<p>Nueva Cerveza</p>
</a>
<a href="cata.php">
<p>Mis catas</p>
</a>
<a href="mis_cervezas.php">
<p>Mis cervezas</p>
</a>
<a href="mis_amigos.php">
<p>Mis amigos</p>
</a>
</nav>
<div class="some-sample-content">
<p>Lorem Ipsum</p>
<p>Lorem Ipsum</p>
<p>Lorem Ipsum</p>
<p>Lorem Ipsum</p>
<p>Lorem Ipsum</p>
<p>Lorem Ipsum</p>
<p>Lorem Ipsum</p>
<p>Lorem Ipsum</p>
<p>Lorem Ipsum</p>
<p>Lorem Ipsum</p>
<p>Lorem Ipsum</p>
<p>Lorem Ipsum</p>
<p>Lorem Ipsum</p>
</div>
</div>
</body>
If you really must keep your fixed positioning on your left nav, then you are going to have to compute it's top value based on on the height of both the banner & the top nav, such that if the top of scroll bar's Y position is past the height of the banner, the top value of the left nav will be equal to the height of the top nav - so you push it down so that they don't overlap. If the top of the scroll bar's Y position is not past the height of the banner, the top value of the left nav is going to be equal to the difference of the height of the banner & the top nav minus the top of the scroll bar's Y position.
$(window).scroll(function() {
// innerHeight is used to include any padding
var bgImgHeight = $('.some-bg-img').innerHeight();
var topNavHeight = $('#menu_arriba').innerHeight();
var leftNavInitialCssTop = bgImgHeight + topNavHeight;
// if the the scroll reaches the end of the background image, this is when you start to assign 'fixed' to the top nav
if ($(window).scrollTop() >= bgImgHeight) {
$('body').addClass("navs-are-fixed");
$("#menu_izq").css("top", topNavHeight);
} else {
$('body').removeClass("navs-are-fixed");
$("#menu_izq").css("top", leftNavInitialCssTop - $(window).scrollTop())
}
});
#menu_izq {
height: 100%;
width: 200px;
position: fixed;
left: 0;
top: 252px;
z-index: 3;
background-color: #503522;
overflow-x: hidden;
padding-top: 20px;
}
#menu_arriba {
background-color: #503522;
width: 100%;
z-index: 1;
top: 0;
}
body {
background-color: #ffc75a !important;
height: 400vh; /* sample arbitrary value to force body scrolling */
}
.some-bg-img {
background: url(https://via.placeholder.com/1920x200.png?text=Sample%20Background%20Image);
height: 179px;
background-repeat: no-repeat;
background-size: cover;
background-position: bottom;
}
.navs-are-fixed #menu_arriba {
position: fixed;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<div class="some-bg-img"></div>
<nav class="navbar navbar-expand-lg navbar-light bg-light" id="menu_arriba">
<div class="navbar-brand"></div>
<a href="user.php" class="navbar-brand">
<p>Inicio</p>
</a>
<a href="instrucciones.php" class="navbar-brand">
<p>Instrucciones</p>
</a>
<a href="contacto.php" class="navbar-brand">
<p>Contacto</p>
</a>
<a href="faq.php" class="navbar-brand">
<p>FaQ</p>
</a>
<a href="ajax/logout.php" class="navbar-brand">
<p><i class="fas fa-sign-out-alt"></i> Salir</p>
</a>
</nav>
<nav id="menu_izq" class="sidenav">
<div></div>
<a href="nueva_cata.php">
<p>Nueva Cata</p>
</a>
<a href="nueva_cerveza.php">
<p>Nueva Cerveza</p>
</a>
<a href="cata.php">
<p>Mis catas</p>
</a>
<a href="mis_cervezas.php">
<p>Mis cervezas</p>
</a>
<a href="mis_amigos.php">
<p>Mis amigos</p>
</a>
</nav>
You should be able to have that working with just CSS and no javascript using position: sticky attribute.
Make both elements position: sticky, the top nav should have a top: 0 property and the side nav should have a top: x property where x is the height of the top nav.
That should be enough and you should be able to remove the js code.
Read more about sticky position here https://developer.mozilla.org/en-US/docs/Web/CSS/position
why you want to do this? you can move the top menu and side menu and text container together in one container to be relative with each other, set the text box container fixed height in percent and set its overflow-y to auto. make the whole container animatable like the top menu. this will solve your problem.
The side and top sliding <nav> elements cannot interact correctly with the page content. Especially the lateral <nav> with vertical sliding according to many changing rules - sit, follow, slide against, stick apart. It's too much at once.
Workaround 1 - smooth - top sliding, side fixed (anchors corrected)
I'm afraid this is not the solution to your dreams. Works smooth and easy as it avoids the crush point.
$(window).scroll(function(){
var elementPosition = $('#menu_arriba').offset();
if($(window).scrollTop() >= elementPosition.top){
$('#menu_arriba').css('position','fixed').css('top','0');
} else {
$('#menu_arriba').css('position','relative'); /* fixed */
}
if(elementPosition.top <= 200){
$('#menu_arriba').css('position','initial').css('top', '200');
}});
*{ box-sizing: border-box}
body{
margin: 0;
text-align: center;
z-index: -1;
}
#pilar{ /* added fix */
background: #503522;
width: 200px;
position: fixed;
top: 0;
left: 0;
bottom: 0;
z-index: -1
}
#menu_izq {
background: 0; /* fixed */
width: 200px; /* padding-top: 200px; removed */
position: fixed;
top: 200px; /* fixed */
left: 0;
bottom: 0;
z-index: 0; /* fixed */
}
#menu_arriba{
background: #503522;
width: 100%;
position: relative; /* added fix */
z-index: 1; /* added fix */
}
p{ margin: 100px 100px 100px 250px; z-index: -1 }
a{ display: inline-block; width: 150px; border: 1px solid white; text- align: center; padding: 10px 0; margin: 20px}
img{ border-bottom: 10px solid #503522; margin: 0 0 -3px; width: 100%; height: 200px; z-index: 1; z-index: 9;}
<img src="img/blue.jpg" alt="blue">
<div id="pilar"></div> <!-- added fix -->
<nav class="navbar navbar-expand-lg navbar-light bg-light" id="menu_arriba">
<div class="navbar-brand" ></div> <!-- needed or redundancy? -->
Inicio
Instrucciones
Contacto
FaQ
<i class="fas fa-sign-out-alt"></i>Salir
</nav>
<nav class="sidenav" id="menu_izq">
Nueva Cata
Nueva Cerveza
Mis catas
Mis cervezas
Mis amigos
</nav><p>... </p><p> ...</p>
Workaround 1.1 - smooth with a nice view
only changes
#menu_arriba{
background: 0;
width: 100%;
position: relative; /* added fix */
z-index: 0 /* added fix */
}
#hole{
background: #503522;
height: 100%;
margin-left: 200px;
width: auto;
}
<div id="pilar"></div> <!-- added fix -->
<nav class="navbar navbar-expand-lg navbar-light bg-light" id="menu_arriba">
<div id="hole">
<div class="navbar-brand" ></div>
Inicio
Instrucciones
Contacto
FaQ
<i class="fas fa-sign-out-alt"></i> Salir
</div></nav>
Workaround 2 - dirty - hide or cover up side effects
If you still insist - not so smooth, slightly bouncy menu. Your dreams are also not coming true, but there are no visible holes. Here you have it:
$(window).scroll(function(){
var elementPosition = $('#menu_arriba').offset();
if($(window).scrollTop() >= elementPosition.top){
$('#menu_arriba').css('position','fixed').css('top','0');
$('#menu_izq').css('position','fixed').css('top','0');
} else {
$('#menu_arriba').css('position','initial');
$('#menu_izq').css('position','initial');
}
if(elementPosition.top <= 200){
$('#menu_arriba').css('position','initial').css('top', '200');
$('#menu_izq').css('position','initial').css('top', '200');
}});
*{ box-sizing: border-box}
body{
margin: 0;
text-align: center;
}
#menu_izq {
background: 0;
height: auto;
width: 200px;
padding-top: 100px;
}
#menu_arriba{
background: #503522;
width: 100%;
z-index: 1
}
#pilar{
background: #503522;
width: 200px;
position: fixed;
top: 0;
left: 0;
bottom: 0;
z-index: -1
}
p { margin: 100px 300px; position: relative; bottom: 400px}
a{ display: inline-block; width: 150px; border: 1px solid white; text-align: center; padding: 10px 0; margin: 20px}
img{ border-bottom: 10px solid #503522; margin: 0 0 -3px; width: 100%; height: 200px;}
<img src="img/blue.jpg" alt="blue">
<div id="pilar"></div>
<nav class="navbar navbar-expand-lg navbar-light bg-light" id="menu_arriba">
<div class="navbar-brand" ></div> <!-- what for it is? needed? -->
Inicio
Instrucciones
Contacto
FaQ
<i class="fas fa-sign-out-alt"></i>Salir
</nav>
<nav class="sidenav" id="menu_izq">
Nueva Cata
Nueva Cerveza
Mis catas
Mis cervezas
Mis amigos
</nav><p>... </p><p> ...</p>
There are other minor shortcomings in your code.
<p> .... </p> may not be a crime, but neither is it good. <p> has its own characteristics and is not a stiffener or pillar - I fixed it with css.
Above you have whole code I used - as a hint and explanation. Resize elements to your needs and taste. Hope you like it
cheers

Scrolling fixed header not showing on mobile device

I have a fixed header that changes to a sticky header on scroll using JS.
The dropdown menu works when in mobile view showing on Google Dev Tools and Firefox Responsive Design Mode, however it doesnt work on actual mobile devices.
I've tried changing the Z-index and webkit-backface-visibility.
The HTML:
<header id="myHeader" class="site-header" role="banner">
<div class="nav-container">
<nav id="top-bar">
<div class="row" id="top-bar">
<div class="top-bar-text">
</div>
</div>
</nav>
<nav id="site-navigation" class="main-navigation" role="navigation">
<div class="container nav-bar">
<div class="row">
<div class="module left site-title-container">
<?php shapely_get_header_logo(); ?>
</div>
<div class="module widget-handle mobile-toggle right visible-sm visible-xs">
<i class="fa fa-bars"></i>
</div>
<div class="module-group right">
<div class="module left">
<?php shapely_header_menu(); // main navigation ?>
</div>
<!--end of menu module-->
</div>
<!--end of module group-->
</div>
</div>
</nav><!-- #site-navigation -->
</div>
</header>
header {
height: 85px;
left: 1em;
position: fixed;
z-index: 10000;
right: 1em;
top: 40px;
}
JS changes the header on scroll to:
.sticky {
position: fixed;
top: 0;
left: 0;
width: 100%;
background: #f8b836;
z-index: 999;
height: 90px;
overflow: hidden;
-webkit-transition: height 0.3s;
-moz-transition: height 0.3s;
transition: height 0.3s;
}
The CSS for the menu in mobile view:
#media (min-width:300px) and (max-width:480px){
#site-navigation .module.left {
padding-left: 0px;
position: fixed;
left: 0;
}
}
The JS:
window.onscroll = function() {myFunction()};
var header = document.getElementById("myHeader");
var sticky = header.offsetTop;
function myFunction() {
if (window.pageYOffset > sticky) {
header.classList.add("sticky");
} else {
header.classList.remove("sticky");
}
}
I'd like the dropdown menu to actually show when the page has been scrolled and the sticky heading is showing.
Does the dropdown not open on mobile devices?
Your .sticky css class has overflow: hidden; which is keeping the dropdown hidden. If you put it there to avoid horizontal scrolling, use overflow-x: hidden; instead. Then it won't cut the dropdown off.
Generally you want overflow-y set to scroll when you have a fixed element with a dropdown on mobile. In case the menu extends beyond the bottom of the screen.

How can I implement this horizontal search result bar?

I essentially have a horizontal div that populates content from omdb API. It dynamically generates a bunch of search results, and displays them all; however the overflow: hidden is active.
I have 2 questions:
I have two custom "buttons" that I made with an empty div and icon. I gave it a bit of a box-shadow to give it the illusion that it's hovering. Is it better practice to use a button element instead, or does it matter?
My main question is this: I want to be able to navigate back and forth between my search results using my arrow buttons. What would be the best way to implement this? The only thing I can think of is using the buttons to adjust the left or right margins of my search results. (ie. pressing the left button would adjust the margin-left of my results with a negative margin, and the right arrow would adjust it with a positive margin)
However, this feels crude and not very accurate. Meaning with a few extra clicks, the content could be pushed out of the view entirely (either by accident or on purpose).
Is there a way to set this up more efficiently?
Here is some code as an example:
const leftArrow = document.querySelector("#left-arrow");
const rightArrow = document.querySelector("#right-arrow");
const marginSelector = document.querySelector("#nav-margin");
var marginValue = -20;
leftArrow.addEventListener('click', () => {
marginSelector.style.marginLeft = marginValue + "px";
marginValue += -20;
});
.scrollbar-container {
width: 800px;
display: flex;
border: 1px #5e9af9 solid;
position: relative;
top: 100px;
overflow: hidden;
margin: auto;
align-items: center;
}
.result-container {
display: inline-block;
margin: 2px;
}
img {
display: inline-block;
vertical-align: middle;
position: relative;
}
.nav-button {
position: absolute;
width: 50px;
height: 50px;
background: rgba(230, 232, 237, .5);
text-align: center;
margin: auto 0;
}
.left-arrow {
left: 1%;
}
.right-arrow {
right: 1%;
}
.margin-start {}
<script src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
<div class="scrollbar-container">
<div id="nav-margin" class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div id="left-arrow" class="nav-button left-arrow">
<i class="fas fa-angle-left fa-3x"></i>
</div>
<div id="left-arrow" class="nav-button right-arrow">
<i class="fas fa-angle-right fa-3x"></i>
</div>
</div>
I've written script to move back and forth the search results. You just need to check and adjust the marginLeft value for your marginSelector. I've added transition into the CSS of #nav-margin so that it looks smooth. marginValue is been initialized with 0. max-width of container has been set to 500px for convenience. When you change your max-width do not forget to change it in addEventListener for rightArrow. You can also make the value inside if condition to dynamic so that it actually takes the value from .scrollbar-container.
Let me know if you have any queries.
const leftArrow = document.querySelector("#left-arrow");
const rightArrow = document.querySelector("#right-arrow");
const marginSelector = document.querySelector("#nav-margin");
var marginRightValue = 0;
rightArrow.addEventListener('click', () => {
if(-(marginRightValue) <= (500+20))
marginRightValue += -100;
marginSelector.style.marginLeft = marginRightValue + "px";
});
leftArrow.addEventListener('click', () => {
if(marginRightValue < 0)
marginRightValue += 100;
marginSelector.style.marginLeft = marginRightValue + "px";
});
.scrollbar-container {
max-width: 500px;
display: flex;
border: 1px #5e9af9 solid;
position: relative;
top: 100px;
overflow: hidden;
margin: auto;
align-items: center;
}
#nav-margin{
transition: all 1s;
}
.result-container {
display: inline-block;
margin: 2px;
}
img {
display: inline-block;
vertical-align: middle;
position: relative;
}
.nav-button {
position: absolute;
width: 50px;
height: 50px;
background: rgba(230, 232, 237, .5);
text-align: center;
margin: auto 0;
cursor: pointer;
}
.left-arrow {
left: 1%;
}
.right-arrow {
right: 1%;
}
.margin-start {}
<script src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
<div class="scrollbar-container">
<div id="nav-margin" class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div id="left-arrow" class="nav-button left-arrow">
<i class="fas fa-angle-left fa-3x"></i>
</div>
<div id="right-arrow" class="nav-button right-arrow">
<i class="fas fa-angle-right fa-3x"></i>
</div>
</div>
I'm not entirely sure if this would be the best response, but:
Point 1 - I don't think it matters here. A <button> is meant for a form, from a semantics point of view. For more context, read: https://css-tricks.com/use-button-element/
Point 2 - I can already scroll/swipe from left to right (in your code demo when I run the snippet), using my mouse/trackpad. So having extra buttons to do that job seems unnecessary. I would think rather to make a Javascript carousel (or slider) like effect when clicking the right button takes me to the next "slide", or the next chunk of your results. You could then disable buttons when there is no more content on the right (or left), or have them cycle back to the beginning. Effectively you want to think of a fixed width "slide" window (responsive for different viewports) and "slide" accordingly. Does that make sense for your problem?

sticky div in page header overlapping page content

I have a "sticky" div that starts in an absolute position and then switches to fixed at top: 0 once the window begins to scroll (I am using it as a navigation bar), but I also have "in-page" links.
My problem is that the sticky overlaps the other content in the body, in other words the top 200px (the size of the navbar) become hidden (beneath the sticky navbar) as soon as they begin to scroll down.
Is this a CSS problem or a JavaScript problem? How can I fix it?
http://jsfiddle.net/b26g1ztu/
javascript:
function sticky_relocate() {
var window_top = $(window).scrollTop();
var div_top = $('#sticky-anchor').offset().top;
if (window_top > div_top) {
$('#sticky').addClass('stick');
} else {
$('#sticky').removeClass('stick');
}
}
$(function () {
$(window).scroll(sticky_relocate);
sticky_relocate();
});
HTML:
<!--navigation with logos-->
<div id="sticky-anchor"></div>
<div id=sticky>
<a href="#lccpost">
<img alt="lansing" src="https://pbs.twimg.com/profile_images/558329813782376448/H2cb-84q_reasonably_small.jpeg">
</a>
</div>
<!--Articles-->
<!--Nav pics-->
<section>
<div id=lcc1>
<a name="lccpost"><img alt="lansing" src="https://pbs.twimg.com/profile_images/558329813782376448/H2cb-84q_reasonably_small.jpeg"></a>
</div>
</section>
<!--titles-->
<section>
<div id=submissions><h2>Submissions</h2></div>
<!--single submissions-->
<div class=name>
<h3>John Doe</h3>
</div>
<div class=subs>
<a href="submissions/1.%20News%20Story/The%20Lookout_News%20Story_Shelby%20Schueller.pdf" target=_blank>
<img src="http://www.wolfson.org.uk/media/1187/pdf_icon.png" /></a>
</div>
<div class=judgesub>
<!--<a href="">
<img src="pictures/PDF_Logo.jpg" /></a>-->
</div>
<!---->
<div class=name>
<h3>Jane Doe</h3>
</div>
<div class=subs>
<a href="submissions/1.%20News%20Story/The%20Lookout_News%20Story_Sarah%20Spohn.pdf" target=_blank>
<img src="http://www.wolfson.org.uk/media/1187/pdf_icon.png" /></a>
</div>
<div class=judgesub>
<!--<a href="">
<img src="pictures/PDF_Logo.jpg" /></a>-->
</div>
<!---->
<div class=name>
<h3>Jason Doe</h3>
</div>
<div class=subs>
<a href="submissions/1.%20News%20Story/The%20Lookout_News%20Story_Jeremy%20Kohn.pdf" target=_blank>
<img src="http://www.wolfson.org.uk/media/1187/pdf_icon.png" /></a>
</div>
<div class=judgesub>
<!--<a href="">
<img src="pictures/PDF_Logo.jpg" /></a>-->
</div>
CSS:
body
{
background-color: RGB(95,0,0);
}
#sticky
{
position:absolute;
top:150px;
background-color: RGB(65,0,0);
color:White;
border-style:solid;
border-color:RGB(255,215,0);
padding: 5px;
width: 500px;
height: 150px;
overflow: hidden;
overflow-y: scroll;
}
#sticky.stick {
position: fixed;
top: 0px;
bottom:auto;
z-index: 10000;
}
#lcc1
{
position:absolute;
top: 350px;
left: 20px;
}
#submissions
{
position:absolute;
top: 320px;
left: 240px;
color:White;
}
.name
{
position:relative;
top:400px;
left: 150px;
color:White;
}
.subs
{
display:inline-block;
position:relative;
top: 330px;
left: 270px;
border-style: dashed;
border-color:Red;
padding:5px;
}
I think your problem is a bit JS and a bit CSS.
You're using JS/JQuery to toggle between two CSS classes and essentially toggling between absolute and fixed positioning. Further you are using top to make your decisions in JS, but they evaluate to different values when you are in absolute or fixed positioning.
Finally, i'd recommend that you either (a) just stick with fixed positioning and adjust the location (top/left) onscroll or (b) when you are in .stick mode add padding-top:300px to the body or margin-top:300px on body section:first-child

Categories

Resources