Elements taking over the space of an element with position absolute - html

I am trying to have a div at the top of my page that fits with no space against the top and sides.
All the example I have seen on how to do this put the div position to absolute.
But when I do this, the following img sibling moves to the top of the page with the previous div.
So I have two questions. Why does the following sibling move? Also, how can I have a div fit with 0 space against the top, without having position:absolute
div {
position: absolute;
top: 0px;
left: 0px;
background: #888888;
width: 100%;
height: 100px;
}
<body bgcolor="#000000">
<div>
<h1>HEADER</h1>
</div>
<img src="pic_mountain.jpg" alt="Mountain View" style="width:304px;height:228px;">
</body>
</html>

You don't need position: absolute to align things to top just use margin: 0 on the body, h1 Like:
body, h1 {
margin: 0;
}
Have a look at the snippet below:
body, h1 {
margin: 0;
}
div {
background: #888888;
width: 100%;
height: 100px;
}
<!DOCTYPE html>
<html>
<body bgcolor="#000000">
<div>
<h1>HEADER</h1>
</div>
<img src="http://placehold.it/304x228" alt="Mountain View" style="width:304px;height:228px;">
</body>
Hope this helps!

When you give an element position: absolute, you remove it from the normal flow of the document. This means that it no longer takes up any space in the layout. As a result, surrounding elements don't know it exists and take over the previously used space.
But you don't need absolute positioning in this case. The reason for the gaps are default margins on elements set by the browser. Just override those defaults with your own settings.
body, h1 {
margin: 0;
}
div {
height: 100px;
background: #888888;
}
<body bgcolor="#000000"bgcolsor="#000000">
<div>
<h1>HEADER</h1>
</div>
<img src="pic_mountain.jpg" alt="Mountain View" style="width:304px;height:228px;">
</body>
More information:
Normal flow ~ MDN
Absolute positioning ~ MDN

Why does the following sibling move?
It moves to the top because the first div is position: absolute, that's what expected when we apply this property / value. This div is also relative to the parent / body and the whole document (because no position: relative was specified anywhere else). When you apply position: absolute you remove that element from the normal document flow. It kind of flies over the document.
When you have this option applied to an element nested to something using position: relative, you'll see that the child will obey the parent's top, left, right and bottom.
Also, how can I have a div fit with 0 space against the top, without having position:absolute
This way:
body {
margin: 0;
}
With:
h1 {
margin-top: 0;
}
Or:
div {
overflow: hidden;
}
Without position: absolute; top: 0px; left: 0px; width: 100%; on the div. div's default params will take over what's needed.
The margin-top: 0 or overflow: hidden must be there just to get rid of the top h1's default margin, because when there's a margin in a case like that, the div background won't follow the whole div flow. Using overflow: hidden the way I've shown you is a technique of "clearing" things, like clearfix and others. You can read more about them here.
Also, Michael_B links about normal flow and absolute positioning are very relevant and a must read.

Related

Changing the order of elements using absolute positioning

I want to move a child element to the bottom of its parent via absolute positioning.
Ie The parent will finish and then the element will appear directly after. ie the Parents bottom margin will be aligned with the childs top margin.
I have somewhat achieved this via padding however I don't see how to make this work when the child's size is changeable? ie I have a hardcoded padding size.
<body>
<footer class="footer">
<p> I am the footer </p>
<div class="after">
<h2> I want to appear after the footer</h2>
<img src="http://static.guim.co.uk/sys-images/Guardian/Pix/pictures/2014/4/11/1397210130748/Spring-Lamb.-Image-shot-2-011.jpg"/>
</div>
<h3> I should be in the footer</h3>
</footer>
</body
css ->
.footer {
position: relative;
left: 30px;
padding-bottom: 500px;
}
.after {
position: absolute;
bottom: 0px;
left: 0px;
}
codepen -> http://codepen.io/ianw92/pen/pvXYeV
Absolutely positioned elements are removed from the normal flow. By definition, they therefore won't take other elements into consideration when being positioned. As you are seeing, you would need to hardcode some value.
I'd suggest avoiding absolute positioning and using a flexbox solution to change the order of the elements:
Updated Example
.footer {
display: flex;
flex-direction: column;
}
.footer .after {
order: 3;
}

Position relative and absolute

