Make Divs Absolute Only To Each Other - javascript

I have <div> elements as pages, and "next" and "back" buttons to switch between them. When the "next" button is clicked, the current page fades out and the next page fades in, using jQuery. As I've been doing it so far, the only way to ensure that the divs sit on top of each other instead of sitting next to each other is to style them position:absolute. However, this forces the divs to also overlay anything else on the page that they would otherwise push out of the way.
Is there any way to make divs basically positioned absolute only relative to each other, and still act as though they are positioned relative to the rest of the page? I've tried putting them inside a container that is positioned relatively, but the divs overflow their container, making it more or less useless.
Edit:
Basic fiddle: http://jsfiddle.net/9AXS4/4/
Yes, I mix up $ and jQuery. I've been using jQuery a lot after calling jQuery.noConflict()

If your pages, as you call them, are of fixed width and height, then you can set their container to be position:relative and also have the width and height of the pages..
.container{
position:relative;
width:500px; /*the total width of a page, including padding and borders*/
height:400px; /*the total height of a page, including padding and borders*/
}
This way the container element will handle the pushing around of the other elements
Here is your corrected fiddle: http://jsfiddle.net/gaby/9AXS4/2/
(the width/height of the container must account for paddings and border on the page elements)
Also you were targeting the container with .pagecontainer instead of #pagecontainer (since you used an id)
Update (after comment about arbitrary heights..)
Since your pages height is not fixed, you will need to resort to jQuery to resize the container..
Here is a full demo : http://jsfiddle.net/gaby/9AXS4/7/

The divs can't be positioned absolute in relation to each other, but they can be positioned absolutely in relation to an outer div. The container that holds the page divs should have position: relative in order to contain the inner page divs that are absolutely positioned.
If there is unwanted overlap, you can use overflow: hidden or overflow: auto on the outer div to hide it, depending on whether or not you want to allow for scrolling. If you are going to use the overflow property, be sure to include a height and width so the browser knows where the overflow should be.
http://jsfiddle.net/vkTXs/
$(".page").each(function(){
jQuery(this).hide();
});
$(".page").first().show();
$(".next").click(function() {
jQuery(this)
.parent().fadeOut()
.next().fadeIn();
var page = $(this).parent().next();
resizeContainer(page);
});
$(".back").click(function() {
jQuery(this)
.parent().fadeOut()
.prev().fadeIn();
var page = $(this).parent().next();
resizeContainer(page);
});
function resizeContainer(page){
// get height of next page
var newPageHeight = $(page).height();
// add padding and border
newPageHeight = newPageHeight + 14;
$('#pagecontainer').height(newPageHeight);
}

Related

When div reaches bottom of window, stick and scroll over next div

I want to create this sliding scroll behavior in between divs. Let's say that the markup looks like this:
<main>
<div class="slide">Content</div>
<div class="slide">Content</div>
<div class="slide">Content</div>
</main>
Every .slide div would have different heights depending on the content inside them and would of course also change it's height depending on window size.
What I want is that when each div reaches it's bottom when scrolling the page, I. e. when the bottom of the div is at the bottom of the window, the div should become fixed and the div underneath should then scroll over the previous fixed div. And this behavior would be repeated for each div within the container (in this example main).
Do you have any ideas for how this could be achieved?
I figured that adding the following to each section through JavaScript (in my case jQuery just for this exercise) will make each div behave like I wanted on scroll:
$(".slide").each(function(){
$(this).css({
"top": `-${$(this).height() - $(window).height()}px`
})
})
Essentially applying a CSS top value that is the div height minus the window height.
This would also require the divs to have position: sticky applied to them through CSS.

Create Scrollable Div for Angular Chat

I am creating a chat application in Angular and I am trying to set up the UI for it. I need to create a div that will be housing the chat messages and as more messages fill the div I do not want the div to expand but just stay the same size and show a scroll bar. This div should be 100% the size of the parent div. As you click the button to add data the div grows. Even if I set a height in px or percent format the div still grows.
The page you link won't load but here are the basics to make a scrollable element:
HTML / JS Structure
Make an outer container div
Make an inner container div (this will be the "scroll wrapper")
Append the inner container to the outer container
Insert whatever you need into the inner container (you can use something like insertAdjacentHtml or whatever works for your specific situation)
This order of steps in particular will work well for a scenario where the contents are dynamically changing.
CSS
For the outer container
Set a fixed value for width and set height: auto
Set a border-radius if you want circular edges
Set overflow: hidden to keep the scroll wrapper's corners from popping out
You will probably want some padding
For the inner container
Set position: relative
Set overflow-y: auto and overflow-x: hidden so that you can scroll up and down, but not side to side
For the desired overflow behavior, you need to set width: 100% and set fixed values for max-height and min-height. (max-height decides when things will start to overflow ie. make a scroll bar)
You will want max-height and min-height to be less than the outer container's fixed width + any padding, etc. it may have.

Image resizes when position is changed to fixed on scroll

