In my Angularjs app I have a dropdown menu that appears when I click on a link. To stop scrolling on the page while the menu is showing I use overflow:hidden and add the class to the body when the menu is showing:
However, using overflow:hidden also removes the vertical scrollbar completely from Windows based browsers meaning the whole page shifts to the right (by the width of the scrollbar) when the menu opens.
Can I stop the scrolling without completely removing the scrollbar? Perhaps keep the scrollbar container in place but hide the handle.
Example
Take a look at https://fancy.com/ - click on the login link and the modal should appear. The scrollbar handle disappears but the scrollbar container remains. How can I achieve this effect?
Take a look at https://fancy.com/ - click on the login link and the modal should appear. The scrollbar handle disappears but the scrollbar container remains. How can I achieve this effect?
Looks like they are simply doing this by having overflow-y: scroll set for body to begin with, and then a class fixed is added to the html element when you click “login”.
And then that class affects the main content container of the page, setting it to fixed position:
.fixed #container-wrapper {position:fixed;left:0;width:100%; /*[…]*/
Put the menu into a wrapper div and set overflow-x: and overflow-y: as you need for this div.
As I mentioned in the comments, this can easily be done with nested divs. Yes it could be done using the body tag but that is a very simple change from my code below. You can see the effect here: https://jsfiddle.net/udgj3ot5/
Note: I doubt you will be calling the function straight from the child div so another means to pointing to the element other than this will probably need to be used.
CSS
html, body {
padding:0;
margin:0;
width:100%;
height:100%;
}
div.parentDiv { /*Set this to the body if you don't want two divs*/
width:inherit;
height:inherit;
overflow-y:scroll;
}
JavaScript
function toggleChildDiv(elem) {
if (elem.style.overflow == "hidden") {
elem.style.width = "auto";
elem.style.height = "auto";
elem.style.overflow = "visible"
} else {
elem.style.width = "100%";
elem.style.height = "100%";
elem.style.overflow = "hidden"
}
}
HTML
<div class="parentDiv">
<div onclick="toggleChildDiv(this)">
YOUR PAGE CONTENT
</div>
</div>
Related
I have a div .layer that darkens the entire page to highlight a modal, but when I trigger the event there is a problem to occupying 100% of the screen, and is that the scroll bar of the original browser is deleted
Is there any fancy way to make the div .layer, when is visible, keep the original bar scroll of the page?
In smartphones / tablet I do not find any problem when shooting the event .layer").show(); but on desktop screens the original scroll bar of browser is eliminated and the whole html document moves to right, taking its place.
What would be the correct way to avoid html to the right?
Thanks in advance!
HTML:
<div class="layer"></div>
<div class="open-modal">Open</div>
<div class="modal">
<div class="close-modal">Close</div>
</div>
CSS:
html {width:100%;min-height:100%;margin:0 auto;top:0;left:0;padding:0}
body {top:0;left:0;margin:0;padding:0;min-height:100%}
.layer {
display:none;
position:fixed;
top:0;
left:0;
width:100%;
min-height:100vh;
background:rgba(0,0,0,.9);
z-index:2
}
.modal {display:none;z-index:1}
SCRIPT:
$(document).ready(function(){
$(".open-modal").click(function(){
$(".modal,.layer").show();
$("body").css("overflow","hidden");
});
$(".close-modal,.layer").click(function(){
$(".close-modal,.layer").hide();
$("body").css("overflow","");
});
});
You need to get rid of your use of "overflow". I've included a link below to the Mozilla Developer Network docs for "overflow", but below is a quick quote explaining what's happening.
"hidden
Content is clipped if necessary to fit the padding box. No scrollbars are provided, and no support for allowing the user to scroll (such as by dragging or using a scroll wheel) is allowed. The content can be scrolled programmatically (for example, by setting the value of a property such as offsetLeft), so the element is still a scroll container."
https://developer.mozilla.org/en-US/docs/Web/CSS/overflow
Also, after one cycle of clicking Open and Close, if you were to click Open again, the word Close won't show up. That's because you're not using the .show() method to show that text upon clicking Open. Updated JavaScript below.
JavaScript:
$(document).ready(function(){
$(".open-modal").click(function(){
$(".modal,.layer,.close-modal").show();
});
$(".close-modal,.layer").click(function(){
$(".close-modal,.layer").hide();
});
});
Currently on my single page site when you click on the Bootstrap navbar menu items it takes you to the section of the page with that div #ID. However, naturally because the top of the navbar lines up with the top of the new section my content is overlapped by the width of the navbar (80px or 50px when collapsed).
Screenshot of issue:
"Ready to book" heading is actually centered in the middle of that div but overlapped by 80px of navbar.
Screenshot showing top of page:
The issue is that I do not wish for the navbar to overlap the content in the section I have linked to. Put in other words, I would like the top of bottom of the navbar to line up with the top of the new section div.
Surely this can be handled using some JS to offset the navbar up by the height of the the navbar?
I have had a suggestion to use CSS to add padding into the top of section but this adds an extra 80px of padding that I don't want, when normally scrolling the page.
Okay so I found two solution to this finally using JS and CSS
here.
My preference is for this CSS solution:
#id:before {
display: block;
content: " ";
margin-top: -80px;
height: 80px;
visibility: hidden;
}
Obviously, replace ID with the ID of the anchor.
The actual JS snippet solution:
var shiftWindow = function() { scrollBy(0, -50) };
window.addEventListener("hashchange", shiftWindow);
function load() { if (window.location.hash) shiftWindow(); }
However, it is still a bit clunky as you can actually see the the browser scroll to the anchor point and then back up by the scrollBy offset amount of 80px.
I am not sure if this problem has been solved yet, but I had the same problem and adding the appropriate heading worked (by appropriate padding I mean the height of your navbar element).
For example:
#id { padding:50px }
I'm using Bootstrap 3.2.0.
I can show the modal just fine and the background stays in place. The modal contains a textarea. When I tap or focus on that textarea and the virtual keyboard comes up, the background scrolls to the top.
This only happens with iOS 8 and not iOS 7.
It's like iOS 8 wants to put whatever is focused on in the middle of the screen and it scrolls until that element is in the middle. It scrolls up and up and up until it hits the top THEN pulls the modal down a little.
Very frustrating. Has anyone experienced this yet? Any solutions?
Update: I'm thinking it has to do with the fact that the modal is fixed position and not absolute. iOS wants to put the focused element in the middle of the screen so it scrolls the viewport or document up until the element is in center but scrolling does nothing because the element is position fixed.
The solution for me was to set the modal involved to position:absolute; (by default it is position: fixed;) and instead of placing the modal at the bottom of my HTML by appending it to the body, I appended it to the parent element of the button that I clicked to show the modal. I also needed to ensure that the element that I was appending the modal into had a position of relative.
CSS
.modal.fade.my-special-modal {
position: absolute;
/* 'top' is not required but I did it for my taste */
top: 15px;
}
.my-special-modal-container {
position: relative;
}
HTML
<div class="my-special-modal-container">
<button>Show the modal</button>
<!-- js will inject the modal here -->
</div>
Thanks to #Christina for helping me discover this solution.
you can add this property globally:
if( navigator.userAgent.match(/iPhone|iPad|iPod/i) ) {
var styleEl = document.createElement('style'), styleSheet;
document.head.appendChild(styleEl);
styleSheet = styleEl.sheet;
styleSheet.insertRule(".modal { position:absolute; bottom:auto; }", 0);
}
Suppose we have a DIV element like this:
<div id='parent'>
<!-- The childs will come here -->
<div id='footer'>This is footer</div>
</div>
and this function that create HTML elements dynamically and inserts them into the div#parent
function addChild(name)
{
$("<div></div>").text(name).prependTo( $("div#parent") );
}
CSS:
div#parent
{
height:400px;
background-color:yellow;
}
div#footer
{
/* height: ??? */
background-color:red;
}
Now I want, the element div#footer covers whole available/remaining height of the element div#parent, How I can do this by CSS or Javascript?
Thanks
Another solution using CSS. The solution here is using display:table and display:table-row
div#parent
{
display:table;
height:400px;
width:100%;
background-color:yellow;
}
div{
display:table-row;
height:20px;
}
div#footer
{
/* height: ??? */
background-color:red;
height:auto;
}
http://jsfiddle.net/aawbE/
If you simply want the footer to always be at the bottom of the page, then I would suggest checking out http://www.cssstickyfooter.com/. They have a great concept for making sure that the footer will either be at the end of the content, or touch the bottom of the page.
Example
If you want the footer to cover the entire bottom portion of the screen (beginning where the content ends and ending at the bottom of the screen) then you do need to know the total height being used by all of the elements inside of the "container" element as well as the height of the "container" element.
An easy way to do this is to put all child elements into a different div (the height of which you can easily track.
//find the difference in height between the
//"parent" div (minimum of 100% of page height) and
//the "main" div (the total height of its child elements)
height = document.getElementById('parent').offsetHeight -
document.getElementById('main').offsetHeight;
//Set the top margin of footer to minus the height
//(make footer go up 'height' number of pixels
document.getElementById('footer').style.marginTop = -height+'px';
//Set the height of the footer to 'height'
document.getElementById('footer').style.height = height+'px';
It's important to note that these calculations are based off of the cssStickyFooter code. This makes sure that the bottom of the footer remains at the bottom of the screen (unless it passes the bottom of the screen).
Example
For this example I added a green border around the 'main' div so that you can see where it ends. I also make sure to change the footer whenever the page is re-sized in case the child elements move around (re-size the page to see this happen). I also added a min-height to the footer so there will still be a footer even if #main.height >= #parent.height.
I hope this helps.
I've created an effect whereby an HTML element is initially hidden behind another HTML element, and the CSS 'top' value of the hidden element is animated to expose it from beneath the masking element in a smooth sliding motion.
Does anyone know if there is a way to recreate this effect without the masking element on top?
I want to avoid the jQuery'esque slideDown where the height of the element being shown is animated.
I have the feeling that this just isn't possible, but if someone is otherwise aware, your advise would be much appreciated.
You can easily do this with a wrapper that has overflow set to hidden
http://jsfiddle.net/xvNf6/1/
HTML
<div id="wrapper" style="height:0px;">
<div>content</div>
</div>
Sample CSS
#wrapper{width:300px;height:280px;margin:0 auto; overflow:hidden; background:#eee}
Javascript
//if you must not use jQuery
var animationTimer = setInterval(function(){
var wrapper = document.getElementById("wrapper");
wrapper.style.height = (parseInt(wrapper.style.height) + 1) + "px";
if(parseInt(wrapper.style.height) >= 280)
clearInterval(animationTimer)
},1);
//if you can use jQuery
$("#wrapper").animate({height:"280px"},1000);
Place your element within a parent div with overflow:hidden. Then, position your element beyond bounds of the parent div so that it is hidden.
#wrapper { overflow: hidden; }
#target { height: 100px; top: -100px; } /* shift element out of view */
You can then reveal it by animating to {"top":0} to get the slidedown effect that doesn't resize the height of the element.
Here's a rather crude demo: http://jsfiddle.net/7RSWZ/
Update: Here's another demo that attempts to deal better with different content sizes by dynamically setting the heights and top values. http://jsfiddle.net/7RSWZ/2/