Clear absolutely positioned elements with CSS possible? - html

Is there any way to clear absolutely positioned elements with CSS? I'm creating a page where I need each part of the site (section element) to be absolutely positioned, and I want to apply a footer with content below those elements.Tried to relatively position the header and footer to see if a total height would be taken into account but the footer still gets "trapped" underneath the section elements. Any ideas?
<header style="position: relative;"></header>
<div id="content" style="position: relative;">
<section id="a" style="position: absolute;"></section>
<section id="b" style="position: absolute;"></section>
<section id="c" style="position: absolute;"></section>
<section id="d" style="position: absolute;"></section>
<section id="e" style="position: absolute;"></section>
</div>
<footer style="position: relative;"></footer>

Absolutely-positioned elements are no longer part of the layout - parent items have no idea how big absolutely-positioned child elements are. You need to set the height of "content" yourself to ensure it does not overlap the footer.

Don't use absolutely-positioned elements for layouts since that elements are removed from normal flow and no longer affect elements around them. And they're not affected by other elements.
Use absolute-positioning to move elements within a container when conditions allow.
For floated elements I suggest you to use a specific clearing technique called clearfix. I use it religiously.
http://nicolasgallagher.com/micro-clearfix-hack/
http://jsfiddle.net/necolas/K538S/

Had same question, made all absolute positioned, but let the first one be relative, as for responsive layout where height does change, it did help to keep track of the elements height changes, notice in this case all elements have same height:
.gallery3D-item {
position: absolute;
top: 0;
left: 0;
}
.gallery3D-item:first-of-type {
position: relative;
display: inline-block;
}

I discovered a easy solution to this, it might not cover all possible problems but at least it solved my problem.
HTML:
<p>Content before</p>
<div class="offset-wrapper">
<div class="regular">
<img src="https://www.gravatar.com/avatar/bdf0bf75e96fa18e57769865ebeb9a6e?s=48&d=identicon&r=PG" />
</div>
<div class="special">
<img src="https://www.gravatar.com/avatar/bdf0bf75e96fa18e57769865ebeb9a6e?s=48&d=identicon&r=PG" />
</div>
</div>
<p>Content after</p>
CSS:
.offset-wrapper {
background: green;
position: relative;
width: 100px;
}
.offset-wrapper .regular {
visibility: hidden;
}
.offset-wrapper .special {
bottom: -15px;
left: -15px;
position: absolute;
}

Related

Why does an image of position:absolute have no height? When I can see in the browser it has height

I am trying to understand why a div with display:block will not sit under another div with display:block
My mark-up is this:
.container{
display: block;
position: relative;
}
.container img{
width: 100%;
position: absolute;
top:0;
left:0;
}
.container .text-left{
position: absolute;
top:35rem;
left:35rem
}
.container .text-right{
position: absolute;
top:35rem;
right:35rem
}
<div class="container" >
<img src="/image1.jpg" alt="">
<div class="text_left">
<h2>HEADING 1</h2>
</div>
</div>
<div class="container" >
<img src="/image2.jpg" alt="">
<div class="text_right">
<h2>HEADING 2</h2>
</div>
</div>
I am trying all sorts of stuff to make this work - overflows etc - but can't seem to get the second display block div to sit under the first.
EDIT: It seems that if you put position:absolute element/s inside a position:relative element - that may have height due to that element being an image - the absolute element/s removes this height. So you need to add it back in as height: X.
But why??
Is this due legacy mark up - using absolutes in ways not designed for?
Why would the browser not take into consideration the image height as default. And we could override this if needed.
Can anyone please enlighten me?
thanks
The reason you have lost height is because position:absolute; removes element from the flow, therefore your parent container won't be able to use it to work out its height. It's not legacy markup, it's part of the scope.
A quick excerpt from CSS-Tricks
The trade-off (and most important thing to remember) about absolute positioning is that these elements are removed from the flow of elements on the page. An element with this type of positioning is not affected by other elements and it doesn't affect other elements. This is a serious thing to consider every time you use absolute positioning. Its overuse or improper use can limit the flexibility of your site.
If for whatever reason you are required to have that specific element as position:absolute; your next best bet would be to adjust the parent container using JavaScript/jQuery, however that might be a bulky fix.
My suggestion would be to try and achieve your preferred layout without using the absolute positioning, and then if you get stuck, post another question here explaining your desired layout and current code trying to achieve it.
EDIT
That being said, if the mentioned JavaScript/jQuery solution does not sound to bulky to you, you could try the following:
$('.container').each(function(){
$(this).css({
'padding-top': $(this).find('img').height()+'px'
});
});
This will add padding-top to the container based on the image size. Alternative, you could add an empty div below the image and adjust its height based on the image size.
To make it work just make the img and test_* position to relative instead of absolute. Why ? Position absolute removes element from the flow, that means that because all your container's childrens are absolute, it is like your container has no content, that's why it collapse.
.container{
display: block;
position: relative;
}
.container img{
width: 100%;
position: relative;
top:0;
left:0;
}
.container .text_left{
position: absolute;
top:90%;
left:5%;
color: #fff;
}
.container .text_right{
position: absolute;
top:90%;
right:5%;
color: #fff;
}
<div class="container" >
<img src="https://placeimg.com/640/480/any" alt="">
<div class="text_left">
<h2>HEADING 1</h2>
</div>
</div>
<div class="container" >
<img src="https://placeimg.com/640/480/any" alt="">
<div class="text_right">
<h2>HEADING 2</h2>
</div>
</div>

