Slideout.js menu isnt smooth - javascript

I have been trying to get slideout.js to work properly for my site.
The issue is that when the menu is opened, the text appears before the fully opens and when the menu is closed, the text disappears after the menu is closed.
I have looked at the CSS and made sure that there are backgrounds to the menu and heights are correctly set.
Demo (view as mobile) - http://stefan.admark.co.uk/gates/index.php
JS:
window.onload = function() {
var slideout = new Slideout({
'panel': document.getElementById('main'),
'menu': document.getElementById('menu'),
'side': 'right',
'padding': 256,
'tolerance': 70
});
document.querySelector('.js-slideout-toggle').addEventListener('click', function() {
slideout.toggle();
});
};
CSS:
.slideout-menu {
position: fixed;
top: 80px;
bottom: 0;
width: 256px;
/* min-height: 100vh; */
overflow-y: auto;
-webkit-overflow-scrolling: touch;
z-index: 999;
display: none;
padding-left:20px;
}
.slideout-menu-left {
left: 0;
}
.slideout-menu-right {
right: 0;
}
.slideout-panel {
position: relative;
z-index: 1;
will-change: transform;
background-color: #ffffff; /* A background-color is required */
min-height: 100%;
-webkit-box-shadow: 6px 0px 5px 0px rgba(0,0,0,0.1);
-moz-box-shadow: 6px 0px 5px 0px rgba(0,0,0,0.1);
box-shadow: 6px 0px 5px 0px rgba(0,0,0,0.1);
}
.slideout-open,
.slideout-open body,
.slideout-open .slideout-panel {
overflow: hidden;
}
.slideout-open .slideout-menu {
display: block;
}
#media screen and (min-width: 1000px) {
.slideout-panel {
/* margin-left: 256px; */
}
.slideout-menu {
display: none;
}
}
.panel:before {
content: '';
display: block;
background-color: rgba(0,0,0,0);
transition: background-color 0.5s ease-in-out;
}
.panel-open:before {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
background-color: rgba(0,0,0,.5);
z-index: 99;
}

It looks like your <nav> element on your page doesn't have any transition CSS on it.
For instance, your <main> element has the following transition applied to it:
transition: -webkit-transform 300ms ease 0s; transform: translateX(-256px)
Whatever javascript you have triggering the transition for your <main> element, if applied to <nav> should cause the text and everything inside <nav> to transition properly as well.

Related

Transition going only one way when removing class

I'm trying to create a sidebar like this:
function show_menu(){
document.querySelector('#sidebar').classList.toggle('sidebar_open');
document.querySelector('#blackscreen').classList.toggle('blackscreen_open');
}
#hamburger {
width: 5rem;
height: 5rem;
background-color: red;
}
#header_wrapper {
display: block;
}
#sidebar {
position: fixed;
top: 0;
right: 0;
width: 0;
height: 100vh;
transition: width 0.25s;
}
.sidebar_open {
width: 50% !important;
background-color: green;
display: grid !important;
}
#blackscreen{
position:fixed;
top:0;
right:0;
width:100vw;
height:100vh;
transition: background-color 0.25s;
}
.blackscreen_open {
background-color: rgba(0, 0, 0, 0.5);
}
<div id="hamburger" onclick="show_menu()">click here</div>
<div id='blackscreen' onclick="show_menu()"></div>
<span id='sidebar'>
</span>
but the sidebar transition only works one way,
My best guess is that the transition requires 2 classes to operate
but since I've removed one class the transition back might not be taking place
so I tried the solution according to this question like this:
function show_menu(){
document.querySelector('#sidebar').classList.toggle('sidebar_open');
document.querySelector('#blackscreen').classList.toggle('blackscreen_open');
}
#hamburger {
width: 5rem;
height: 5rem;
background-color: red;
}
#header_wrapper {
display: block;
}
#sidebar {
position: fixed;
top: 0;
right: 0;
width: 0;
height: 100vh;
}
#sidebar:not(.sidebar_open) {
transition: width 0.25s;
}
.sidebar_open {
width: 50% !important;
background-color: green;
display: grid !important;
}
#blackscreen {
position: fixed;
top: 0;
right: 0;
width: 100vw;
height: 100vh;
transition: background-color 0.25s;
}
.blackscreen_open {
background-color: rgba(0, 0, 0, 0.5);
}
<div id="hamburger" onclick="show_menu()">click here</div>
<div id='blackscreen' onclick="show_menu()"></div>
<span id='sidebar'>
</span>
but as you can see even that didn't work
I'm pretty sure I'm missing something obvious but any & all help is greatly appreciated!
I'm fairly certain that the transition IS working but you're not seeing it because when it's not open, your sidebar doesn't have a background colour, and since you don't have a transition setting for your background attribute, when you remove the sidebar_open class the background colour IMMEDIATELY reverts to none and the width transition becomes invisible.
You should be able to test this by moving background-color: green; from the .sidebar_open class to the #sidebar element.
You need to have the background-color set even when the sidebar is not open. Otherwise, when the class is removed, you can no longer see it even though the width is being animated.
#sidebar {
position: fixed;
top: 0;
right: 0;
width: 0;
height: 100vh;
background-color: green;
transition: width 0.25s;
}
function show_menu() {
document.querySelector('#sidebar').classList.toggle('sidebar_open');
document.querySelector('#blackscreen').classList.toggle('blackscreen_open');
}
#hamburger {
width: 5rem;
height: 5rem;
background-color: red;
}
#header_wrapper {
display: block;
}
#sidebar {
position: fixed;
top: 0;
right: 0;
width: 0;
height: 100vh;
background-color: green;
transition: width 0.25s;
}
.sidebar_open {
width: 50% !important;
display: grid !important;
}
#blackscreen {
position: fixed;
top: 0;
right: 0;
width: 100vw;
height: 100vh;
transition: background-color 0.25s;
}
.blackscreen_open {
background-color: rgba(0, 0, 0, 0.5);
}
<div id="hamburger" onclick="show_menu()">click here</div>
<div id='blackscreen' onclick="show_menu()"></div>
<span id='sidebar'></span>