I would like an image to become fixed where it is once it appears on screen during a scroll, but become unfixed if the user scrolls back up.
However, when I use a JS on scroll function to change the image position to fixed, it suddenly "jumps"/resizes, and I'm not sure why. My fix was to create variables that alter the width and left values of the image after it becomes fixed, but I want to do this will multiple images on a page and each one seems to require a different width and left adjustment. I'm not sure what is conceptually causing this issue. Simply resetting the width and left to their original values does not work. Does a fixed position resize and image.
Here is a jsfiddle of the issue. And here is the code. JS:
var sitckyImageWidth = "38.4%";
var normalImageWidth = "48%";
document.addEventListener("scroll", function(){
var windowTop = $(window).scrollTop();
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
//loop through each div and grab top/bottom/midpoint info and find id
$('.articles').each(function(i){
var top = $(this).offset().top;
var bottom = top+ $(this).height();
var midPoint = (bottom+top)/2;
var thisId = this.id;
var newId;
//use container div info to find media info
var newId = thisId+"Media";
var sectionImage=document.getElementById(newId);
var sectionImageTop = $(sectionImage).offset().top;
//if article is on the page, change position to fixed and set top position
if (top<=windowTop&&bottom>windowTop){
$(sectionImage).css("top","10px")
$(sectionImage).css("position","fixed")
//$(sectionImage).css("width",sitckyImageWidth)
}
//if container is not at top of the page, return to relative
if (bottom<=windowTop||(bottom>windowTop&&top>windowTop)){
$(sectionImage).css("position","relative")
}
})
}); //end scroll
Position fixed means that an element will have relative sizes and positioning in relation to the viewport, not their parent elements.
Specifically what is happening here is that your div with ID article1Media is set to have a width of 48%. When it has the CSS property of position: relative then that resolves as 48% of the width of it's containing element (the div with id article1) however when it is position fixed that resolves as 48% of the width of the viewport. Since there is an implicit 8px margin on the <body> element then these are different.
There are a few different solutions to this, and how you tackle it depends on how you want to build your site.
Example fix 1
A simple fix for your immediate example is to simply add the following CSS.
body{
margin:0px;
}
.image{
margin:8px;
}
https://jsfiddle.net/Chipmo/k56qkk5b/13/
This moves the implicit margin onto the image element. Of course you can set it to whatever you like, or omit it entirely.
Look into CSS resets for more information about overriding implicit default styles, though be warned that it is possible to cause problems with overzealous reset codes.
( Edit: To be clear the above code is definitely not a drop in code for this problem everywhere. It will only work on quite simple HTML pages like your jsFiddle. )
Example fix 2
Another technique you could consider is locking the width and height to it's initial values using jQuery .width() and .height() functions. This would be inflexible, and you would have to do extra work to make it responsive (for mobile etc), but could be appropriate in some circumstances.
Example fix 3
A more portable solution might be to eschew relative sizing in favour of fixed widths and then use CSS media queries for reponsivity. Something like this:
.image{
width:500px;
}
#media(min-width:800px){
width:300px;
}
Example fix 4
If you wish to preserve the 'fluid' nature of using percentages I would suggest looking into using calc along with an offset that gets applied when the position is fixed (so, you add a class when you make the image fixed) that adjusts the sizing appropriately.
.media.image-fixed{
position:fixed;
width:calc(48% - 8px);
}
See this example https://jsfiddle.net/Chipmo/6mu2Lt9g/2/
Above behavior is observed since because of applying the position property not because of the scroll.Please take a look at the following link Position Properties
Position Fixed : Fixed position elements relative to document not on
any parent container.Hence occupies the complete width available.
Position Relative: Relative positioned elements behaves relative to hosted
containers.And inner elements consumes the hosted parent width.

Fixed placed element within certain area

