I'm using the Snap.js plugin - (it allows you to create scrolling side drawers/panels).
It works by creating 3 absolutely positioned divs, one of which contains main content.
Is there a way to position a div fixed to the top of the window when it is itself inside the absolutely positioned div.
At the moment i'm just getting the fixed div to pin to the top of the absolutely positioned div, rather than to the top of the browser. When I scroll, the div remains fixed to the top of the main content, but not the window.
For example:
<div style="position:absolute;">
<div style="position:fixed;top:0">
<!-- some content which needs to be pinned to top of window -->
</div>
</div>
At the moment i'm using javascript to track the scroll offset and manually adjust the top position of the child div, which is not ideal for performance.
Any help appreciated!
I've made a fiddle showing my javascript workaround - it jitters when scrolling in internet explorer, any ideas.
<div id="displayed-content" class="snap-content scrollable">
<div><!-- regular content --></div>
<div><!-- fixed content --></div>
<div><!-- footer content --></div>
</div>
http://jsfiddle.net/bxRVT/
I am guessing a bit about what you are trying to do, but you might be looking for something like this:
<div class="local-wrap">
<div class="fixed">
Some content which needs to be pinned to top of window
</div>
<div class="port">
Regular content...
</div>
</div>
and apply the following CSS:
.local-wrap {
position: relative;
}
.local-wrap .fixed {
position: absolute;
top: 0;
left: 0;
background-color: lightgray;
width: 100%;
height: 5.00em;
}
.local-wrap .port {
position: relative;
top: 5.00em;
min-height: 10em;
height: 15em;
overflow: auto;
border: 1px solid gray;
border-width: 0 1px 1px 1px;
}
Demo fiddle: http://jsfiddle.net/audetwebdesign/pTJbW/
Essentially, to get a fixed block with respect to a block element, you need to use absolute positioning. Fixed positioning is always with respect to the root element or view port, so position: fixed won't help you.
What I have done is define a .local-wrap container, with two child blocks, one which is
positioned absolutely to the top of .local-wrap and the other in regular flow. I used position: relative to position it below .fixed, but a top margin would have also worked.
I fixed some heights to demonstrate scrolling content within the local window/port, but that can be changed depending on your design and application.
Disclaimer
I am not familiar with snap.js so there may be other considerations to consider.
Comment on CSS3 Transform and Fixed Elements
According to the CSS3 specs, if you apply a transform to an element, call it div.transformed, then div.transformed creates a new stacking context and serves as a containing block for any fixed position child elements that it contains, which is why in your scenario, the fixed position context does not stay at top of the window.
For reference, see Mozilla Developer Network -> CSS Reference -> Transform
Related
Here is a simplified version of my layout:
<body>
[... a bunch of content ...]
<div id="modal-overlay">
</div>
</body>
body contains enough content that the entire page scrolls.
#modal-overlay is styled like this:
#modal-overlay {
display: none;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
In response to a user action, I'll display the #modal-overlay by setting display: block;
The #modal-overlay then fills the entire viewport.
Here's the trouble...
SOMETIMES, when you swipe vertically on the the #modal-overlay - its content scrolls as it should.
However, SOMETIMES, the body scrolls instead, and the content in #modal-overlay doesn't scroll at all. It's as if I'm scrolling body through the #modal-overlay, which is exactly what I don't want.
In fact - it seems totally random whether #modal-overlay or body scrolls in response to the swipe gesture.
I've read about a few hacks (e.g., applying overflow:hidden to the body but I don't want to do that, since it loses the correct scroll position, and causes other problems as well.) I also would like to have a solution that works with any number of nested layers. I'm really trying to prevent scrolling through the uppermost layer, not fiddling with the underlying layers.
This is particularly problematic on iOS, since scrolling the body reduces the height the browser chrome, which expands the viewport, which messes with the layout of the #modal-overlay, since it's sized to fill the viewport. Aaargh.
Thanks in advance for any advice or guidance!
I haven't tried to achieve this on ios, but you can at least give a try using slimscroll jquery plugin if you are dealing with multiple layers and prevent scrolling of other layers.
Hope it helps
Body should be overflow-hidden and
add dynamically position: absolute; width: 100%; height: 100% CSS properties to other content wrapper (content container inside the body) in the body when modal open.
When open the Modal
<style>
.modal-open {
overflow: hidden;
}
.modal-open .container {
position: absolute;
width: 100%;
height: 100%;
}
</style>
<body class="modal-open">
<section class="container">
Site content will be here
</section>
<div class="modal">
Modal content will be here
</div>
</body>
Add this "modal-open" class dynamically when open the modal and remove it when it close.
Since your modal-overlay covers the body 100%, I believe adding position:fixed to body when you display the #modal-overlay will fix your issue.
I am trying to position a box in a fixed way relative to the window, but only within the limits of a certain section of the site. You can visualise this easier in the jsfiddle that I created.
https://jsfiddle.net/animyrch/dzrpg6gh/
My element (the yellow box) needs to remain where it is on the screen. And it does exactly that. But the wrapper element (blue box) has a height of 20em. And when the screen is scrolled further than that, the fixed element continues to stay on the screen and goes out of its wrapper. How can I ensure that it doesn't go further than a specific point (for example, after 19 em or the starting point of the padding or the border of the wrapper, etc.) and starts to disappear from the screen as the scrolling goes on?
I have searched for an answer but all my search queries are understood as "keeping an element fixed relative to its parent". It's true that when the fixed element reaches a certain point, I want it to be no longer fixed relative to the window but relative its parent but it's clear that it's not the same thing.
Thank you in advance for your answers.
Here is the code from jsfiddle:
HTML
<div class="wrapper">
<div class="fixedElement">
<p>This should stay fixed on screen but shouldn't go lower than its parent</p>
</div>
</div>
<div class="enlargingPage"></div>
CSS
.wrapper {
background-color: blue;
padding: 2em;
left: 50%;
top: 50%;
height: 20em;
}
.fixedElement {
background-color: yellow;
position: fixed;
}
.enlargingPage {
background-color: gray;
height:30em;
}
What you are probably looking for is position: sticky. Check the MDN documentation on how to use it.
https://developer.mozilla.org/en-US/docs/Web/CSS/position
Remember browsers natively don't support it much. http://caniuse.com/#feat=css-sticky
You can obviously polyfill it using one of the polyfills out there. Example - https://github.com/wilddeer/stickyfill
I'm wanting to fix a right hand col to the top of the window (when scrolling) using Bootstrap 3.0 and affix.
This is the html for the element:
<div class="col-lg-4 right-hand-bar" data-spy="affix" data-offset-top="477">
This is the css:
.right-hand-bar.affix {
width: 390px;
position: fixed;
top: 0px;
right: 0px;
margin-top: 110px;
}
In the example here you will see that a few strange things are happening.
The fixed .right-hand-bar (popular blog posts etc) jumps to the right of the screen (due to position fixed being applied). I don't really want to mess about with the right positioning as the site is responsive.
The fixed bar jumps outside of the main container.
I've had to add a width to the fixed element which I'd rather not (due to it being responsive).
I'd also like it to stop scrolling with the page when the bottom of the fixed element hits the top of the footer (or an offset value from the footer).
Can anyone help with any of these.
Thanks in advance!
Wrap a media query for .right-hand-bar.affix styles, so they only apply to the desktop version. You don't want it to be fixed on small-screens anyway.
Then add position: relative; to the styles for .row, and the .right-hand-bar will be affixed relative to that container instead of to the entire page.
I have a website that has a fixed height and a scrollable div inside that. Is it possible to remove the inner scrollbar and change it to the pages' one? The current example with the scrollbar inside the div is here.
I suspect this might need to be done with Javascript and a search on Stack Overflow shows a number of entries referring to it but I'm kind of hoping it doesn't need to be done using Javascript.
Currently, I just let the users scroll inside the div but it's not really an elegant solution:
.singlepost {
position: fixed;
top: 270px;
bottom: 20px;
background-color: white;
padding-left: 20px;
padding-right: 20px;
overflow-x: hidden;
}
You could set every other element on the page to position: fixed, leaving your div to expand the body and make it scrollable. Check the fiddle for an example:
http://jsfiddle.net/GYatesIII/TnzG5/4/
The Next Web uses a similar tactic.
Looking at your demo page, it may be easiest to just put everything above into a div, which floats on top and whatever goes below scrolls up beneath the top div. That would keep your nav at the top and the rest of the page scrolling as usual, using the main windows scrollbar.
I have the following:
<div id="container">
<img src="pic.png">
</div>
This is styled as follows:
#container {
height: 50px;
width: 50px;
}
In addition to this, I have some javascript hackery to cause the image to appear dead center in the containing div by setting margin-top and margin-left.
When I look at this in the Chrome web inspector, it's clear that the containing div does not start at the top of its parent. I suspect the image is being positioned relative to the container div's parent.
The trouble with this is that I want the container div to be a target for click events, such as dragging. The div only starts at the top of the image, when I want it to start above the image, and include the margin space as a part of the container. Any advice?
#plalx is right your using the wrong selector you should just do this:
#container{
width: 50px;
height: 50px;
padding: 5px;
}
padding is what your looking for with making the div bigger then the image for click. margin determines place on the page, padding determines space on the page beyond your height and width attributes.
See http://jsfiddle.net/VRJUc/. If you open the element inspector (chrome) and look at the actual size of the div you will see that it is actually 60x60 because I have added 5px of padding to each side.