Header fixed with border - the border should only shown by scrolling

I have coded my index.html with bootstra4 and have the header with border and the class sticky. I want the border only shown when the page is scrolled.
HTML
<!-- TOP NAV -->
<header id="topNav">
<div class="container">
.....
</div>
CSS
#header.shadow-after-3:before {
content: ' ';
position: absolute;
left: 0;
right: 0;
width: 100%;
height: 60px;
bottom: -60px;
background-image: url(../images/misc/shadow3.png);
background-size: 100% 100%;
}
JS
The code of my js will not insert here - if it is nessasary i will try it again
With Javascript you can solve it easily.
$(window).scroll(function() {
if ($(this).scrollTop() > 250){
$('header').addClass("borderClass");
}
else{
$('header').removeClass("borderClass");
}
});
Remove the box-shadow attribute from #header:
Should be like this:
#header {
position: relative;
left: 0;
top: 0;
right: 0;
z-index: 1000;
font-size: 14px;
background-color: #fff;
border-bottom: rgba(0,0,0,0.05) 1px solid;
-webkit-transition: all .800s;
-moz-transition: all .800s;
-o-transition: all .800s;
transition: all .800s;
}
Then change border-bottom attribute in #header.transparent to border-bottom: none;
Should be like this:
#header.transparent {
position: absolute;
background-color: transparent;
border-bottom: none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
Lastly, find and replace #header.shadow-after-3:before to #header.fixed.shadow-after-3:before in your CSS.
When the page is scrolled it adds the fixed class to header element that's why we should style this class.

Fixed menu does not work (menu does not "stick" )

