Transition going only one way when removing class - javascript

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>

Related

css transition not working after calling jQuery function trying to change the DOM

I want to make tarot games. When the user click the card, the size of the card scales and the position of the card moves to the center of the screen. So I want to add a parent div on .flipping-card element after click event by calling jQuery wrap() function. Here's my js code:
Before I add this line: $(this).wrap("<div class='h-modal-bg'></div>");
The tarot cards flip transition effect works perfectly. But after adding that line, the transition effect just disappeared. Can somebody tell me what's wrong with this code? Thank you! (When you run my code on snippets, it's better to resize the screen size to the mobile
$(function() {
$('.h-flipping-card').click(function(){
$(this).toggleClass('card-flipped');
$(this).closest('.card-frame').wrap("<div class='h-modal-bg h-modal-bg-show'></div>");
});
});
*, *:before, *::after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.h-flipping-card {
position: relative;
width: 96%;
height: 0;
padding-bottom: 144%;
display: block;
margin: 0 auto;
perspective: 1000px;
}
.h-flipping-card-content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform 0.8s;
}
.h-flipping-card-front, .h-flipping-card-back {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border-radius: 18px;
box-shadow: 2px 1px 15px #8A8A8A;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.h-flipping-card-front {
transform: rotateY(180deg);
}
.h-flipping-card-back {
background-color: brown;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
.h-flipping-card-front[data-tarot-opt='demo1'] {
background-color: orange;
background-size: 130% auto;
background-repeat: no-repeat;
background-position: center;
}
.h-flipping-card.card-flipped .h-flipping-card-content {
transform: rotateY(180deg);
}
.h-modal-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(33, 33, 33, 0.48);
z-index: 10000;
visibility: hidden;
display: flex;
flex-direction: column;
justify-content: center;
opacity: 0;
-webkit-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
}
.h-modal-bg-show {
visibility: visible;
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<div class="card-frame" style="max-width: 320px; width: 50%; display: inline-block;">
<div class="h-flipping-card">
<div class="h-flipping-card-content">
<div class="h-flipping-card-back"></div>
<div class="h-flipping-card-front" data-tarot-opt="demo1"></div>
</div>
</div>
</div>
</div>
This is because when you call $.wrap(), your original element is removed from the DOM, and then appended again.
Doing so, its computed style gets set directly to the one set by the class .card-flipped, and there is nothing to transition anymore, since for the CSS engine it's already in this flipped state.
You can see this related Q/A which explains a very similar situation.
The solution is thus to first wrap your element, then force a reflow so the CSS engine knows what's the current computed style of your element, and finally change its class, so the transition happens.
$(function() {
$('.h-flipping-card').click(function(){
// first DOM manip
$(this).closest('.card-frame').wrap("<div class='h-modal-bg h-modal-bg-show'></div>");
document.body.offsetWidth; // force recalc
$(this).toggleClass('card-flipped'); // now ask for transition
});
});
$(function() {
$('.h-flipping-card').click(function(){
$(this).closest('.card-frame').wrap("<div class='h-modal-bg h-modal-bg-show'></div>");
document.body.offsetWidth;
$(this).toggleClass('card-flipped');
});
});
*, *:before, *::after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.h-flipping-card {
position: relative;
width: 96%;
height: 0;
padding-bottom: 144%;
display: block;
margin: 0 auto;
perspective: 1000px;
}
.h-flipping-card-content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform 0.8s;
}
.h-flipping-card-front, .h-flipping-card-back {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border-radius: 18px;
box-shadow: 2px 1px 15px #8A8A8A;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.h-flipping-card-front {
transform: rotateY(180deg);
}
.h-flipping-card-back {
background-color: brown;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
.h-flipping-card-front[data-tarot-opt='demo1'] {
background-color: orange;
background-size: 130% auto;
background-repeat: no-repeat;
background-position: center;
}
.h-flipping-card.card-flipped .h-flipping-card-content {
transform: rotateY(180deg);
}
.h-modal-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(33, 33, 33, 0.48);
z-index: 10000;
visibility: hidden;
display: flex;
flex-direction: column;
justify-content: center;
opacity: 0;
-webkit-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
}
.h-modal-bg-show {
visibility: visible;
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<div class="card-frame" style="max-width: 320px; width: 50%; display: inline-block;">
<div class="h-flipping-card">
<div class="h-flipping-card-content">
<div class="h-flipping-card-back"></div>
<div class="h-flipping-card-front" data-tarot-opt="demo1"></div>
</div>
</div>
</div>
</div>
I think the issue is when your click event trigger every time your wrap function is calling and so .card-frame is wrapping inside already wrapped div.
So I think you just want to wrap only once on first click. So I tried something one click function check this
$(function() {
$('.h-flipping-card').click(function(){
$(this).toggleClass('card-flipped');
});
$('.h-flipping-card').one("click", function(){
$(this).closest('.card-frame').wrap("<div class='h-modal-bg h-modal-bg-show'></div>");
});
});
Here is my JSFiddle Link

div sliding from right to full width

Currently, I am building a style guide and I have a question about the transition of an element. Imagine you have a container with two elements besides each other. Both have 50% width. The left element should always be visible, but the right element slides from the right into its 50% width. How can I achieve something like this? I am a bit overwhelmed with the top, bottom, left, right, position:absolute properties.
The html would look like this:
<div class="module-container">
<div class="first-element">
<div class="second-element">
</div>
and the css like this:
.module-container {
display: flex;
}
.first-element {
width: 50%;
}
.second-element {
width: 50%;
}
which properties does the second Element need in the first place? And which should I add via JavaScript after pressing, for instance, a button?
try using jQuery and transitions
$('#btn').click(function() {
$('.secondElement').toggleClass("slide");
});
.moduleContainer {
display: flex;
height: 100px;
overflow: hidden;
}
.firstElement {
position: relative;
width: 50%;
border: 1px solid #000;
}
.secondElement {
position: relative;
width: 50%;
border: 1px solid #000;
left: 100%;
transition: left 1s;
}
.secondElement.slide {
left: 0;
}
#btn {
display: block;
margin-top: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="moduleContainer">
<div class="firstElement"></div>
<div class="secondElement"></div>
</div>
<button id="btn">Click Here</button>
.moduleContainer {
display: flex;
height:100px;
}
.moduleContainer > * {
border:1px solid red;
box-sizing:border-box;
overflow:hidden;
}
.firstElement {
height: 100%;
width: 50%;
}
.secondElement {
height: 100%;
width: 0%;
transition:width 0.3s ease;
}
.moduleContainer:hover .secondElement {
width:50%;
}
<div class="moduleContainer">
<div class="firstElement"></div>
<div class="secondElement"></div>
</div>
I have achieved it with pure CSS.I think it's good to have a bar, so the user can hover it and expand.I hope it will help you.
.moduleContainer{ display: flex;flex-flow: row nowrap; }
.firstElement{ background-color:blueviolet;flex:1;height:100px;position:relative;max-width: 50%; }
.secondElement{ background-color:aqua;height:100px;flex:1;max-width:1%;position:relative;transition:1s ease;left:48%; }
.secondElement:hover{ background-color: chartreuse;left:0px;max-width:50%; }
<div class="moduleContainer">
<div class="firstElement">First Element</div>
<div class="secondElement"></div>
</div>
You can use a negative value for margin-left of the .second-element.
.module-container {
display: flex;
height: 50px;
overflow: hidden;
}
.module-container:hover .second-element {
right: 0;
}
.first-element {
flex: 0 0 50%;
background: #f90;
}
.second-element {
flex: 0 0 50%;
background: #0f9;
right: -50%;
transition: all .6s ease;
position: relative;
}
<div class="module-container">
<div class="first-element"></div>
<div class="second-element"></div>
</div>
Or you can use position: absolute and animate the left property
.module-container {
position: relative;
height: 50px;
overflow: hidden;
}
.module-container:hover .second-element {
right: 0;
}
.first-element {
width: 50%;
background: #f90;
position: absolute;
left: 0;
top: 0;
bottom: 0;
}
.second-element {
background: #0f9;
width: 50%;
position: absolute;
right: -50%;
top: 0;
bottom: 0;
transition: all .6s ease;
}
<div class="module-container">
<div class="first-element"></div>
<div class="second-element"></div>
</div>

anchors overlaying and not properly changing color, because not fully clickable

I'm trying to change the color every image on click but they are not properly selectable because of overlying each other with positioning and z-index...
code is working as you can check by clicking on top right corner it change color...tried different methods of CSS, not JavaScript... newbie in JavaScript.
body,div,p,h1,h2,h3,h4,h5,h6,span {
margin: 0;
}
div.nav {
height: 100px;
width: 100%;
padding: 20px 0;
background-color: #615d5d;
text-align: center;
}
.screens_wrap {
display: inline-block;
margin: 0 auto;
height: 100%;
position: relative;
}
.screen_inner {
position: relative;
height: 100%;
margin: 0 auto;
width: 150px;
}
.screen {
position: absolute;
width:100px;
height: 58px;
border: 3px solid #aeaeae;
}
/* transparent style -------------------------------------------------------------------*/
.nav .screen.screen1 {
bottom: 0;
left: 0;
z-index: 3;
background-color: #00ad63;
}
.nav a .screen.screen2 {
bottom: 15px;
left: 15px;
z-index: 2;
background-color: transparent;
}
.nav a .screen.screen2:hover{
background-color: #4f025a;
}
.nav .screen.screen3 {
bottom: 30px;
left: 30px;
z-index: 1;
background-color: transparent;
}
.nav .screen.screen3:hover{
background-color: #ffec36;
}
.nav .screen2:hover, .screen3:hover {
-webkit-animation-name: hover;
-webkit-animation-duration: 1s;
animation-name: hover;
animation-duration: 4s;
-webkit-animation-fill-mode: forwards;
opacity: 1;
width: 100px;
}
.nav.nav6 {
height: 200px;
}
.screen_inner a.screenanchors:first-child img {
position: absolute;
left: 0;
top: 0;
z-index: 1;
}
.screen_inner a.screenanchors:nth-child(2) img{
position: absolute;
left: 20px;
top: 20px;
z-index: 2;
}
.screen_inner a.screenanchors:nth-child(3) img{
position: absolute;
left: 40px;
top: 40px;
z-index: 3;
}
.screenanchors img {
overflow: hidden;
}
#keyframes spinning {
from {
transform: translateZ(-5em) rotateY(0deg);
}
to {
transform: translateZ(-5em) rotateY(180deg);
}
}
#keyframes skewing {
from {
transform: translateZ(-5em) skew(-3deg, -25deg);
}
to {
transform: translateZ(-5em) skew(-3deg, 0deg);
width: 100%;
height: 100px;
z-index: 9999999;
bottom: 0;
}
}
/* Standard syntax */
#keyframes hover {
0% {
margin-bottom:+10px;
bottom: unset;
}
100% {
margin-bottom:+10px;
bottom: unset;
}
}
<div class="nav nav6" style="margin-top: 25px;">
<div class="screens_wrap">
<div class="screen_inner">
<img id="imgName" src="https://imageshack.com/i/plylrZh4p" onclick="changeSrc()" width="100px">
<img id="imgName1" src="https://imageshack.com/i/pljaZE0Gp" onclick="changeSrc1()" width="100px">
<img id="imgName2" src="https://imageshack.com/i/plm9slyTp" onclick="changeSrc2()" width="100px">
</div>
</div>
</div>
<script>
function changeSrc(){
document.getElementById("imgName").src="https://imageshack.com/i/plm9slyTp";
document.getElementById("imgName1").src="https://imageshack.com/i/plylrZh4p";
document.getElementById("imgName2").src="https://imageshack.com/i/pljaZE0Gp";
}
function changeSrc1(){
document.getElementById("imgName").src="https://imageshack.com/i/pljaZE0Gp";
document.getElementById("imgName1").src="https://imageshack.com/i/plm9slyTp";
document.getElementById("imgName2").src="https://imageshack.com/i/plylrZh4p";
}
function changeSrc2(){
document.getElementById("imgName").src="https://imageshack.com/i/plylrZh4p";
document.getElementById("imgName1").src="https://imageshack.com/i/pljaZE0Gp";
document.getElementById("imgName2").src="https://imageshack.com/i/plm9slyTp";
}
</script>
it should work by clicking every where on single image, no overlay effecting clickable space...
Just to Help out others, I fixed the issue using area mapping...

