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
Related
I'm trying to emulate position: fixed; using javascript, the reason being that the element has to be inside a scrollable div (overflow-scroll-y), and position: fixed; only works relative to the window scroll, not an elements scroll, though normally in a case like this I could fix it by using position: absolute; and everything would just work, but the scollable div / container element needs to have perspective: 1px; which brakes the position: absolute; adjustment, so back to just js emulation.
Now it works, with javascript, but all too often the element in question lags a bit behind the scroll, creating a kind of "jumpy" feeling (it's especially bad on Firefox), that is say it's fixed at the top of the element, if the user scrolls it's suppose to be exactly at the top always, but in reality it sometimes goes a bit (or allot) too high or low, depending on the scrolling direction, and then snaps in place again, this snapping or jumpy effect is undesirable, and is not present in cases where you can fix the element using either position: fixed; or position: absolute;.
I've made a jsFiddle Example, if you don't notice the undesirable effect in your browser you can try uncommenting the increaseLag function, on my computer the lag is clearly visible on Firefox but not as noticeable on Chrome unless I enable the increaseLag function (I'm running Ubuntu).
How could one tackle this? Is there perhaps a pure css solution I'm missing or an alternative js route?
My current buggy solution uses a scroll event on the container element which updates the top css property of the "fixed" element relative to the updated scroll position.
$("#container_element").scroll(function() {
//increaseLag(this);
var scrollTop = $(this).scrollTop();
$(".fixed_emulation").css("top", scrollTop+"px");
});
#container_element {
width: 100%;
height: 100%;
overflow-y: scroll;
perspective: 1px;
}
.fixed_emulation {
background-color: #000;
color: #FFF;
position: absolute;
top: 0;
width: 100%;
}
<div id="container_element">
<div class="fixed_emulation"> :) </div>
<p>Text text text. Text text. Text.</p>
<p>Text text text. Text text. Text.</p>
<p>Text text text. Text text. Text.</p>
...
</div>
I've looked through a variety of other posts, and to no avail, I have yet to find the kind of solution I'm looking for. Many solutions involved people using CSS with methods like fixing the right and left (which wouldn't make it worth floating and a waste of brain power) or to word-wrap at a certain amount to the right (which also defeats the purpose of what I'm trying to do.
My problem exists like this:
I have 3 divs: wrapper, menu, and content. Wrapper is used to apply a background to 100% of the page, and create extra styling properties to be inherited by other CSS. Menu is for my menu script I coded in JQuery and it takes up 400px of space on the left hand of the screen and descends downwards at 100vh. I may change it to fixed, but it doesn't change the issue. Anyway, content is the rest of the page; let's say the other 80% of it. I have both menu and content floating left and it works just fine. However, until text wraps at the end of the screen, the div goes under (disappears in my case) the screen and no longer viewable.
My solution:
function simplyWidth(changed, menu1, wrapper){
var wrapperWidth = $(wrapper).width();
var menuWidth = $(menu1).width();
var newWidth = wrapperWidth - menuWidth;
$(changed).css("width", newWidth);
};
Does it work? Of course it works. The only problem is, it isn't dynamic at all! It resizes to the screen once, and you have to refresh the page just to get it to update again. Is there a way to take that JQuery/Javascript and make it so I can just update it every .1 of a second? Would that make the page lag? Or am I doing it wrong.
Also assume that my HTML is spot on, and it needs no corrections. The reason I won't disclose it is because there's too much there for me to post and to not confuse the living crap out of you people.
This is the basic layout of my page:
<div id="wrapper">
<div id="menu1"></div>
<div id="content"></div>
</div>
As for my wrapper CSS:
#wrapper {
width: 100%;
background-color:black;
margin: 0 auto;
top: 0px;
overflow:hidden;
height: 100vh;
background-image:url(Assets/background1.jpg);
}
Menu1 CSS:
#menu1 {
margin: 0 auto;
height: 100%;
width: 400px;
background-color:#191919;
color:white;
z-index: 400;
float: left;
}
Content CSS:
#content {
float:left;
color:white;
height: 100vh;
}
listen to resize event and call the same function when the window is resized:
$(window).resize(simplyWidth);
So I have a header bar for a page I made with a height of 150px. Under that area I want another DIV to fill the remaining space (width and height) all across the screen and to the bottom of the screen. I've tried setting height: 100% for the DIV, but that causes the screen to become scrollable and I only want it to fill the remainder of the page. NOTE: There is NO footer or anything under it.
Using jQuery/Javascript is acceptable, but CSS-only is prefered (if possible). If using jQuery, please explain the proper way to have it implemented into the page (I'm assuming $(function() {...}); under the <style> tag in the head.
I've tried searching for a result before, but nothing seems to work correctly.
tl;dr I basically made 3 options for you. click on the 'like this' in the below paragraph to see what they all look like without any text. Click on the A). B). and C). links in the paragraphs below that to see the difference between the three options. Check how each one scrolls differently, they are all different I promise. After you look at all three you can read how the one you want is implemented. (that is if you like any of them.) Hope you like it, no problem if you don't :)
I'll have a go at this, because it honestly depends on what you're going after there are multiple ways to look at it and it depends on your end goal. I will cover three possible scenarios: (which all look the same without text mind you, like this, but if you want to see what they look like with text click the letters. Make sure you scroll the page to see the difference between them.)
(Just as a side note I based A). and B). off how Twitter Bootstrap does it.)
A). You just want it to look like one div on top of the other (header div on top of main-content div) and display like that, but you still want the page to scroll if the 2nd div's text overflows. In this implementation when they scroll will move the header out of view, but if you don't want the header div to move out of view that leads me to
B). Same as the first header div on top of main-content div, but when they scroll the header div will still stay in place at the top instead of moving out of view.
and last of all,
C). You really do want the div to stretch to the bottom of the screen and never have the scroll bar for the whole page. This could be used in some cases, for instance, Spotify makes a nice music app with this kind of style so that you never scroll the whole page just panes in the page.
Ok so first here is the html code used to construct all three of them
<body>
<div class="header"></div>
<div class="main-content"></div>
</body>
And now to the fun part...
I will provide a Fiddle for the following examples, and with the css I will put the necessary code at the top and the unneccessary code at the bottom. (The html may have some unneccasary text so just ignore that. I just want you to see the page scrolls differently on the three.)
A).
no need to rephrase what it is so I'll just show you the code that is necessary.
First, here is A). without the text just so you can see what it looks like the others until the content gets too large.
Here is the fiddle with the text so you can see how it differs.
Here is the necessary css for A). (the background-color isn't completely necessary, but it is somewhat necessary to show the point.)
body {
padding-top: 150px;
background-color: #ddd;
}
.header {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 150px;
background-color: #676767;
}
and now for...
B).
First, here is B). without the text just so you can see what it looks like the others until the content gets too large.
Here is the fiddle with the text so you can see how it differs.
Here is the necessary css for B).
body {
padding-top: 150px;
background-color: #ddd;
}
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 150px;
background-color: #676767;
}
As you can probably tell the only difference is the position: fixed on the .header, but look at the two examples to see the difference it makes.
and now last of all C).,
C).
First, here is C). without the text just so you can see what it looks like the others until the content gets too large.
Here is the fiddle with the text so you can see how it differs, and with I'll call option 1 where it has a scroll bar just for that area's overflowing content.
Here is the fiddle with the text so you can see how it differs, and with I'll call option 2 where it hides the overflowing content. (This is honestly bad practice and I wouldn't do it. So if I may suggest. I would go with option 1 of C).)
Here is the necessary css for C).
body {
padding-top: 150px;
}
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 150px;
background-color: #676767;
}
.main-content {
position: fixed;
top: 150px;
left: 0;
right: 0;
bottom: 0;
background-color: #ddd;
}
I won't explain it, but here is an article on positioning that will.
here is the only necessary css for option 1 is adding overflow-y: auto to .main-content, but if you want to go with option 2 which I don't suggest you can go with overflow-y: hidden on .main-content
Well that's all for my post which is probably too long for most people sorry if I bored you, but I'm just trying to help. Hope you figure out the layout you want. This is only a few examples of the layouts possible with good old css. If you don't get the layout you want from this or any other post feel free to send me a message by commenting below, and I'll be happy to answer it sometime. Hope this helped. If it didn't that's fine too. :)
You can try css3 flexbox.
http://jsfiddle.net/wL9aM/1/
.container {
display: -webkit-flex;
display: flex;
flex-direction: column;
height: 700px;
}
.header {
height: 200px;
background: red;
}
.main {
-webkit-flex: 1;
flex: 1;
background: blue;
}
try using script..
var window_h = $(window).height();
var header_h = $("header").height(); //This is what you said you had 150px
$(".filler_div").height(window_h - header_h);
You can also put that inside a function() so that you can add it also when you resize the browser, the filler space also adjusts...
function setfillerDivHeight(){
//the code above
}
$(document).ready(function(){
setFillerDivHeight(); //the initial setting of height
});
$(window).resize(function(){
setFillerDivHeight(); //reapply setting of height when window resizes
});
<div class="full-page-height-wrapper">
<header></header>
<main></main>
</div>
html,body {
height: 100%;
margin: 0;
}
header {
height: 150px;
}
.full-page-height-wrapper {
min-height: 100%;
position: relative;
}
CODE: http://fiddle.jshell.net/N7zJg/9/
preview: http://fiddle.jshell.net/N7zJg/9/show/
I don't think you cannot acheive that in pure CSS.
So, there is two different solutions:
1) You can put the 150px div in the 100% div.
2) You can do it with jQuery:
If your top div is <div id="A"> and the second one is <div id="B">, you'll have:
var b = $("#B");
var height = $("body").height() - b.position().top;
b.css({ height: height });
Feel free to adapt the code if you have some margins.
Found a solution myself finally. Doing it this way makes the design more responsive since (if i choose to add something to the bottom), it will automatically resize the div's height.
.container {
display: table;
}
.row {
display: table-row;
}
.column {
display: table-column;
}
#fullDiv {
height: 100%;
}
I found two solution.
The one is that I have must set the div in the absolute position.
the div float over the screen.
another one is use table-row display.
If you use just CSS, you cant achieve your task by giving 100% height to div. Because what basically CSS is doing is giving 100% height to your DIV plus giving 150 px to above header. Consider giving height of DIV less than 100% or some static value such as 600px or 700px.
Alternate is having a class of DIV with min-height 100% and inside it putting your header and body.
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'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