I want to make a fixed menu. However, when it scrolls, the menu does not "stick" to the browser window. When I remove position: relative; with navbar__box the menu is sticky and scrolls, but the transition from sticky to fixed is not smooth...
window.onscroll = function() {myFunction()};
function myFunction() {
if (window.scrollY > 0) {
var parentwidth = $('.header').width();
$('.navbar__box').addClass("fixed").width(parentwidth);
} else {
$('.navbar__box').removeClass('fixed').width(parentwidth);
}
}
.fixed {
background: aliceblue;
box-shadow: 0 1px 7px $black;
position: fixed;
top: 0;
padding-top: 10px;
z-index: 1299;
}
.navbar__box {
position: relative;
transition: all 0.3s ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header class="header" >
<div class="navbar__box">
<div class="navbar">
<nav class="navbar__nav">
<ul id="nav" class="navbar__nav--list">
<li class="navbar__nav--list-item">
Home
</li>
</ul>
</nav>
</div>
</div>
</header>
updated CSS - example fiddle - I just removed the unnecessary position: relative on .navbar__box.
.fixed {
background: red;
box-shadow: 0 1px 7px black;
position: fixed;
top: 0;
padding-top: 10px;
z-index: 1299;
}
.navbar__box {
transition: all 0.3s ease-in-out;
}
Change the order of your css/classes. Looks like .nav__box is overwriting .fixed
.navbar__box {
position: relative;
transition: all 0.3s ease-in-out;
}
.fixed {
background: $aliceblue;
box-shadow: 0 1px 7px $black;
position: fixed;
top: 0;
padding-top: 10px;
z-index: 1299;
}
Fiddle

Center element with animation / transition

I'm trying to create a full screen menu that does a bottom-to-top movement and I'm having trouble when it comes to vertically centering it.
Basically, it comes out of the screen and should end up right in the middle of it (centered).
However, since it is a fixed menu with an unknown height and I'm using animations, the options available aren't many:
I can't use the margin: auto technique because the auto value doesn't work with transitions;
I'm trying to avoid using flexbox;
translateY() seems to work fine but it creates a top-to-bottom movement instead of the desired bottom-to-top one (see my code)
anything else? (preferably that works with older browsers, but I can also manage with using translateY if there's a way to change the direction)
$('#small-nav-btn').click(function() {
$('#overlay').addClass('open');
$('#close-menu-cross').addClass('open');
$('#nav').addClass('open');
})
$('#cross').click(function() {
$('#overlay').removeClass('open');
$('#close-menu-cross').removeClass('open');
$('#nav').removeClass('open');
})
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: "Now-Regular", sans-serif;
font-size: 12px;
font-weight: bold;
}
ul {
list-style-type: none;
}
a {
color: black;
}
#overlay {
background: #fff;
opacity: 0;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 0;
transition: all 1s ease 0s;
z-index: 1555;
}
#overlay.open {
opacity: 1;
height: 100%;
}
#small-nav-bar {
display: block;
width: 80%;
margin: 0 auto;
text-align: center;
color: black;
}
#small-nav-btn {
cursor: pointer;
}
#nav {
background: orange;
position: fixed;
top: -100%; /*I need it to be bottom: -100% for the bottom-top movement*/
left: 50%;
transform: translate(-50%, -50%);
transition: all 0.8s linear 0.1s;
z-index: 1556;
}
#nav.open {
top: 50%; /*Again, I need this to be bottom: 50%*/
}
#close-menu-cross.open {
display: block;
position: fixed;
top: 15px;
right: 20px;
z-index: 1556;
cursor: pointer;
}
#close-menu-cross {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="nav-container">
<div id="small-nav-bar">
<div id="small-nav-btn">BUTTON</div>
</div>
<ul id="nav">
<li><span>HELLO</span>
</li>
<li><span>HELLO</span>
</li>
</ul>
<div id="close-menu-cross">
<div id="cross">X</div>
</div>
</nav>
jsfiddle
Thanks in advance! :)
You were quite close. With just a few adjustments in the CSS, you have a full working demo:
$('#small-nav-btn').click(function() {
$('#overlay').addClass('open');
$('#close-menu-cross').addClass('open');
$('#nav').addClass('open');
})
$('#cross').click(function() {
$('#overlay').removeClass('open');
$('#close-menu-cross').removeClass('open');
$('#nav').removeClass('open');
})
#nav {
background: orange;
position: fixed;
top: 100%; /* 1 */
left: 50%;
transform: translate(-50%, 0); /* 2 */
transition: all 0.8s linear 0.1s;
z-index: 1556;
}
#nav.open {
top: 50%;
transform: translate(-50%, -50%); /* 2 */
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: "Now-Regular", sans-serif;
font-size: 12px;
font-weight: bold;
}
ul {
list-style-type: none;
}
a {
color: black;
}
#overlay {
background: #fff;
opacity: 0;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 0;
transition: all 1s ease 0s;
z-index: 1555;
}
#overlay.open {
opacity: 1;
height: 100%;
}
#small-nav-bar {
display: block;
width: 80%;
margin: 0 auto;
text-align: center;
color: black;
}
#small-nav-btn {
cursor: pointer;
}
#close-menu-cross.open {
display: block;
position: fixed;
top: 15px;
right: 20px;
z-index: 1556;
cursor: pointer;
}
#close-menu-cross {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="nav-container">
<div id="small-nav-bar">
<div id="small-nav-btn">BUTTON</div></div>
<ul id="nav">
<li><span>HELLO</span></li>
<li><span>HELLO</span></li>
</ul>
<div id="close-menu-cross">
<div id="cross">X</div>
</div>
</nav>
Notes:
The CSS offset properties (top, bottom, left, right), when applied to absolutely-positioned elements (which includes position: fixed), shift the element x-distance from the respective edge.
You have top: -100% in your code. This puts the element 100% above the top edge.
You then have it shifting to top: 50%. This puts the element halfway inside the container.
Essentially, your animation moves the element a distance of 150%, from above the window to inside it. The movement is top to bottom.
But you want the movement to go from bottom to top.
So start the element all the way at the bottom and off-screen (top: 100%), and have it shift up to halfway inside the container (top: 50%).
The transform: translate() rule simply fine-tunes the centering.
If translateY(-50%) is applied to the primary state (like in your code), it will shift 50% of the nav onto the screen before the transition (demo).
That's why I applied translateY(-50%) only to the transitioned state.
For a complete explanation see my answer here: Element will not stay centered, especially when re-sizing screen
jsFiddle

