Reputation: 141
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:
margin: auto
technique because the auto
value doesn't work with transitions;translateY()
seems to work fine but it creates a top-to-bottom movement instead of the desired bottom-to-top one (see my code) 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><a href="contact.html"><span>HELLO</span></a>
</li>
<li><a href="about.html"><span>HELLO</span></a>
</li>
</ul>
<div id="close-menu-cross">
<div id="cross">X</div>
</div>
</nav>
Thanks in advance! :)
Upvotes: 1
Views: 2658
Reputation: 371133
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><a href="contact.html"><span>HELLO</span></a></li>
<li><a href="about.html"><span>HELLO</span></a></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
Upvotes: 1