I have a page where I display a long list of results from a DB query.. and I also show a Google Map to the RIGHT of this long list.
Map is roughly 240px wide and maybe 600px long/height.
This MAP is inside a container DIV (#mapContainer).. that contains the map, and a dropdown box above the map canvas.
Currently, the mapContainer scrolls along with the page itself.. what I would like to do is have it be static/fixed element. So it starts/displays/is placed where I have it currently on the page.... if I scroll the page.. the map should stay fixed.. until the end (bottom) of the results are scrolled to..
(I dont want the mapContainer to scroll and cover the footer element/div)
Following this tutorial:
http://www.webgeekly.com/tutorials/jquery/a-simple-guide-to-making-a-div-static-as-you-scroll-past-it/
It doesnt stay fixed..
//sticky map placement
$(function () {
var msie6 = $.browser == 'msie' && $.browser.version < 7;
if (!msie6) {
console.log("NOT IE 6");
var top = $('#mapContainer').offset().top;
$(window).scroll(function (event) {
console.log("scrolling.......");
var y = $(this).scrollTop();
if (y >= top) {
$('#mapContainer').addClass('fixed');
console.log("class added");
}else {
$('#mapContainer').removeClass('fixed');
console.log("class removed");
}
});
}
});
The first console.log() outputs fine.. but nothign in the window.scroll() portion fires ever.
Rest of code used:
#mapContainer{
display:table;
width:240px;
float:right;
/* sticky map */
position: absolute;
top: 458px;
left: 50%;
/* width: 100px; */
margin-left: 339px;
}
#<span class="skimlinks-unlinked">mapContainer.fixed</span> {
position: fixed;
}
On the tutorials page itself.. he has a toolbar on the left side..
that stops 'being fixed' when you scroll all the way to the top.. (it will start to move with the rest of the page scroll at a certain point).. and it doesnt go all the way down to cover the footer either.
I'm not clear why the jQuery portion isnt firing.. and I'm not clear what that last style is for? (seems odd looking)
All this absolute, fixed, relative, to parent, to viewport..etc.. is confusing.
Any easy to read/follow/understand tutorials that will get me to where I want to be? Or suggestions on what I am doing wrong with the correct approach?
I looked at your Fiddle and noticed a couple things:
Your "fixed" class was not represented in the CSS. When I looked into the CSS I saw a span element wrapping a ".fixed" reference with a position property set.
You are styling the mapContainer div using the ID. This is a very rigid selector as the order of CSS selectors goes. The hierarchy of CSS selectors is specifid and IDs will override types and classes. See: http://htmlhelp.com/reference/css/structure.html
The when scrolling, I am seeing the console logging in my dev tools. Also, when inspecting the element, I am seeing it add and remove the class name.
Based on my observations, modifying the CSS selector for your container should do the trick. Adding the ID to the class will keep the CSS rule specific enough:
#mapContainer.fixed { position: fixed; }
Refer to this updated Fiddle for an example with these changes in place:
http://jsfiddle.net/pmurst8e/4/
Update: For demonstration purposes of what I was referring to with the resize I modified your example a bit. It isn't the prettiest, but it conveys the point: http://jsfiddle.net/pmurst8e/6/
Update: There are a couple issues with the latest Fiddle (v12):
The sidebar will always go fixed the moment you scroll because "top" is never calculated. It's being set to zero, and the offset calculation is commented out.
Absolute positioning is relative to the closest positioned parent. If no parent is positioned, it's relative to the window. To constrain an absolute positioned element, set the constraining parent to "position:relative;".
Instead of using a percentage and left position rule, consider positioning the sidebar to the right, relative to the "contentContainer", by a set number of pixels.
When the fixed position takes effect, we also need to set the sidebar fixed left position. Otherwise, it will use the positioning in the CSS. In contrast to absolute positioning, Fixed positioning is relative to the window, meaning an absolute element "right: 10px" will be 10px from the right of the positioned parent, but will appear 10px from the right of the window when fixed.
You don't need a float when you have absolute positioning. Absolute position removes an element from the normal flow of the document, and because of this float does not apply.
I updated the Fiddle to show how to make these adjustments. I cleaned out the float and margin from the mapContainer and left the absolute positioning. With that I set the contentContainer to relative to constrain mapContainer to it. You will also see, on the script side, I added a line to set the offset of mapContainer. Without this, when it becomes fixed it will be 10px off the right border of the window.
Updated Fiddle: http://jsfiddle.net/pmurst8e/14/
Also, you want to leave your top offset line in tact. Without that, it goes fixed the moment the scroll moves and never goes back. When that becomes the case, you're better off just setting fixed permanently.
var top = $('#mapContainer').offset().top; // you want this
Regarding the bottom boundary, you can do a couple things:
Resize the sidebar so that it shrinks to the window size. This is demoed in my example from my first post in this and the downside is it forces the sidebar to become a scrollable div so the child content is all visible.
Use a check for the bottom so that when you hit the limit, the container goes back to an absolute position, but one set at the bottom: 0 of the parent.
Something like:
var limit = $('footer').offset().top;
var $mc = $('#mapContainer');
var pos = $mc.offset().top + $mc.outerHeight();
if (pos >= limit) {
$mc.removeClass('fixed')
.addClass('bottom-set').css('left',''); // define this in CSS for bottom absoluteness
}
#mapContainer.bottomFixed {
bottom: 0;
top: auto;
}
And to be fully honest, you might save yourself some time working this all out if you take a look at the ScrollToFixed plug-in (https://github.com/bigspotteddog/ScrollToFixed). I seem to be mentioning it quite a bit lately, but this issue seems to be a popular one right now.
Incidentally, go to your OP and click the Edit button. Shrink the height of your browser and scroll down. You should see SO has a fixed sidebar that passed the footer. ;)

position:fixed for a floated div

I have a div that is floated left in a wrapper container. Now I want the div to stay in one spot when the page is scrolled. So I tried position:fixed, but this ruins the other css properties of the div.
I've tried using javascript aswell:
$(window).scroll(function () {
$("#id").css({'top',$(window).scrollTop() + 'px'});
});
That javascript isn't doing anything. Is there any other way to do this, I still want to keep the float:left property intact.
Thanks
See all the elements with different position attributes form different layers. So you have to adjust other elements when you keep this element 'position:fixed'
You have to keep empty space for this div forever, and it will stay fixed there even when you scroll your page.
See this link for better understanding
http://davidwalsh.name/demo/css-fixed-position.php

Categories

Resources