Fixed header shaking when scrolling down

When I use a fixed header, it's shaking when adding my is-sticky
CSS class. It's starting with top:0; for it's animation when scrolling down. I want it to stay fixed smoothly on top in a way that will not cause noticeable jitter. For Example: http://www.lazada.com.my/
Here is my demo.
$(window).load(function(){
$(window).scroll(function(){
if($(window).scrollTop()>0){
if( ! ($('#scroller').hasClass('is-sticky'))) {
$('#scroller')
.addClass('is-sticky')
.css('top',9)
.animate({
'top': 84
},'1000');
}
} else {
if($('#scroller').hasClass('is-sticky')) {
$('#scroller')
.removeClass('is-sticky')
.css('top',9)
.animate({
'top':84
},1000);
}
}
});
});
body{
height:1000px;
margin:0;
padding:0;
position:relative;
}
#scroller {
position: absolute;
left: 0;
top: 84px;
width: 100%;
z-index: 30;
background:#CCC;
height:20px;
}
#scroller.is-sticky {
position: fixed;
width: 100%;
left: 0;
top: 9px;
margin-top: -31px;
height: 53px;
z-index: 701;
background: #CCC;
opacity: .97;
filter: alpha(opacity = 97);
-webkit-box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.1);
-moz-box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.1);
box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<body>
<div id="scroller">Some controls</div>
</body>
The effect, from the website you linked, is actually quite easy to do.
Firstly, you want your header element to have position: fixed; there is no need to add this dynamically via javascript. It should have this property by default (as it shows in the website you linked).
What they are doing is hiding the top navigation which is within the header at a certain scroll point.
You can use jquery to do this very simply.
DEMO
var $el = $('header .two');
$(window).scroll(function(){
if ($(this).scrollTop() > 200) {
$el.addClass('hide');
} else {
$el.removeClass('hide');
}
});
* {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
}
header {
position: fixed;
top: 0;
left: 0;
width: 100%;
text-align: center;
}
header .one {
height: 20px;
width: 100%;
background: lime;
position: relative;
z-index: 10;
}
header .one.hide {
height: 0;
}
header .two {
background: red;
height: 40px;
position: relative;
z-index: 20;
-webkit-transition: -webkit-transform .25s;
transition: transform .25s;
}
header .two.hide {
-webkit-transform: translateY(-20px);
transform: translateY(-20px);
}
main {
background: lightblue;
height: 1200px;
width: 100%;
padding-top: 60px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<header>
<div class="one">div</div>
<div class="two">fixed</div>
</header>
<main>
content
</main>
<footer>footer</footer>
You have to check .scrollTop when is reached to 84. In addition, you don't need to use jquery .animate function, you can achieve that effect by css transition.
Jsfiddle
You can create a fixed navbar and divide it into two parts vertically and when user scroll just hide the above part with .slideUp() animation and when user again scrolls on top show it with .slideDown() animation.
Here is the code :
$(window).load(function(){
$(window).scroll(function(){
if($(window).scrollTop()>0){
//check if it is visisble
if($('#nav-part-to-hide').is(':visible')) {
//if yes then lets hide it
$('#nav-part-to-hide').slideUp();
}
} else {
if(!$('#nav-part-to-hide').is(':visible')) {
$('#nav-part-to-hide').slideDown();
}
}
});
});
body
{
height:1000px;
}
#sticky-navbar
{
position:fixed;
top:0;
left:0;
width:100%;
height:80px;
}
#nav-part-to-hide
{
height:40px;
width:100%;
background:#333;
color:#fff;
}
#nav-part-stays
{
height:40px;
width:100%;
background:#bbb;
color:#333;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body>
<div id="sticky-navbar">
<div id="nav-part-to-hide">
this conetent hides
</div>
<div id="nav-part-stays">
this conetent stays on page
</div>
</div>
</body>

Categories