I have a fixed
vertical <nav>
element that has a dynamic width. I want it not to overlap with the <main>
element no matter what, even if the screen width is small
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
* {
box-sizing: border-box;
margin: 0;
scroll-behavior: smooth;
}
body {
display: flex;
}
nav {
position: fixed;
display: flex;flex-direction: column;
flex-wrap: wrap;
width: 20%;
min-width: max-content;
height: 100%;
padding: 1rem 0.5rem;
background-color: #5382a1;
font-family: Tahoma, sans-serif;
}
nav header {
font-weight: bold;
color: white;
}
nav ul {
padding: 0;
}
nav li {
display: block;
padding: 0.4rem;
border: 1px solid white;
margin: 0.2rem 0;
text-align: center;
border-radius: 3px;
background-color: white;
color: hsl(34, 94%, 54%);
}
nav li:hover {
color: white; background-color: hsl(34, 94%, 54%);
}
nav a {
text-decoration: none;
color: inherit;
}
nav a:hover {
color: white;
}
main {
width: 70%;
min-width: 200px;
margin: 1rem 1rem 2rem 25%;
}
p {
margin: 1rem 0;
}
</style>
</head>
<body>
<nav id="navbar">
<header>Navbar</header>
<ul>
<li><a class="nav-link" href="#section-one">Section One</a></li>
<li><a class="nav-link" href="#section-two">Section Two</a></li>
<li><a class="nav-link" href="#section-three">Section Three</a></li>
</ul>
</nav>
<main>
<section id="section-one" class="main-section">
<header>
<h2>Section One</h2>
</header>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</section>
<section id="section-two" class="main-section">
<header>
<h2>Section Two</h2>
</header>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</section>
<section id="section-three">
<header>
<h2>Section Three</h2>
</header>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</section>
</main>
</body>
</html>
You don’t see any overlap in the code snippet above, but that’s because the width is big enough. If you shrink it roughly to the size of a smartphone, you can start to see the issue
You may notice that <body>
has a display: flex
property, but it doesn’t help since the <nav>
is fixed
(so any flex behavior doesn’t apply to it). However, it may give you a better idea of what I try to achieve here
I could hypothetically do something like this
main {
width: calc(100% - nav.width);
padding: 1rem;
}
but the problem is you can’t reference variables in the calc()
function
I also tried this
nav {
width: 20vw;
}
main {
width: 80vw;
}
What would you recommend to avoid overlap of a fixed dynamically-sized vertical navbar with the main content without the use of JS?
I came across this similar question, but none of the answers proved helpful
2
Answers
This kind of works, but it's a bit too hard-coded for my liking. Notice these changes
Add parent div with
position: fixed
anddisplay: flex
and removepostion:fixed
fromnav
.also, don’t forget to add
height: 100%
andoverflow-y: scroll
tomain
Here is the jsfiddle link.