I do not get how I should get transition to work in both ways. Any tip?
To ensure the transition works smoothly in both directions, you need to explicitly set the width.
nav.open {
width: 260px;
left: 0;
}
It seems that there is 2 sliders (with different transitions) and the text is not slided. It is altered (2 lines)…
Sorry. I thought that was the look you were going for.
Here is a revised version.
And the code to copy/paste:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sliding Menu</title>
<style>
* {
margin: 0;
font-size: 16px;
}
body {
position: relative;
overflow: hidden;
display: flex;
width: 100vw;
height: 100vh;
}
nav {
z-index: 1;
overflow: hidden;
display: flex;
flex-direction: column;
width: 0;
height: 100%;
font-size: 1.8rem;
font-weight: 300;
color: #505050;
background-color: #fff;
box-shadow: 10px 0 18px -15px rgba(85 85 85 / 70%);
transition: width 1s ease-in-out;
}
nav.open {
width: 260px;
}
main {
display: flex;
flex-direction: column;
width: 100%;
height: 100vh;
margin-left: 0;
background-color: lightgray;
transition: margin-left 1s ease-in-out;
}
button {
cursor: pointer;
width: fit-content;
height: 42px;
margin: 15px;
padding: 0 20px;
font-size: 1rem;
line-height: 42px;
color: white;
text-align: center;
background-color: #900;
border: none;
border-radius: 21px;
}
p {
width: 230px;
padding: 15px;
word-wrap: break-word;
}
</style>
</head>
<body>
<nav>
<p>
Text that should be animated into view.
</p>
</nav>
<main>
<button type="button" id="menu-toggle">
Toggle Menu
</button>
</main>
<script>
function menu() {
document.querySelector("nav").classList.toggle("open");
}
const menuToggle = document.querySelector('#menu-toggle');
const nav = document.querySelector("nav");
menuToggle.addEventListener('click', () => {
nav.classList.toggle('open');
});
</script>
</body>
</html>
Or, to have the <nav>
element animate in and push the <main>
element to the side.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sliding Menu</title>
<style>
* {
margin: 0;
font-size: 16px;
}
body {
position: relative;
overflow: hidden;
display: flex;
width: 100vw;
height: 100vh;
}
nav {
position: absolute;
z-index: 1;
left: -260px;
overflow: hidden;
display: flex;
flex-direction: column;
width: 260px;
height: 100%;
font-size: 1.8rem;
font-weight: 300;
color: #505050;
background-color: #fff;
transition: left 1s ease-in-out;
}
nav.open {
left: 0;
}
main {
display: flex;
flex-direction: column;
width: 100%;
height: 100vh;
margin-left: 0;
background-color: lightgray;
transition: margin-left 1s ease-in-out;
}
main.shifted {
margin-left: 260px;
}
button {
cursor: pointer;
width: fit-content;
height: 42px;
margin: 15px;
padding: 0 20px;
font-size: 1rem;
line-height: 42px;
color: white;
text-align: center;
background-color: #900;
border: none;
border-radius: 21px;
}
p {
width: 230px;
padding: 15px;
word-wrap: break-word;
}
</style>
</head>
<body>
<nav>
<p>
Text that should be animated into view.
</p>
</nav>
<main>
<button type="button" id="menu-toggle">
Toggle Menu
</button>
</main>
<script>
function toggleMenu() {
document.querySelector("nav").classList.toggle("open");
document.querySelector("main").classList.toggle("shifted");
}
const menuToggleButton = document.querySelector('#menu-toggle');
const nav = document.querySelector("nav");
menuToggleButton.addEventListener('click', toggleMenu);
</script>
</body>
</html>
Be careful with your fixed heights as you have given a fixed height to the body and hidden the overflow. That means nothing can be taller than the viewport and will be cut off.
If the page is allowed to scroll then your menu scrolls away also so how will a user activate it?
The answers to these questions will determine what styles to use for those panels.
@James_Hibbard has solved your transition questions though if that’s all you were interested in.
Yes, this was perfect. But there are 3 events that should be addressed.
- Toggle in and out (button)
- Resizing window (hide nav on mobile)
- Hide and show nav above content (mobile)
Here is what I come up with. If anybody can simplify or find something wrong, please…
I’m just about to go offline but if you clarify what you want to happen then I;ll take a look tomorrow
You already have that working so what is it that you need it to do now?
Why are you using loads of JS for this? You can do all that with css and media queries. No JS needed at all. Use a media query or two and hide the nav with css at the widths you require. No need to bother the JS resize event which is a massive resource hog anyway.
Again there is no need for js for this as that can all be done in CSS assuming that it is constructed from the start with this purpose in mind.
Lastly you didn’t answer my questions about document height so I suggest you add a load of content that is taller than the viewport and a load of nav items that are taller than the viewport and then define what is supposed to happen? The result of that question will affect how the nav and main are constructed which is why I asked the question originally
If you can answer those questions then I can take a look tomorrow unless one r more of the other members are around beforehand.
It is OK.
I do not have a good answer for this. More than JS may be easier sometimes as my CSS knowledge is limited. But I want to avoid JS, so do you have any suggestions I am eager to learn.
Again. If I can avoid JS…
I think this is because the <main>
is later divided into 2 sub <section>
with full overflow. Here is a live example what I am trying to achieve. But these do not have a good transition effect. I find a good transition to be nicer UI.
I’d do something like this but its only rough to give the idea. All animations can be tweaked and changed as required.
CSS does nearly everything and you only need JS to toggle the one class on the body. There is some extra js to close the nav on small screen using matchmedia instead of the resize event.
Thanks, I see that it might be possible, but the question is how I make the transition to the left and not to the top. I will try to understand this and see if I can do the left thing in CSS. Switching from left to top may confuse users especially on mobile.
Sorry I thought you wanted it to switch to the top on small screen?
You can change the animation and this one is slightly different.
Remember though that someone on a mobile will not go from large width to small width. Only people on a desktop who close the window to mobile size will see that view.
Yes, but my original dream was to not disturb any user with different UI to navigate. Jumping from desktop to mobile and reverse. So now is 2 out of 3 perfect. Mobile view is still confusing.
In my example you can slide mobile to the left quite easily as that’s basically the default. I misunderstood when you said on top as meaning from the top.
Yes, I should said with higher z-index
Here’s my example with the nav from the side overlaying the content.
I added a blur to the content to enhance the menu but all that can be changed as required.
Thanks a lot. I think i grasp it to a certain level. I never thought of transition the body instead of the nav. Do you see any other improvements I could make?
BTW, why add a class to a semantic tag? <nav class="nav">
? Benefits?
A document may have several <nav>
elements, for example, one for site navigation and one for intra-page navigation.
It is unlikely that you would style all the nav elements the same. You may only have one at the moment but you may need another at some time and would have to undo all the global rules for it.
The only issue I could see is if you added more side nav items and then you would need to make sure that small height screens can scroll to see them. At the moment they just disappear below the fold.