position:fixed -- content disappearing on Zoom
After dwelling with this issue,finally found a solution -- thanks to stackoverflow community!!.. here's the link(had posted another question as this ques dint gain any output)
unable to get the scroll when position:fixed -- elements disappears form the screen
Position fixed on chrome mobile causing element to move on scroll up/down
I found out.
For some god forsaken reason, my beloved Google Chrome on mobile require minimum-scale=1 on the viewport meta.
<meta name="viewport" content="minimum-scale=1">
It works now.
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: block
— it 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;
}
disappearing position fixed header in ios7 mobile safari
I was having the same issue, it seems to be a bug that occurs when there is too much going on inside the page, I was able to fix it by adding the following transform code to the fixed position element, (transform: translateZ(0);-webkit-transform: translateZ(0);
) that forces the browser to use hardware acceleration to access the device’s graphical processing unit (GPU) to make pixels fly. Web applications, on the other hand, run in the context of the browser, which lets the software do most (if not all) of the rendering, resulting in less horsepower for transitions. But the Web has been catching up, and most browser vendors now provide graphical hardware acceleration by means of particular CSS rules.
Using -webkit-transform: translate3d(0,0,0); will kick the GPU into action for the CSS transitions, making them smoother (higher FPS).
Note: translate3d(0,0,0) does nothing in terms of what you see. it moves the object by 0px in x,y and z axis. It's only a technique to force the hardware acceleration.
#header {
position: fixed;
/* MAGIC HAPPENS HERE */
transform: translateZ(0);
-moz-transform: translatez(0);
-ms-transform: translatez(0);
-o-transform: translatez(0);
-webkit-transform: translateZ(0);
-webkit-font-smoothing: antialiased; /* seems to do the same in Safari */
}
Fixed element disappears in Chrome
This is a webkit issue that has yet to be resolved, oddly making the jump with JavaScript, rather than using the #
url value, doesn't cause the problem. To overcome the issue, I supplied a JavaScript version that takes the anchor value and finds the absolute position of the element with that ID and jump to that:
var elements = document.getElementsByTagName('a');
for(var i = 1; i < elements.length; i++) {
elements[i].onclick = function() {
var hash = this.hash.substr(1),
elementTop = document.getElementById(hash).offsetTop;
window.scrollTo(0, elementTop + 125);
window.location.hash = '';
return false;
}
}
I could refine this further and make it is that only it only looks for links beginning with a #
, rather than ever a
tag it finds.
Stop fixed position at footer
Live demo
first, check its offset every time you scroll the page
$(document).scroll(function() {
checkOffset();
});
and make its position absolute if it has been downed under 10px before the footer.
function checkOffset() {
if($('#social-float').offset().top + $('#social-float').height()
>= $('#footer').offset().top - 10)
$('#social-float').css('position', 'absolute');
if($(document).scrollTop() + window.innerHeight < $('#footer').offset().top)
$('#social-float').css('position', 'fixed'); // restore when you scroll up
}
notice that #social-float
's parent should be sibling of the footer
<div class="social-float-parent">
<div id="social-float">
something...
</div>
</div>
<div id="footer">
</div>
good luck :)
How can I make a div stick to the top of the screen once it's been scrolled to?
You could use simply css, positioning your element as fixed:
.fixedElement {
background-color: #c0c0c0;
position:fixed;
top:0;
width:100%;
z-index:100;
}
Edit: You should have the element with position absolute, once the scroll offset has reached the element, it should be changed to fixed, and the top position should be set to zero.
You can detect the top scroll offset of the document with the scrollTop function:
$(window).scroll(function(e){
var $el = $('.fixedElement');
var isPositionFixed = ($el.css('position') == 'fixed');
if ($(this).scrollTop() > 200 && !isPositionFixed){
$el.css({'position': 'fixed', 'top': '0px'});
}
if ($(this).scrollTop() < 200 && isPositionFixed){
$el.css({'position': 'static', 'top': '0px'});
}
});
When the scroll offset reached 200, the element will stick to the top of the browser window, because is placed as fixed.
Sticky header disappearing after going a certain ways down the page
I think you'll get the desired behavior by switching from sticky
to fixed
. Sticky is sort of a hybrid of fixed and relative positioning, and changes its behavior relative to context, and is commonly used to allow items to respond to its neighbors via scroll position.
Sticky positioning can be thought of as a hybrid of relative and fixed positioning. A stickily positioned element is treated as relatively positioned until it crosses a specified threshold, at which point it is treated as fixed until it reaches the boundary of its parent.
So you want:
header {
position: fixed;
}
PS: The reason its disappearing for you is that your body has a computed height, but the contents of the body overflow beyond that height. The sticky element scrolls away once you scroll past the computed height of the body, which is the header's parent.
How does the position: sticky; property work?
Sticky positioning is a hybrid of relative and fixed positioning. The element is treated as relative positioned until it crosses a specified threshold, at which point it is treated as fixed positioned.
...
You must specify a threshold with at least one oftop
,right
,bottom
, orleft
for sticky positioning to behave as expected. Otherwise, it will be indistinguishable from relative positioning.
[source: MDN]
So in your example, you have to define the position where it should stick in the end by using the top
property.
html, body {
height: 200%;
}
nav {
position: sticky;
position: -webkit-sticky;
top: 0; /* required */
}
.nav-selections {
text-transform: uppercase;
letter-spacing: 5px;
font: 18px "lato", sans-serif;
display: inline-block;
text-decoration: none;
color: white;
padding: 18px;
float: right;
margin-left: 50px;
transition: 1.5s;
}
.nav-selections:hover {
transition: 1.5s;
color: black;
}
ul {
background-color: #B79b58;
overflow: auto;
}
li {
list-style-type: none;
}
<nav>
<ul align="left">
<li><a href="#/contact" class="nav-selections" style="margin-right:35px;">Contact</a></li>
<li><a href="#/about" class="nav-selections">About</a></li>
<li><a href="#/products" class="nav-selections">Products</a></li>
<li><a href="#" class="nav-selections">Home</a></li>
</ul>
</nav>
Related Topics
Line Height Default Value If Font Size Is 100%
CSS Grid Vertical Columns with Infinite Rows
Draw a Line That Doesn't Get Thicker When Image Stretches
Angular Mat-Select Text Color Doesn't Change
What Does 14Px/26Px Font Size in CSS Do
How to Find "Emulate CSS Media" in Google Chrome
How to Put Text in the Upper Right, or Lower Right Corner of a "Box" Using CSS
CSS Performance Between Class and Attribute Selectors
Can You Add New CSS Properties in Chrome Inspector
Bootstrap Collapse Menu Disappears When Resizing Screen
Z-Index When Using ::After Under Element
What Does \ Mean in a CSS Hex Color Notation
React Js: How to Animate Conditionally Rendered Components
How to Float Paragraph Next to Image Without Wrapping the Image
Is There a Trick to Show Arial Black in Firefox