I have DIV container with relative position, and the child with absolute position.
here is my code source:
JSFIDDLE
HTML:
<div class="wrapper">
<h1>Hello</h1>
</div>
CSS
.wrapper {
background: red;
width: 100px;
height: 100px;
position: relative;
}
.wrapper h1 {
color: #333;
position: absolute;
top: 60px;
}
when I put in top 60px, the child element jump to the bottom , normally the container has a relative position so the child element should be under the container not over the container.
Please, someone can explain me why this happen ?
I hope I explained, well my question.
When you have an element with position: absolute that element is placed relatively to its closest positioned parent. A positioned element is any element with position different from static, be it relative, absolute or fixed.
In your case you have a .wrapper with position: relative and h1 inside it with position: absolute, that is why the latter is positioned 60 pixels from the top of its parent.
If you insist of the child element being below the parent, add z-index: -1 to it - http://jsfiddle.net/jt92sedr/4/
This property applies only to positioned elements.
You can check: http://www.barelyfitz.com/screencast/html-training/css/positioning/
The CSS is actually doing what you think (sort of), but there is also (in Firefox, at least) a 21 pixel top margin which pushes the "text" down a bit farther.
Add a rule to remove the top margin:
.wrapper h1 {
color: #333;
position: absolute;
margin-top: 0; /* added this */
top: 60px;
}
Try adding "margin:0; to the h1 element:
.wrapper h1 {
color: #333;
position: absolute;
top: 60px;
margin:0;
display:block;}
Its the other way around, Relative always means relative to the parent. if you want to the child to be set in relation to parent, then make it relative.
the relative in your case on parent does not mean anything.
Are you wondering why 60px from top of the div looks like 80px or 90 px? If this is your question, answer is easy. Browsers add some margin to h1, div and body elements. Simply clear that efect:
body, div, h1 {
margin: 0;
padding: 0;
}
http://jsfiddle.net/14sLb8jg/
Modern browsers, like Chrome and Firefox, are putting a 0.67em margin on top and bottom of h1 tags.
In your case declaring a margin 0 for .wrapper h1 will solve your problem.
Your code should be:
.wrapper {
background: red;
width: 100px;
height: 100px;
position: relative;
}
.wrapper h1 {
color: #333;
position: absolute;
top: 60px;
margin: 0;
}
If you are in doubt, use your browser's inspection / developer tools to find out what default stylings the browser is giving into any given element so you know which one you need to override.
Jsfiddle Example
View on Jsfiddle

Lack of outermost margin with smaller viewport

I have a <div id="wrapper"></div>​ with
#wrapper {
height: 300px;
margin: 10px;
position: absolute;
top: 0;
left: 0;
width: 400px;
}​
When I resize the viewport so that horizontal scrollbars appear, the right margin disappears; I can only scroll as far right at the element's content, but I want the margin to be present on all sides. It also happens to the left margin if right: 0; is applied, and to the bottom margin if the viewport is made shorter. Giving wrapper a position: static; (default) makes no difference.
Why is this happening? It doesn't follow normal margin collapse rules. How can I get my margin back? I've tried giving the body padding/margin.. nada.
jsFiddle
Background Info
The default width of the body element is the html width which is also the window width (or iframe width in such a case). The default behavior of a block level element is that the scroll only accounts for the actual element (hence, it doesn't care about the right margin if there is nothing more to display on the right). This causes your right margin issue. (By the way, according to this article, the scroll bars are actually appearing on the html element, not the body.)
For Position: Absolute
By having #wrapper with position: absolute, the body element ends up with zero height. This causes your bottom margin issue in this case.
A solution is to account for the margins like so (see fiddle):
body {
min-height: 320px;
min-width: 420px;
}
This assigns a minimum dimension to the body equal to the width + margins and height + margins of the absolute element.
Now, I'm not sure what you expect to happen if you have right: 0 set, as forcing a left margin to "remain" just ends up causing, in my opinion, a premature scroll bar to activate. See this fiddle.
Regarding Position: Static
The default block level behavior can be changed by forcing a shrink-wrap like behavior on the body element using (see fiddle):
body { display: inline-block; }
Note: that body { float: left; } did not give me the same shrink-wrap behavior (see fiddle).
The inline-block element will account for the margin of its inner elements to determine its own width, which then allows the right margin to work.
The reason the display: inline-block; solution does not work on the #wrapper being position: absolute is because it makes the body have a zero width and height, since the absolute positioning takes that element out of flow and there is nothing left inside body to give it dimension.
The above was currently only tested on IE9.
I'm afraid there's only one simple and quick solution, and that is to create a new div inside the wrapper div.
http://jsfiddle.net/QHKmN/2/
CSS
#wrapper {
background: black;
height: 300px;
margin: 10px;
position: absolute;
top: 0;
left: 0;
width: 400px;
}
#inwrapper {
background: green;
height: 290px;
margin: 5px auto;
position: relative;
width: 390px;
}
​
HTML:
<div id="wrapper">
<div id="inwrapper">
</div>
</div>
​
And there's your margin.