Two CSS absolute positioned items in one page

I have a design that requires an absolute positioned object on the top of the page. (menu inside of a circle)
Then about 5 row later (using foundation) I have a second absolute positioned element. But its position is based on the previous element because once you apply position: absolute to one element, you’ll usually find yourself applying it to everything else. So even if the rows are positioned relative by default, it doesn't reset the absolute position, so the element is floating to the beginning of the page.
I can position it but if I add an element I have to touch up the CSS so this is not good.
So how do you reset absolute position, I tried to have elements before my second element static and the other absolute but it does not work.
The first element is based on this Gist, then later the code is:
.or {
position: absolute;
background-image: url(../assets/img/OR.svg);
top: 50%;
left: 50%;
margin: -42px;
width: 84px;
height: 84px;
background-size: 84px 84px;
z-index: 50;
}
That's it for the HTML
<div class="row" data-equalizer>
<div class="small-6 columns text-center">
<div class="panel " data-equalizer-watch>
this is the content
</div>
</div>
<div class="or" > OR</div>
<div class="small-6 columns text-center">
<div class="panel" data-equalizer-watch>
this is the content
</div>
</div>
</div>
This is the Or part that need to be centered no matter the content on the side here it is regular but not on all the page
The solution was simple (like always) is is to put relative to the parent div

Stop absolutely positioned div from overlapping text

Here is a simplification of my layout:
<div style="position: relative; width:600px;">
<p>Content of unknown length, but quite quite quite quite quite quite quite quite quite quite quite quite quite quite quite quite long</p>
<div>Content of unknown height</div>
<div class="btn" style="position: absolute; right: 0; bottom: 0; width: 200px; height: 100px;background-color: red;"></div>
</div>
The problem I'm having is that if the text/unknown div content is too long it is overlapping my absolutely positioned div.
I have searched the web and SO for a solution and the only one I found suggested putting an invisible div where absolutely positioned div is - trouble is if I could do that I wouldn't need to have the absolutely positioned div in the first place (or am I missing the point here).
Can anyone think of a css solution before I go down the jquery route?
The solution for me was to create a second invisible div at the end of the content of unknown length, this invisible div is the same size as my absolutely positioned div, this ensures that there is always a space at the end of my content for the absolutely positioned div.
This answer was previously provided here:
Prevent absolutely-positioned elements from overlapping with text
However I didn't see (until now) how to apply it to a bottom right positioned div.
New structure is as follows:
<div id="outer" style="position: relative; width:450px; background-color:yellow;">
<p>Content of unknown length</p>
<div>Content of unknown height </div>
<div id="spacer" style="width: 200px; height: 25px; margin-right:0px;"></div>
<div style="position: absolute; right: 0; bottom: 0px; width: 200px; height: 20px; background-color:red;">bottom right</div>
</div>
This seems to solve the issue.
Short answer: There's no way to do it using CSS only.
Long(er) answer: Why? Because when you do position: absolute;, that takes your element out of the document's regular flow, so there's no way for the text to have any positional-relationship with it, unfortunately.
One of the possible alternatives is to float: right; your div, but if that doesn't achieve what you want, you'll have to use JavaScript/jQuery, or just come up with a better layout.
If you are working with elements of unknown size, and you want to use position: absolute on them or their siblings, you're inevitably going to have to deal with overlap. By setting absolute position you're removing the element from the document flow, but the behaviour you want is that your element should be be pushed around by its siblings so as not to overlap...ie it should flow! You're seeking two totally contradictory things.
You should rethink your layout.
Perhaps what you want is that the .btn element should be absolutely positioned with respect to one of its preceding siblings, rather than against their common parent? In that case, you should set position: relative on the element you'd like to position the button against, and then make the button a child of that element. Now you can use absolute positioning and control overlap.
Put a z-indez of -1 on your absolute (or relative) positioned element.
This will pull it out of the stacking context. (I think.) Read more wonderful things about "stacking contexts" here: https://philipwalton.com/articles/what-no-one-told-you-about-z-index/
Thing which works for me is to use padding-bottom on the sibling just before the absolutely-positioned child. Like in your case, it will be like this:
<div style="position: relative; width:600px;">
<p>Content of unknown length, but quite quite quite quite quite quite quite quite quite quite quite quite quite quite quite quite long</p>
<div style="padding-bottom: 100px;">Content of unknown height</div>
<div class="btn" style="position: absolute; right: 0; bottom: 0; width: 200px; height: 100px;background-color: red;"></div>
</div>
<div style="position: relative; width:600px;">
<p>Content of unknown length</p>
<div>Content of unknown height</div>
<div id="spacer" style="width: 200px; height: 100px; float:left; display:inline-block"></div>
<div class="btn" style="position: absolute; right: 0; bottom: 0; width: 200px; height: 100px;"></div>
</div>
This should be a comment but I don't have enough reputation yet. The solution works, but visual studio code told me the following putting it into a css sheet:
inline-block is ignored due to the float. If 'float' has a value other than 'none', the box is floated and 'display' is treated as 'block'
So I did it like this
.spacer {
float: left;
height: 20px;
width: 200px;
}
And it works just as well.
Could you add z-index style to the two sections so that the one you want appears on top?
You should set z-index to absolutely positioned div that is greater than to relative div.
Something like that
<div style="position: relative; width:600px; z-index: 10;">
<p>Content of unknown length</p>
<div>Content of unknown height</div>
<div class="btn" style="position: absolute; right: 0; bottom: 0; width: 200px; height: 100px; z-index: 20;"></div>
</div>
z-index sets layers positioning in depth of page.
Or you may use floating to show all text of unkown length. But in this case you could not absolutely position your div
<div style="position: relative; width:600px;">
<div class="btn" style="float: right; width: 200px; height: 100px;"></div>
<p>Content of unknown length Content of unknown length Content of unknown length Content of unknown length Content of unknown length Content of unknown length Content of unknown length Content of unknown length</p>
<div>Content of unknown height</div>
<div class="btn" style="position: absolute; right: 0; bottom: 0; width: 200px; height: 100px;"></div>
</div>​
I'm responding because I also ended up in this post and found a simple and effective solution: the absolute element has a fixed position and size, so you simply need to add right padding of 400px (referring to your example) to your content
put texts into a new div. Then make that div also position: absolute; . Also, you can use overflow: hidden; for that div.

