Make fixed page elements "honor" the body right padding? - javascript

My fixed button triggers a menu. While menu is opened, the body has overflow-y: hidden and a padding-right: 17px (actually this value is computed, omitted for brevity). The button (position: fixed) is shifted.
The HTML (the <p> is only needed to show the scrollbar):
<body>
<button class="btn">
Menu
</button>
<p style="height: 5000px;"></p>
</body>
To the CSS... note that .menu-opened is added when you click the button, via JavaScript:
body {
background-color: blue;
}
body.menu-opened {
padding-right: 17px;
overflow-y: hidden;
}
/* Useless styles */
.btn {
background-color: red;
position: fixed;
padding: 1rem;
top: 0;
right: 0;
margin-right: 2rem;
margin-top: 2rem;
}
Example pen here
As soon as the scrollbars are disabled, button is shifted because fixed elements doesn't honor the body padding (which is added to compensate the absence of the scrollbar). Any idea on how to solve this, without touching all fixed elements?
I think this is a common problem, so there should be an easy solution, but I can't get it.

Take a look at scrollbar-gutter: MDN: scrollbar-gutter

Related

How to enable scrolling over fixed element?

I have a problem with scrolling over fixed element, it doesn't work on my site. But I saw that there is no such problem in some scrolling examples like this one. After a while I found a little difference - on my site the scrolling of the page is not on the html tag but on the of app's root tag.
Here you can find an example of the situation that I have - you can't scroll over the red block http://jsbin.com/rutogosesa/edit?html,css,output, and here an example where you can scroll over the red block http://jsbin.com/munixamuqo/edit?html,css,output.
My quesion is: how to allow scrolling in first example. I know that I can subscribe on onwheel event and move scrollbar mannually, but it looks weird as all browsers have smooth scrolling my implementation will broke its behaviour, especially for mac users. Maybe there are some other possible solutions?
Let's boil your trouble down to this: if the mouse is over #inner, you can't use the usual methods (spacebar, arrow keys, trackpad, wheel) to scroll #outer up and down.
If you need to keep everything you have, get around this by adding pointer-events: none to the inner element. (Note that this means you won't be able to interact with it at all - so any links in the inner element won't be clickable. Given the examples you gave in your question, that won't be a problem.)
html,
body {
height: 100%;
margin: 0;
}
html {
overflow: hidden;
}
#inner {
position: fixed;
background: red;
width: 200px;
height: 200px;
pointer-events: none; /* this is your fix. note it doesn't work in IE < 9 */
}
#outer {
overflow-y: auto; /* I changed this from "scroll". that may have been an inappropriate change, but it seems like it's probably desirable - you don't want the scrollbar to show even if the window is tall enough that you can't scroll */
background: blue;
height: 100%;
}
#push {
height: 2000px;
}
<div id="outer">
<p>top of #outer</p>
<div id="inner">
#inner
</div>
<div id="push" />
</div>
If you can get away with changing your html's styles, you can work around this by dropping the html {height: 100%; overflow: hidden}. This solution doesn't use pointer-events: none so you'll still be able to interact with the inner element!
html {
margin: 0; /* dropped html {height: 100%; overflow: hidden} */
}
body {
height: 100%;
margin: 0;
}
#inner {
position: fixed;
background: red;
width: 200px;
height: 200px;
}
#outer {
overflow-y: auto; /* I changed this from "scroll". that may have been an inappropriate change, but it seems like it's probably desirable - you don't want the scrollbar to show even if the window is tall enough that you can't scroll */
background: blue;
height: 100%;
}
#push {
height: 2000px;
}
<div id="outer">
<p>top of #outer</p>
<div id="inner">
#inner
</div>
<div id="push"></div>
</div>

Partially exposed div to slide up when image is clicked

this might be a weird one but what I am trying to do is make a div slide up from the bottom of the screen when someone clicks an image. To paint this clearer, imagine the Windows desktop, and if you click the start menu image/icon, instead of the start menu popping up from the button, the entire start menu bar would slide up exposing the entire div.
What I'm doing now (forgive me as I have just learned JS and jQuery from codecademy) is using the slideUp function. However, this is causing the div to slide down out of sight instead of up, exposing the entire div. The goal is that when you click the button the div slides up, and if you click the button again (or anywhere outside the div) it'll slide back down leaving the top 60px exposed like before.
Here's my JS/jQuery code:
$('#start').click(function() {
$('#nav').slideUp('slow');
});
My HTML
<div id="nav" class="nav">
<img id="start" src="img/btn_start.png">
</div>
My CSS
* {
padding: 0px;
margin: 0px;
}
body {
width: 100%;
font-family: Helvetica;
}
.nav {
width: 100%;
min-width: 100%;
height: 500px;
background: #000;
color: #fff;
position: absolute;
bottom: -440px;
text-align: center;
padding: 5px;
box-sizing: border-box;
overflow: auto;
}
.nav ul li {
display: inline;
}
.nav li {
padding: 20px;
margin-top: 80px;
position: relative;
top: 50%;
transform: translateY(-50%);
}
#start {
float: left;
}
Thanks, and I hope this isn't too ridiculous.
Instead of slideUp you should use
$('#start').click(function() {
$('#nav').animate({bottom: "0px"}, 1200);
});
...which will smoothly animate from the current location until the bottom is at 0px (i.e. aligned with the bottom of the containing element).
For even smoother results, checkout velocity.js (http://julian.com/research/velocity/), which does even smoother animation by synchronising with browser frame updates.
JsFiddle here: http://jsfiddle.net/11r46jnm/
You can also do this with CSS transitions instead. For stuff like this I like to hook my CSS into data attributes on the HTML:
<div id="nav" class="nav" data-nav-state="collapsed">
<img id="start" src="img/btn_start.png">
</div>
...use javascript to change the attributes...
$('#start').click(function() {
//toggle the nav element between two states
var currentState = $('#nav').attr("data-nav-state");
var newState = "collapsed";
if ( currentState === "collapsed" ) {
newState = "expanded";
}
$('#nav').attr("data-nav-state", newState);
});
Finally we use CSS to set the positions of the two states, and to ensure that transition is smooth. CSS transitions have much better performance than jQuery, so I recommend using them if you can:
#nav[data-nav-state=collapsed] {
bottom: -440px;
}
#nav[data-nav-state=expanded] {
bottom: 0px;
}
#nav {
transition: bottom 1.2s ease;
}
See this jsFiddle for a demo: http://jsfiddle.net/Lv2saepy/1/