controlling the dimensions of elements html and css

I have a header element with 2 elements inside - an img and p elements.
I'd like the header height to be the exact height of the image it contains so that when I remove the margin and padding it "fits".
Rather than adjusting the height of the header element to be the same pixel height as the image, is there a way to "auto" do this?
I have tried height:auto but that just brings unexpected wonky results.
Here's the code:
<header>
<img src="images/logosketch.jpg" alt="companylogo" />
<div class="search">
<p>SEARCH HERE</p>
</div>
</header>
header { position: relative; }
.search { bottom: 0; position: absolute; right: 0; }
.search p { margin: 0; }
Any pointers?
Try the following -
header { position: relative; padding: 0; margin: 0;}
header img {
display: block;
height: 100px;
}
With this method, making the image a block element and manually setting its height, it will cause the parent block element to adjust its size. However, if any other block elements in that header have a greater height than the img element, then it will cause the header to take on that other elements height with the exception of block elements that are position absolute.
Hope this helps.
Remove padding from the container and margin from the image. Some browsers have their own styling on common elements. That's why many people use a CSS Reset stylesheet.
However, if the p element gets bigger, so will the container so you will have to restrict that element in some way (make sure the text does not make it higher than the image or specify the height to be the same as the container.

Place a footer with Content positioned as absolute

I have a wrapper class that contains all the content on the web page. the problem is if the content is absolutely placed, it eats my footer. I have to place the content as absolute positioned.
It seems like the footer doesnot recognize that the content is absolute. Heres my code
<style>
* {
margin: 0;
}
html, body {
height: 100%;
}
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -4em;
}
.footer, .push {
height: 4em;
}
</style>
</head>
<body>
<div class="wrapper">
<img src="activity/Chrysanthemum.jpg" style="z-index: 1; position:absolute; width: 420px; height: 400px; left: 100px;top:260px; ">
<div class="push">
</div>
</div>
<div class="footer" >copyrights</div>
</body>
If I change the image style by removing the position:absolute property , everything looks normal. so my question is how can we place the footer at the bottom with absolute positioned contents?
Updated answer, regarding comment.
As I mentioned at my previous answer, this effect cannot be achieved using pure CSS. So, I will show the JavaScript approach. Add relevant IDs (see Fiddle), and add the following code at the end of your body. This code snippet will resize your wrapper when necessary.Note: When the page is smaller than the window's height, the page wrapper will still take the full height, because it's not possible to distinguish a height change by an absolutely positioned element.
<script>
(function(){
var wrapper = document.getElementById("wrapper");
var height = document.documentElement.scrollHeight;
wrapper.style.height = height + "px";
})();
</script>
Previous answer:
The issue is caused by the fact that absolutely-positioned elements do not affect the height/width of their parent.
To fix your code, apply the following CSS (only showing relevant CSS, updated postfixed by descriptive comments). Fiddle: http://jsfiddle.net/4ja2V/
html, body {
height: 100%;
width: 100%;
padding: 0; /* Get rid off the padding */
}
.wrapper {
position: relative; /* Necessary to properly deal with absolutely positioned
child elements. */
height: 100%;
margin: 0 auto 4em; /* So that the content is visible when scrolled down*/
}
.footer {
height: 4em;
position: fixed; /* Positions your footer at a fixed position in the window*/
bottom: 0; /* At the bottom of the window*/
}
You were using a negative bottom-margin for .wrapper, which caused the element to "eat" the footer. When you're using absolutely poisitioned inner elements, there's no reliable pure-CSS method to get the real width/height of the .wrapper element. Hence the appearance of position:fixed.
The footer is defined to have a height of 4em. Because the footer is positioned at a fixed position (ie, the element won't move when scrolling down), it's necessary to apply an additional margin at the bottom of the wrapper element.
give your footer a fixed hight and then in your absolute class, do
bottom: heightOfYourFooter + 5px;