Relative z-index?

I've got a "Dialog" widget that pops up with a z-index of 100. When I create another popup (a floating div), it appears underneath the dialog widget, because I haven't explicitly set the z-index on the new popup.
The structure ends up looking something like
<div id="dialogbox" style="z-index: 100">
<div>
<div id="widgetThatCausesThePopup" />
</div>
</div>
<div id="popupHiddenBehindTheDialog" />
I'm using GWT to generate this HTML. There can be arbitrary levels of nesting between dialogbox and widgetThatCausesThePopup, and the actual z-index may be arbitrary as well.
How can I ensure that the new div will be shown in front of the dialogbox?
If your new dialog windows are inserted in the DOM after the previous ones:
You can set the z-index: 100 on all dialog windows. When elements with the same z-index are found, order in the DOM determines which is on top.
The natural CSS solution is to:
Make sure, that "dialogbox" gets a stacking context. This can be done by
setting z-index to something else than auto,
and additionally position to either relative, absolute or fixed.
Then add your popup as a child to "dialogbox". If it isn't yet, you can always move it in the DOM.
In that case, your popup doesn't need a z-index at all. This completely avoids the "z-index hell".
Example:
<!doctype html>
<html>
<head>
<style type="text/css">
#dialogbox {
width: 400px; height: 300px;
top: 0; left: 0;
background-color: red;
}
#popup {
width: 500px; height: 200px;
top: 0; left: 0;
background-color: green;
}
</style>
</head>
<body>
<div id="dialogbox" style="z-index: 100; position: absolute;">
<div>
<div id="widgetThatCausesThePopup" >
<button>Show popup</button>
</div>
</div>
<div id="popup" style="position: absolute;">
<!-- Empty divs cause really weird problems.
Always make sure, that your divs aren't empty! -->
</div>
</div>
</body>
</html>
The stacking context even allows you to use z-indexes relative to the context, if you need them (note, that the child order doesn't matter, and the z-indexes don't have to be larger than 100):
<div id="dialogbox" style="z-index: 100; position: absolute;">
<div id="popup" style="position: absolute; z-index: 2;">
<!-- Empty divs cause really weird problems.
Always make sure, that your divs aren't empty! -->
</div>
<div>
<div id="widgetThatCausesThePopup" style="position: absolute; z-index: 1;">
<button>Show popup</button>
</div>
</div>
</div>
Get the computed z-index of the parent (see In GWT how to know all the styles applied to a given element (by id or class name)) and increment it for each child.

CSS overflow hidden

I have a container div. Inside that div are three graphs aligned at 700px intervals (the width of the container). The idea is that the other 2 graphs will be hidden off screen which I can then, with jQuery, slide across when a user interacts with various controls on the web page.
A simplified version of my code is like so:
Style
#graphcontainer {
height: 260px;
overflow: hidden;
width: 700px;
}
.graph {
position: absolute;
}
HTML
<div id="graphcontainer">
<div class="graph" style="left: 0px;"></div>
<div class="graph" style="left: 700px;"></div>
<div class="graph" style="left: 1400px;"></div>
</div>
For some reason the second and third graphs, which are positioned off to the right, are still visible! How do I ensure they are not visible?
First you have to set, position:relative for the parent. Then, you have to set the height of the parent.
Demo: http://jsfiddle.net/Scfdk/
You need to add position: relative; and set a height to the element you have overflow set to hidden on.
if you want to hide a div, have you considered "display: none"? For example,
<div class="graph" style="display: none"/>