Positioning a children div depending on screen size and parent div position

I have a div (which is a basically a button) that shows another div (which is basically a container for some items).
Check real world example:
And a working example in Plunkr.
As you can see, the container layer is placed below the button with
position: absolute;
which works fine if the button is somewhere in the upper left corner of the page, but not that fine if the button is somewhere on the bottom or somewhere on the right side of the page, as it's always shown below the button and expanded to the right. That causes the layer to be rendered outside of the webpage visible area and creates scrolls.
Is there any way I could do the following only with CSS:
if there is no enough space o the right, render the layer by placing the upper right corner of the layer to the lower right corner of the button.
if there is no enough space on the bottom, render the layer by placing it on top of the button.
Note that I don't know previously neither the width or the height of the layer.
This can be a HTML5/CSS3 solution, I don't need to support old browsers.
AFAIK is not possible. The possible way is detect it with javascript or if you only want to use CSS you must define the position classes. Example:
HTML
<div class="dropdown btm-right">
<span class="button">Button</span>
<div class="items">
<span class="item">Item</span>
</div>
</div>
CSS
.dropdown {
display: inline-block;
position: fixed;
}
.dropdown:hover .items {
display: inline-block;
}
.dropdown.btm-right {
bottom: 10px;
right: 10px;
}
.dropdown.top-right {
top: 10px;
right: 10px;
}
.dropdown .button {
position: relative;
z-index: 1;
}
.dropdown .items {
position: absolute;
display: none;
}
.dropdown.btm-right .items {
right: 0;
bottom: 100%;
}
.dropdown.top-right .items {
top: 100%;
right: 0;
}
Then we can use the btm-right or top-right class to position the dropdown. Thanks!

Div Items Move Up on toggle

I have four <div>. One of them is not displayed using display:none and is only displayed once you click an icon. When the item is clicked jQuery toggle function is called. One <div> is set to display:none and the one which was previously hidden is displayed. This is working perfectly but for some odd reason the page content moves 10 pixels or so up on toggle. I don't know what's causing it as all the <div> have same css and classes. Here is the css:
element.style {
margin-right: 5px;
margin-left: 10px;
left: 0px;
display: block;
}
#contactus {
background-color: #DDD;
position: relative;
position: relative;
left: 0;
}
#media (min-width: 1200px)
.span4 {
margin-left: 5px;
width: 320px;
}
span4 is the class for the toggled divs. Element styling is also the same. Can any one give me a hint what is causing this behavior. Here is the url:
http://contestlancer.com/davidicus/
You can see it the problem if you click on message icon besides the logo heading.
Ahmar.
add a height to your logo header eg
height: 90px;

How to always make page content appear beneath navigation bar?

I want to keep the content of my page to always appear beneath the navigation bar, similar to how this page works:
http://www.google.com/intl/en/enterprise/apps/business/products.html#calendar
You can scroll down or up in the content, but the navigation bar never goes away.
For this purpose, I've used position:fixed to fix the navigation bar to the top of the page. This works, but I'm still able to scroll the content up and down, causing it to run 'through' and over the navigation bar, when I want the content to always be pushed below the navigation bar.
Any ideas on how to do this? Here's my css code for the <ul id='navigation'> containing the navigation:
#navigation
{
text-align: center;
position: fixed;
float: left;
margin: 0;
padding: 0;
top: 0;
left: 0;
list-style-type: none;
}
#navigation li
{
display: inline-block;
width: 150px;
height: 110px;
cursor: pointer;
}
And here's the css for the <div id="container"> which appears below #navigation and holds all of the page content body:
#container
{
position: absolute;
margin-top: 180px;
font-size: 25px;
width: 90%;
}
The reason it's going through is because you didn't set a background color to your navigation bar. Try that.
Edit: Looked at your source code. Replace navigation CSS in style.css file with this:
#navigation
{
text-align: center;
position: fixed;
float: left;
margin: 0;
padding: 0;
top: 0;
left: 0;
list-style-type: none;
background-color: #FFFFFF;
z-index:999;
}
The problem was the z-index. Putting it at 999 puts the navigation bar on top of all other elements.
You can use the property z-index:xxx, did you try that?
Years ago created my site with that same functionality. I opted for Server Side Includes and it works great. I created a 'header' the navigation links and a 'footer' that gets included on each page.
Have you tried to add data-role="header" ?
<div data-role="header" data-position="fixed">

Categories

Resources