0

If I resize my page and the elements overflow above the viewport, I can't scroll up to see them. I found this question with a solution but it didn't work. I have two "core" invisible divs and a div element that has all of the content inside.

The "container" div exists because I was trying to fix this issue.

.container {
   position: fixed;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
   z-index: 500;
}

.main-content {
   display: flex;
   width: 100%;
   height: 100%;
   overflow: auto;
   margin: auto;
}

.window {
   /*height: 16vw;
   width: 27vw;*/
   display: flex;
   height: 550px;
   width: 800px;
   position: absolute;
   top: 50%;
   left: 50%;
   border: solid blue 5px;
   background-color: black;
   margin: auto;
   overflow: hidden;
}
<div class="container">
  <div class="main-content">
    <div class="window" id="window1" style="transform: translate(-10%, -90%);">
      <div class="header" id="window-header">
        <img src="https://picsum.photos/800/550">
        <p class="title">navigation</p>
      </div>
    </div>
  </div>
 </div>
TylerH
  • 20,799
  • 66
  • 75
  • 101
nezzled
  • 93
  • 10
  • Absolutely positioned elements are positioned in relation to the nearest position ancestor. If there is no positioned ancestor, then the root elements (i.e., the viewport). Have you tried adding `position: relative` to `.main-content`? https://jsfiddle.net/xwvj2zay/ – Michael Benjamin Jul 04 '23 at 14:39
  • @MichaelBenjamin I just tried that, it unfortunately didn't change anything – nezzled Jul 04 '23 at 17:12
  • Any resolution on this? It's been a bit at this point and this is still an issue for me. – nezzled Jul 13 '23 at 00:23
  • Perhaps post more details about the problem and things you've tried. Also consider a bounty to attract more attention. – Michael Benjamin Jul 13 '23 at 13:46
  • I've tried using `margin:auto` on multiple divs, all the solutions recommended on this page, and changing the structure of the divs themselves. Nothings worked. I may try a bounty but to be frank I don't even know how they work XD – nezzled Jul 14 '23 at 22:43
  • I think if you provide more info on what exactly you seek it'd be easier to help! Surely the issue is with the transform property, may I ask why you need it? What exactly you want to do with it? I'm trying to give an alternative to the transform property for your case – Merlin the Immortal Jul 20 '23 at 13:14
  • 1
    You are setting both `position:fixed` and `position: absolute` on these elements, which messes with scroll behavior, and you are using `transform`, which preserves scroll layer painting, so I don't know what you expect should allow scrolling to update. Try using a property other than `transform` if you want to move the elements and have scroll behavior update to reflect the new positioning. – TylerH Jul 20 '23 at 15:01

4 Answers4

1

For this i think the only solution is to make a custom scrollbar (if it is necessary that the image must be above the viewport)

here is the code i have made it according to your code

let stopDrag = false;
        const mouse = {}
        document.addEventListener('mousemove', (e) => {
            mouse.x = e.clientX;
            mouse.y = e.clientY;
        })
        document.getElementsByClassName('scrollbar')[0].addEventListener('mousedown', startDrag)
        document.getElementsByClassName('drag')[0].addEventListener('mousedown',startDrag)
        document.addEventListener('mouseup', () => {
            stopDrag = true;
        })
        function startDrag() {
            stopDrag = false;
            let interval = setInterval(() => {
                if(mouse.y+180 > 495) {
                    document.getElementsByClassName('drag')[0].style.top ="495px";
                } else 
                if(mouse.y+180 <217) {
                    document.getElementsByClassName('drag')[0].style.top ="0px";
                }
                else
                {
                    document.getElementsByClassName('drag')[0].style.top = mouse.y+(180 + ((Number(document.getElementsByClassName('drag')[0].style.top.split("p")[0]) -760)/3.5));
                }
                document.getElementsByClassName('window')[0].style.bottom = (Number(document.getElementsByClassName('drag')[0].style.top.split("p")[0]) -760) + "px"
                if(stopDrag) {
                    clearInterval(interval)
                }
            })
        }
.container {
   position: fixed;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
   z-index: 500;
}

.main-content {
   display: flex;
   width: 100%;
   height: 100%;
   overflow: auto;
   margin: auto;
}

.window {
   /*height: 16vw;
   width: 27vw;*/
   display: flex;
   height: 550px;
   width: 800px;
   position: absolute;
   top: 50%;
   left: 50%;
   border: solid blue 5px;
   background-color: black;
   margin: auto;
   overflow: hidden;
}
.scrollbar {
    height: 100%;
    width: 2%;
    position: fixed;
    top: 0%;
    right: 10%;
    z-index: 3;
    background: white;
}
.scrollbar .drag {
    background: darkgray;
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 10%;
    
}
.scrollbar .drag:hover {
    background: grey;
}
<div class="container">
        <div class="main-content">
          <div class="window" id="window1" style="transform: translate(-10%, -90%);">
            <div class="header" id="window-header">
              <img src="https://picsum.photos/800/550">
              <div class="scrollbar">
                <div class="drag" draggable = false></div>
              </div>
              <p class="title">navigation</p>
            </div>
          </div>
        </div>
       </div>

EXPLANATION

basically i have made a scrollbar with html and css and put it to the very right of the image

hope the html and css is understood now, for the javascript

first we map the mouse coordinates

const mouse = {}
document.addEventListener('mousemove', (e) => {
            mouse.x = e.clientX;
            mouse.y = e.clientY;
        })

we make the event listeners which call the functions or change the stop drag variable

let stopDrag = false;
document.getElementsByClassName('scrollbar')[0].addEventListener('mousedown', startDrag)
        document.getElementsByClassName('drag')[0].addEventListener('mousedown',startDrag)
        document.addEventListener('mouseup', () => {
            stopDrag = true;
        })

then we make the startDrag() function

function startDrag() {
            stopDrag = false;
            let interval = setInterval(() => {
                if(mouse.y+180 > 495) {
                    document.getElementsByClassName('drag')[0].style.top ="495px";
                } else 
                if(mouse.y+180 <217) {
                    document.getElementsByClassName('drag')[0].style.top ="0px";
                }
                else
                {
                    document.getElementsByClassName('drag')[0].style.top = mouse.y+(180 + ((Number(document.getElementsByClassName('drag')[0].style.top.split("p")[0]) -760)/3.5));
                }
                document.getElementsByClassName('window')[0].style.bottom = (Number(document.getElementsByClassName('drag')[0].style.top.split("p")[0]) -760) + "px"
                if(stopDrag) {
                    clearInterval(interval)
                }
            })
        }

in this first we set the stopdrag to false as the user is currently dragging the scrollbar then we make an interval to loop the code mouse.y according coords was mostly trial and error for me we check if it is above or below the limit if it is we reposition then we change the top of the scrollbar when dragging (calculations were again trial and error) then we change the bottom of the window class div to reposition the window class div (because image can't be repositioned by itself; you can make another container on it if you don't want the entire window class div to move) to see it and if dragging has stopped we clear the interval

0

Two potential solutions to consider:

In both/either solutions, remove the transform property.

1) Change the position properties and remove overflow: hidden from the "window" div container:

Remove the fixed position property setting from the "container" div, and change the one in the "window" div to position: relative (to enable the top and left properties to be effective).

.container {
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
   z-index: 500;
}

.main-content {
   display: flex;
   width: 100%;
   height: 100%;
   overflow: auto;
   margin: auto;

}

.window {
   display: flex;
   height: 550px;
   width: 800px;
   /* transform: translate(-10%, 90%); */
   position: relative;
   top: 50%;
   left: 50%;
   border: solid blue 5px;
   background-color: black;
   margin: auto;
   /* overflow: hidden; */
}

.title {
/*    color: white;*/
display: inline-flex;
font-size: 24pt;
}
<div class="container">
  <div class="main-content">
    <div class="window" id="window1">
      <div class="header" id="window-header">
        <img src="https://picsum.photos/800/550">
        <p class="title">navigation</p>
      </div>
    </div>
  </div>
</div>

2) Or, to have the p "title" element appear inside of the "window" div container, use overflow: auto:

.container {
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 500;
}

.main-content {
  display: flex;
  width: 100%;
  height: 100%;
  overflow: auto;
  margin: auto;
}

.window {
  display: flex;
  height: 550px;
  width: 800px;
  /* transform: translate(-10%, 90%); */
  position: relative;
  top: 50%;
  left: 50%;
  border: solid blue 5px;
  background-color: black;
  margin: auto;
  overflow: auto;
}

.title {
  color: white;
  display: inline-flex;
  font-size: 24pt;
}
<div class="container">
  <div class="main-content">
    <div class="window" id="window1">
      <div class="header" id="window-header">
        <img src="https://picsum.photos/800/550">
        <p class="title">navigation</p>
      </div>
    </div>
  </div>
</div>

Extra Notes / Discussion

If you are not already, I would highly recommend, opening up your HTML page using the dev tools in whatever browser you are using, to inspect the code and manipulate/make tweaks to it and watch live what happens. (For example, using Google Chrome Developer Tools.)

Mess around with changing the position parameters (and any others) until you get the exact behavior you are trying to get. As explained by another user in the comments of your question, there likely is an issue with the settings of the position properties as you provide them.

As shown in solution 1) above, I found that removing your overflow: hidden helped to make the title appear.

Alternatively (as shown in solution 2) above), setting overflow to auto results in the p element with the title appearing within the black-background .window div (in which case you would want to uncomment the .title property setting the font color to white to make the text visible).

John Collins
  • 2,067
  • 9
  • 17
  • Hi, thanks for your response. Unfortunately, I get completely different results from you when I use this code. The window div is centered on the top left corner, and scaling the dimensions just keeps it off screen without any scrollbars, even for when it overflows on the right or bottom (which worked previously). Also, the translate(-10%, 90%) is there to have both of the windows in the page equally off center. (And the title text already had formatting, I just excluded it for brevity) – nezzled Jul 20 '23 at 03:55
  • 1
    Thanks to another user (@rozsazoltan) who added the snippet functionality. Using that, I was able to do what I myself recommend doing - tweaking with the various parameters and live testing what works. Perhaps the above code helps with your problem. You can run the snippet to see for yourself the results. @TylerH provides knowledgeable helpful info, as well as some other users now here. – John Collins Jul 20 '23 at 21:13
  • @nezzled Updated answer removing the `transform` properties (as recommended in my original answer) - these merely were moving the div way down (and slightly over in) the viewport. Did you have to change `position`[s] also to solve your problem? – John Collins Jul 22 '23 at 18:15
0

Thanks to @TylerH for solving this. The issue was the transform style in my HTML. Removing it allowed it to scroll correctly. From what I've seen it looks like it offsets the scrolling as well as it if it's moving the entire page instead of just the element. Thanks for everyone's assistance but I got it fixed.

nezzled
  • 93
  • 10
  • 1
    Removing the transform alone, based on the code snippet in your question, doesn't solve the problem. Can you provide what exactly did solve your problem / solves the code snippet as in your question (considering you accepted your own answer yet don't actually provide a [full] answer)? (@TylerH) – John Collins Jul 23 '23 at 19:54
-1

Try changing these 2 lines in .window:

.window {
   /*height: 16vw;
   width: 27vw;*/
   display: flex;
   max-height: 100vh; /* change this */
   width: 800px;
   position: absolute;
   top: 50%;
   left: 50%;
   border: solid blue 5px;
   background-color: black;
   margin: auto;
   overflow: auto; /* and this */
}

And change this in your html:

<div class="window" id="window1" style="transform: translate(-50%, -50%);">
  ...
</div>
rozsazoltan
  • 2,831
  • 2
  • 7
  • 20