Div's contents showing with opacity set to 0

I am attempting to get a panel to slide up when a trigger is selected. This is working in my snippet. The issue is that the contents within the #proposal-panel are showing, even though I have #proposal-panel set to opacity: 0, until the trigger is clicked (.active is added). It is showing at the bottom of the page.
Also, for some reason on my actual site, the panel is not sliding up. I have multiple sections, just like the example. The panel just sets at the bottom of the page. The only thing that happens when the active class is added is the z-index takes effect.
I am wanting the panel to slide from the bottom to the top when triggered. That is what I am trying to do with translateYin the active class.
Does anyone know why the contents are showing and possibly why the panel is not sliding up?
Here is a fiddle.
$('#proposal-trigger').on('click', function () {
$('#proposal-panel').addClass('active');
});
#red {
height: 100vh;
width: 100%;
background: red;
}
#blue {
height: 100vh;
width: 100%;
background: blue;
}
#proposal-trigger {
background: #3B3B3B;
width: 100px;
height: 100px;
position: fixed;
bottom: 0;
right: 200px;
}
#proposal-panel {
background: #333333;
width: 58%;
height: 100vh;
position: fixed;
padding: 15px 0;
right: 0;
bottom: -100vh;
opacity: 0;
transition: ease 0.3s;-webkit-transition: ease 0.3s;
}
#proposal-panel.active {
transition: ease 0.3s;-webkit-transition: ease 0.3s;
transform: translateY(0vh);-webkit-transform: translateY(0vh);
bottom: 0;
top: 0;
z-index: 99;
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<section id="red"></section>
<section id="blue"></section>
<div id="proposal-trigger">
<input>
<input>
</div>
<div id="proposal-panel"></div>
Assuming it's the little black box you see at the bottom, that's from #proposal-trigger. #proposal-panel is hidden. I removed the background color from #proposal-trigger to get rid of that.
And to have the element slide up, use transform: translate().
$('#proposal-trigger').on('click', function() {
$('#proposal-panel').addClass('active');
});
#red {
height: 100vh;
width: 100%;
background: red;
}
#blue {
height: 100vh;
width: 100%;
background: blue;
}
#proposal-trigger {
width: 100px;
height: 100px;
position: fixed;
bottom: 0;
right: 200px;
}
#proposal-panel {
background: #333333;
width: 58%;
height: 100vh;
position: fixed;
padding: 15px 0;
right: 0;
opacity: 0;
transition: 0.3s;
transform: translateY(100%);
bottom: 0;
}
#proposal-panel.active {
transform: translateY(0);
z-index: 99;
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section id="red"></section>
<section id="blue"></section>
<div id="proposal-trigger">
<input>
<input>
</div>
<div id="proposal-panel"></div>
You don't need to use translateY to do this animations, just need to use top and bottom with the fixed position. And remove the background-color from #proposal-trigger so it doesn't show anymore
Here is a demo
$('#proposal-trigger').on('click', function () {
$('#proposal-panel').addClass('active');
});
<section id="red"></section>
<section id="blue"></section>
<div id="proposal-trigger">
<input>
<input>
</div>
<div id="proposal-panel"></div>
#red {
height: 100vh;
width: 100%;
background: red;
}
#blue {
height: 100vh;
width: 100%;
background: blue;
}
#proposal-trigger {
width: 100px;
height: 100px;
position: fixed;
bottom: 0;
right: 200px;
}
#proposal-panel {
background: #333333;
width: 58%;
position: fixed;
padding: 15px 0;
right: 0;
bottom: 0;
top: 100%;
opacity: 0;
transition: ease 0.3s;-webkit-transition: ease 0.3s;
}
#proposal-panel.active {
transition: ease 0.3s;-webkit-transition: ease 0.3s;
bottom: 0;
top: 0;
z-index: 99;
opacity: 1;
}

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

Categories