简体   繁体   中英

How to make a navigation bar always stay at the top of a fixed-position panel that is in the middle of the screen?

I'm attempting to create a layout where there is a menubar, a hovering panel that is centered in the screen, and a menubar at the top of the panel. I can't find a way to do this that results in the panel's menubar both the full width of the panel (and no further) while also not scrolling with the contents of the panel.

Here is the (mostly-anonymized) code: https://jsfiddle.net/BringerOfMisfortune/0rk79dw2/20/ (If you change the class from navBarContainer2 to navBarContainer1 you will see the other issue)

I have several intertwined issues here. I want the main panel that all of my content goes in in the center of the screen. It's a nested div, something like this:

<div>menu bar</div>
<div>
(the panel)
<div>menu bar</div>
<div>content area</div>
(still the panel)
</div>

Ideally, I want the content area to scroll, but the menu bars and the containing "panel" div to be fixed in their positions. To that end, I have the menu bars and the panel set with position: fixed and the panel area is constrained to be 10% from all sides of the screen.

The first issue starts with the fact that I can't seem to find a way that the content area can actually scroll.

If I were to move the scroll: auto out of the panel's CSS and into that of the content area, it not only now does not scroll at all but the text runs out of the bottom of said panel! This is horribly broken and not what I want. I'm not sure why this happens, because the panel can be made to scroll, but not the div inside the panel's div.

So, I needed a way to make the menu bars stay at the top of the screen and at the top of the panel even when the entire panel is being scrolled (since I can't make subsections of it scroll, as per the above issue). I used position: fixed but THAT interferes with the width of the inner menubar on the panel. Note that it sticks way out the right side of the screen. I think that's because it's properly offset to the left wall of the panel, but is still using the window's width... for some reason. Perhaps I can use a manually-tuned percentage, but I'm not sure what would break when resizing a window or making future changes.

However, if I use anything other than fixed (to avoid the broken menubar extending into infinity on the right of the screen), it scrolls with the text, which is the issue I was trying to avoid!

I thus need either of two things:

  1. A way to make the text (and of course other elements too) inside the content area to scroll if they don't all fit inside the panel at once while the panel doesn't scroll
  2. A way to make the panel's menu bar always stay at the top of the scrolling panel without extending out the side of the page

Please help? I have never seen anyone else attempting what I am here (or my Google-fu is that bad), so I'm having trouble figuring out my options.

To make an element scrollable it has to have a height - otherwise the element just extends to be the height of whatever is in it.

In this instance we can't know the exact height of the remainder of the panel, but we can use flex to ask that the text be given the height remaining. Put your text into a div which can then take up the remaining vertical space. I have given this div an id of textdiv and have put the additional CSS into #content and #panel as I don't know whether you use the classes elsewhere but of course you could use classes if appropriate.

So the additional CSS is:

#panel {
  display: flex;
  flex-direction: column;
}
#content {
  display: flex;
  flex-direction: column;
  overflow-y:hidden;
}
#textdiv {
  overflow-y: auto;
}

Here is the complete snippet, with navBarContainer1 which solves your other, horizontal overflow, problem.

 :root { --edges: #333; --footer: #fff; --bgd: #777; --button: #333; --button_hover: #111; --button_lit: #33aaff; --selectable: #999; --selectable_hover: #ddd; --accent: #33aaff; --theme_main: #e9f4ff; --theme_second: #ddd; --formcolor: #fff; --inactive: #eee; } body{ background-color: var(--bgd); margin: 0%; padding: 0; } .navBarContainer1{ position: absolute; background-color: var(--button); width: 100%; margin: 0%; padding: 0; } .navBarContainer2{ position: fixed; background-color: var(--button); width: 100%; margin: 0%; padding: 0; } .blockbutton { display: inline; margin: 0%; padding: 0; } button{ border: none; cursor: pointer; color: white; text-align: center; padding: 14px 16px; margin: 0; text-decoration: none; font-size: 16px; transition: all 0.3s ease; } .navButton{ background-color: var(--button); float: none; } .navButton:hover:not(.activeNav) { background-color: var(--button_hover); } .mainButton{ background-color: var(--selectable); border: 1px solid var(--edges); } .mainButton:hover:not(:disabled){ background-color: var(--selectable_hover); } .activeNav { background-color: var(--button_lit); } button:disabled{ background-color: var(--inactive); color: var(--inactive); } .overlay{ position: fixed; top: 10%; left: 10%; right: 10%; bottom: 10%; border-radius: 15px; background-color: var(--theme_main); border: 10px solid var(--edges); overflow: auto; } .mainWindow{ margin-top: 40px; padding: 20px; } .file{ background-color: var(--selectable); width: 99%; border: 1px solid var(--edges); cursor: pointer; color: black; padding: 14px 0px; font-size: 16px; transition: all 0.3s ease; } .file:hover{ background-color: var(--selectable_hover); } .upload_form{ background: var(--formcolor); padding: 0px; border-radius: 5px; border: 1px solid var(--edges); max-width: 600px; margin: 0px auto; text-align: center; } #footer{ position: fixed; bottom: 0; text-align: center; padding: 15px; color: var(--footer); font-size: 16pt; } progress::-webkit-progress-bar { background-color: var(--theme_second); width: 100%; border: 1px solid var(--edges); } progress::-webkit-progress-value { background-color: var(--accent); width: 100%; } progress { background-color: var(--theme_second); width: 100%; border: 1px solid var(--edges); color: var(--accent); } .hidden{ display: none; } #panel { display: flex; flex-direction: column; } #content { display: flex; flex-direction: column; overflow-y:hidden; } #textdiv { overflow-y: auto; }
 <div class="navBarContainer1"> <button class="navButton activeNav" onclick="">A</button> <button class="navButton" onclick="">B</button> <button class="navButton" onclick="">C</button> <button class="navButton" onclick="">D</button> <button class="navButton" style="float:right;" onclick="toggleIssues">E</button> </div> <div id="panel" class="overlay" style="display:flex;flex-direction:column;"> <div class="navBarContainer1"> <button class="info navButton" onclick="">W</button> <button class="info navButton" onclick="">X</button> <button class="info navButton" onclick="">Y</button> <button class="info navButton" onclick="">Z</button> </div> <div id="content" class="mainWindow"> <form class="upload_form"> <h3 id="friendly_prog">Progress: 50%</h3> <progress id="sysprog" max="100" value="50"></progress> <input type="file" class="file" id="file"> <h3 id="status">Status: Reticulating Splines</h3> <button class="mainButton" type="button" id="start" onclick="">Start!</button> </form> <div id="textdiv"> <p>test</p><p>test</p><p>test</p><p>test</p><p>test</p><p>test</p><p>test</p><p>test</p><p>test</p> <p>test</p><p>test</p><p>test</p><p>test</p><p>test</p><p>test</p><p>test</p><p>test</p><p>test</p> <p>test</p><p>test</p><p>test</p><p>test</p><p>test</p><p>test</p><p>test</p><p>test</p> </div> </div> </div>

try to set parameters top to 50vh like so: top:50vh . this will set the distance relative to the viewport

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM