Make Element Scroll Without Fixed Position Setting

HTML/CSS: scroll div without setting position to fixed or absolute

I think I found a solution for you:

Wrap contents of sidebar into second div and add some class attribute - .fixed in my example. Now, we make .fixed div fixed, .sidebar div will take the space, so .content won't be overlapped by .fixed. Remember to set the same width for .fixed and .content, so they take the same space . Now, set width: auto in .content div, so it take all the space and overflow: hidden.

Now, when .sidebar has display: none, fixed will be hidden, and .content will take all their space :D

CSS:

div.sidebar {
/* take space on the left */
float:left;
width:20%;
margin-bottom:100%;

background-color:rgb(0, 0, 0);
}

div.fixed {
/* display fixed menu */
position:fixed;
width:20%;

left:0rem;
top:0rem;
bottom:1.2rem;
z-index:999;
rgb(110, 110, 110)
overflow-y:scroll;

}
div.content {
width:auto; /* take all the space */
overflow:hidden; /* try using without it and see what happens ;) */

border-width: 0;
background-color: transparent;
font-size: 180%;
line-height: 130%;
}

Working example: http://jsfiddle.net/z8dqhrf2/2/

Make fixed position div scrollable without scrollbar and without scrolling the background content

This is ugly but it works

.mobile_menu 
{
//...
height: 100%;
overflow: scroll;
right: -25px;
}

https://jsfiddle.net/sk9dhgbj/

Have a fixed position div that needs to scroll if content overflows

The problem with using height:100% is that it will be 100% of the page instead of 100% of the window (as you would probably expect it to be). This will cause the problem that you're seeing, because the non-fixed content is long enough to include the fixed content with 100% height without requiring a scroll bar. The browser doesn't know/care that you can't actually scroll that bar down to see it

You can use fixed to accomplish what you're trying to do.

.fixed-content {
top: 0;
bottom:0;
position:fixed;
overflow-y:scroll;
overflow-x:hidden;
}

This fork of your fiddle shows my fix:
http://jsfiddle.net/strider820/84AsW/1/

How can I make the contents of a fixed element scrollable only when it exceeds the height of the viewport?

You probably can't. Here's something that comes close. You won't get content to flow around it if there's space below.

http://jsfiddle.net/ThnLk/1289

.stuck {
position: fixed;
top: 10px;
left: 10px;
bottom: 10px;
width: 180px;
overflow-y: scroll;
}

You can do a percentage height as well:

http://jsfiddle.net/ThnLk/1287/

.stuck {
max-height: 100%;
}

Scrolling div without fixed height

You could stretch the div using absolute positioning. This way it will always take the size of the browser window (or the closest positioned ancestor).

Given this HTML:

<div id="gridcontainer"></div>

the CSS should be something like:

#gridcontainer {
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
overflow: auto;
}

Live Demo

Prevent body scrolling but allow overlay scrolling

Theory

Looking at current implementation of the pinterest site (it might change in the future), when you open the overlay, a noscroll class is applied to the body element (setting overflow: hidden) making the body no longer scrollable.

The overlay created on-the-fly or already injected in the page and made visible via display: blockit makes no difference – has position : fixed and overflow-y: scroll, with top, left, right and bottom properties set to 0: this style makes the overlay fill the whole viewport (but now we are in 2022, so you may use inset: 0 instead).

The div inside the overlay is in position: static so the vertical scrollbar is related to that element. This is resulting in a scrollable but fixed overlay.

When you close the overlay, you have to hide it (using display: none) and you could even remove the node via javascript (or just the content inside, it's up to you but also depends on the nature of the content).

The final step is to also remove the noscroll class applied to the body (so the overflow property gets back to the value it had previously)


Code

Codepen Example

(it works by changing the aria-hidden attribute of the overlay in order to show and hide it and to increase its accessibility).

Markup

(open button)

<button type="button" class="open-overlay">OPEN LAYER</button>

(overlay and close button)

<section class="overlay" aria-hidden="true" tabindex="-1">
<div>
<h2>Hello, I'm the overlayer</h2>
...
<button type="button" class="close-overlay">CLOSE LAYER</button>
</div>
</section>

CSS

.noscroll { 
overflow: hidden;
}

.overlay {
position: fixed;
overflow-y: scroll;
inset: 0; }

[aria-hidden="true"] { display: none; }
[aria-hidden="false"] { display: block; }

Javascript (vanilla-JS)

var body = document.body,
overlay = document.querySelector('.overlay'),
overlayBtts = document.querySelectorAll('button[class$="overlay"]'),
openingBtt;

[].forEach.call(overlayBtts, function(btt) {

btt.addEventListener('click', function() {

/* Detect the button class name */
var overlayOpen = this.className === 'open-overlay';

/* storing a reference to the opening button */
if (overlayOpen) {
openingBtt = this;
}

/* Toggle the aria-hidden state on the overlay and the
no-scroll class on the body */
overlay.setAttribute('aria-hidden', !overlayOpen);
body.classList.toggle('noscroll', overlayOpen);

/* On some mobile browser when the overlay was previously
opened and scrolled, if you open it again it doesn't
reset its scrollTop property */
overlay.scrollTop = 0;

/* forcing focus for Assistive technologies but note:
- if your modal has just a phrase and a button move the
focus on the button
- if your modal has a long text inside (e.g. a privacy
policy) move the focus on the first heading inside
the modal
- otherwise just focus the modal.

When you close the overlay restore the focus on the
button that opened the modal.
*/
if (overlayOpen) {
overlay.focus();
}
else {
openingBtt.focus();
openingBtt = null;
}

}, false);

});

/* detect Escape key when the overlay is open */
document.body.addEventListener('keyup', (ev) => {
if (ev.key === "Escape" && overlay.getAttribute('aria-hidden') === 'false') {
overlay.setAttribute('aria-hidden', 'true');
body.classList.toggle('noscroll', false);
openingBtt.focus();
openingBtt = null;
}
})

Finally, here's another example in which the overlay opens with a fade-in effect by a CSS transition applied to the opacity property. Also a padding-right is applied to avoid a reflow on the underlying text when the scrollbar disappears.

Codepen Example (fade)

CSS

.noscroll { overflow: hidden; }

@media (min-device-width: 1025px) {
/* not strictly necessary, just an experiment for
this specific example and couldn't be necessary
at all on some browser */
.noscroll {
padding-right: 15px;
}
}

.overlay {
position: fixed;
overflow-y: scroll;
inset: 0;
}

[aria-hidden="true"] {
transition: opacity 1s, z-index 0s 1s;
width: 100vw;
z-index: -1;
opacity: 0;
}

[aria-hidden="false"] {
transition: opacity 1s;
width: 100%;
z-index: 1;
opacity: 1;
}

Scrollbar without fixed height/Dynamic height with scrollbar

Flexbox is a modern alternative that lets you do this without fixed heights or JavaScript.

Setting display: flex; flex-direction: column; on the container and flex-shrink: 0; on the header and footer divs does the trick:

HTML:

<div id="body">
<div id="head">
<p>Dynamic size without scrollbar</p>
<p>Dynamic size without scrollbar</p>
<p>Dynamic size without scrollbar</p>
</div>
<div id="content">
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
<p>Dynamic size with scrollbar</p>
</div>
<div id="foot">
<p>Fixed size without scrollbar</p>
<p>Fixed size without scrollbar</p>
</div>
</div>

CSS:

#body {
position: absolute;
top: 150px;
left: 150px;
height: 300px;
width: 500px;
border: black dashed 2px;
display: flex;
flex-direction: column;
}

#head {
border: green solid 1px;
flex-shrink: 0;
}

#content{
border: red solid 1px;
overflow-y: auto;
/*height: 100%;*/
}

#foot {
border: blue solid 1px;
height: 50px;
flex-shrink: 0;
}

Positioning div outside of overflow scroll without using absolute positioning?

If you overlap the #leftCol with the #rightCol (by positioning them absolute to left:0; of their parent container), set the left margin to the width of the left column, then set .content position to relative and box position to absolute, and adjust the positioning using left.

Here is the updated CSS:

#leftCol{
position:absolute;
width: 100px;
height: 500px;
background: green;
left:0;
}
#rightCol{
position:absolute;
padding-left:100px;
width: 400px;
height: 500px;
overflow-y: scroll;
left:0;
}
.content{
height: 700px;
width: 100%;
background: red;
position:relative;
}
.box{
width: 100px;
height: 100px;
background: purple;
position:absolute;
left:-100px;
}

and a DEMO

Hope this helps =)



Related Topics



Leave a reply



Submit