As you can see in the CSS below, I want child2 to position itself before child1. This is because the site I'm currently developing should also work on mobile devices, on which the child2 should be at the bottom, as it contains the navigation which I want below the content on the mobile devices. - Why not 2 masterpages? This is the only 2 divs which are repositioned in the entire HTML, so 2 masterpages for this minor change is an overkill.
HTML:
<div id="parent">
<div class="child1"></div>
<div class="child2"></div>
</div>
CSS:
parent { position: relative; width: 100%; }
child1 { width: auto; margin-left: 160px; }
child2 { width: 145px; position: absolute; top: 0px; bottom: 0px; }
child2 has dynamic height, as different subsites could have more or less navigation items.
I know that absolute positioned elements are removed from the flow, thus ignored by other elements.
I tried setting overflow:hidden; on the parent div, but that didn't help, neither does the clearfix.
My last resort will be JavaScript to reposition the two divs accordingly, but for now I'll try and see if there exist a non-JavaScript way of doing this.
You answered the question yourself:
I know that absolute positioned elements are removed from the flow, thus ignored by other elements.
So you can't set the parents height according to an absolutely positioned element.
You either use fixed heights or you need to involve JavaScript.
Nowadays one might use CSS flexbox or grid layout to reverse the visual order of HTML elements inside a parent container without using position: absolute;. See also Reverse order of columns in CSS Grid Layout
Although stretching to elements with position: absolute is not possible, there are often solutions where you can avoid the absolute positioning while obtaining the same effect. Look at this fiddle that solves the problem in your particular case http://jsfiddle.net/gS9q7/
The trick is to reverse element order by floating both elements, the first to the right, the second to the left, so the second appears first.
.child1 {
width: calc(100% - 160px);
float: right;
}
.child2 {
width: 145px;
float: left;
}
Finally, add a clearfix to the parent and you're done (see the fiddle for the complete solution).
Generally, as long as the element with absolute position is positioned at the top of the parent element, chances are good that you find a workaround by floating the element.
There is a quite simple way to solve this.
You just have to duplicate the content of child1 and child2 in relative divs with display:none in parent div. Say child1_1 and child2_2. Put child2_2 on top and child1_1 at the bottom.
When your jquery (or whatever) calls the absolute div, just set the according relative div (child1_1 or child2_2) with display:block AND visibility:hidden. The relative child will still be invisible but will make parent's div higher.
Feeela is right but you can get a parent div contracting or expanding to a child element if you reverse your div positioning like this:
.parent {
position: absolute;
/* position it in the browser using the `left`, `top` and `margin`
attributes */
}
.child {
position: relative;
height: 100%;
width: 100%;
overflow: hidden;
/* to pad or move it around using `left` and `top` inside the parent */
}
This should work for you.
This question was asked in 2012 before flexbox. The correct way to solve this problem using modern CSS is with a media query and a flex column reversal for mobile devices. No absolute positioning is needed.
https://jsfiddle.net/tnhsaesop/vjftq198/3/
HTML:
<div class="parent">
<div style="background-color:lightgrey;">
<p>
I stay on top on desktop and I'm on bottom on mobile
</p>
</div>
<div style="background-color:grey;">
<p>
I stay on bottom on desktop and I'm on top on mobile
</p>
</div>
</div>
CSS:
.parent {
display: flex;
flex-direction: column;
}
#media (max-width: 768px) {
.parent {
flex-direction: column-reverse;
}
}
With pure JavaScript, you just need to retrieve the height of your static position child element .child1 using the getComputedStyle() method then set that retrieve value as the padding-top for that same child using the HTMLElement.style property.
Check and run the following Code Snippet for a practical example of what I described above:
/* JavaScript */
var child1 = document.querySelector(".child1");
var parent = document.getElementById("parent");
var childHeight = parseInt(window.getComputedStyle(child1).height) + "px";
child1.style.paddingTop = childHeight;
/* CSS */
#parent { position: relative; width: 100%; }
.child1 { width: auto; }
.child2 { width: 145px; position: absolute; top: 0px; bottom: 0px; }
html, body { width: 100%;height: 100%; margin: 0; padding: 0; }
<!-- HTML -->
<div id="parent">
<div class="child1">STATIC</div>
<div class="child2">ABSOLUTE</div>
</div>
There's a very simple hack that fixes this issue
Here's a codesandbox that illustrates the solution: https://codesandbox.io/s/00w06z1n5l
HTML
<div id="parent">
<div class="hack">
<div class="child">
</div>
</div>
</div>
CSS
.parent { position: relative; width: 100%; }
.hack { position: absolute; left:0; right:0; top:0;}
.child { position: absolute; left: 0; right: 0; bottom:0; }
you can play with the positioning of the hack div to affect where the child positions itself.
Here's a snippet:
html {
font-family: sans-serif;
text-align: center;
}
.container {
border: 2px solid gray;
height: 400px;
display: flex;
flex-direction: column;
}
.stuff-the-middle {
background: papayawhip
url("https://camo.githubusercontent.com/6609e7239d46222bbcbd846155351a8ce06eb11f/687474703a2f2f692e696d6775722e636f6d2f4e577a764a6d6d2e706e67");
flex: 1;
}
.parent {
background: palevioletred;
position: relative;
}
.hack {
position: absolute;
left: 0;
top:0;
right: 0;
}
.child {
height: 40px;
background: rgba(0, 0, 0, 0.5);
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
<div class="container">
<div class="stuff-the-middle">
I have stuff annoyingly in th emiddle
</div>
<div class="parent">
<div class="hack">
<div class="child">
I'm inside of my parent but absolutely on top
</div>
</div>
I'm the parent
<br /> You can modify my height
<br /> and my child is always on top
<br /> absolutely on top
<br /> try removing this text
</div>
</div>
I came up with another solution, which I don't love but gets the job done.
Basically duplicate the child elements in such a way that the duplicates are not visible.
<div id="parent">
<div class="width-calc">
<div class="child1"></div>
<div class="child2"></div>
</div>
<div class="child1"></div>
<div class="child2"></div>
</div>
CSS:
.width-calc {
height: 0;
overflow: hidden;
}
If those child elements contain little markup, then the impact will be small.
I had a similar problem.
To solve this (instead of calculate the iframe's height using the body, document or window) I created a div that wraps the whole page content (a div with an id="page" for example) and then I used its height.
"You either use fixed heights or you need to involve JS."
Here is the JS example:
---------- jQuery JS example--------------------
function findEnvelopSizeOfAbsolutelyPositionedChildren(containerSelector){
var maxX = $(containerSelector).width(), maxY = $(containerSelector).height();
$(containerSelector).children().each(function (i){
if (maxX < parseInt($(this).css('left')) + $(this).width()){
maxX = parseInt($(this).css('left')) + $(this).width();
}
if (maxY < parseInt($(this).css('top')) + $(this).height()){
maxY = parseInt($(this).css('top')) + $(this).height();
}
});
return {
'width': maxX,
'height': maxY
}
}
var specBodySize = findEnvelopSizeOfAbsolutelyPositionedSubDivs("#SpecBody");
$("#SpecBody").width(specBodySize.width);
$("#SpecBody").height(specBodySize.height);
There is a better way to do this now. You can use the bottom property.
.my-element {
position: absolute;
bottom: 30px;
}
This is very similar to what #ChrisC suggested. It is not using an absolute positioned element, but a relative one. Maybe could work for you
<div class="container">
<div class="my-child"></div>
</div>
And your css like this:
.container{
background-color: red;
position: relative;
border: 1px solid black;
width: 100%;
}
.my-child{
position: relative;
top: 0;
left: 100%;
height: 100px;
width: 100px;
margin-left: -100px;
background-color: blue;
}
https://jsfiddle.net/royriojas/dndjwa6t/
Also consider next approach:
CSS:
.parent {
height: 100%;
}
.parent:after {
content: '';
display: block;
}
Also since you are trying to reposition divs consider css grid
Absolute views position themselves against the nearest ancestor that isn't statically positioned (position: static), therefore if you want an absolute view positioned against a given parent, set the parent position to relative and the child to position to absolute
Try this, it was worked for me
.child {
width: 100%;
position: absolute;
top: 0px;
bottom: 0px;
z-index: 1;
}
It will set child height to parent height
I'm trying to contain 2 images and some text to a div. I have it positioned the way I'd like, but when adding it to my site it's positioned in the top left corner.
How do I get it so it sits in a div by itself under the rest of my content and doesn't move to the top left of my website?
I created a fiddle with my code: http://jsfiddle.net/43qahfsn/2/
Would using percentages instead of pixels make a difference? Or is there some better way to do this?
#box {
width:1200px;
height:700px;
}
.text, .stripe, .photo {
position: absolute;
text-align: center;
}
.text {
color:#000;
top: 50px;
left: 250px;
}
.stripe {
z-index: 1;
top: 0px;
left: 0px;
}
.photo {
top: 400px;
left: 600px;
}
You need to make the positioning of the absolutely positioned elements relative to their parent. In your case wrap them in a div and apply position:relative; to it.
.container {
position:relative;
}
<div class="container">
<!-- your current html --->
</div>
Demo http://jsfiddle.net/43qahfsn/5/
I need help getting dropdown menu expanding on top. I put z-index on it, yet for some reason I'd like to understand it blends with the rest. The dropdown expands when one types in "Enter your region" on my site 33hotels.com.
I am sorry to post no code but the main problem is I don't know which part of it is responsible for this effect.
Thanks!
EDIT.
Turned out that setting position: absolute instead fixed solved the problem! Also strangely it only was a problem in Chrome and Safari but not Firefox!
Add z-index property to #location-search element. You may just set it to 1.
#location-search {
position: fixed;
z-index: 1;
top: 45px;
margin: 0 5px;
}
Remember, that z-index only works for a fraternal elements - those, who have the same parent. It means, if you have two non-static positioned elements in same parent you can use z-index to place them inside their parent. But as long as they have different parents - you can only rule with their parents z-indecies.
<div id="Wrapper">
<div id="Test1">blue</div>
<div id="Test2">red</div>
</div>
div { position: absolute; }
#Test1 { background: blue; z-index: 10; }
#Test2 { background: red; z-index: 9; }
/* blue is over red, though declared earlier */
But
<div id="Wrapper">
<div id="InnerWrapper">
<div id="Test1">blue</div>
</div>
<div id="Test2">red</div>
</div>
div { position: absolute; }
#InnerWrapper { z-index: 10; }
#Test1 { background: blue; z-index: 15; }
#Test2 { background: red; z-index: 11; }
/* red is over blue, for blue's wrapper has no z-index or lower */
Set z-index to -1 in this css, because your dropdown-menu class is having -z-index of 1000 so you need to set your main content should get behind the autocomplete dropdown.
#row-content {
position: fixed;
top: 85px;
bottom: 0;
width: 100%;
z-index: -1;
}
Also remember to set element positions, because z-index only works on positioned elements (position:absolute, position:relative, or position:fixed).
What is the easiest way (using css) to position several separate text items over the top of a single image?
I've got the following:-
<div>
<img src="image.jpg"/>
<p>One</p>
<p>Two</p>
<p>Three</p>
</div>
with the CSS:-
div {
position: relative;
}
div p {
position: absolute;
top: 0;
left: 0;
}
But that doesn't work because all of the text items are on top of one another.
Is the best way to do it with a list? Or is there another way?
Something like this:
div { position:relative; }
div img { position:absolute; top: 0; left: 0; }
div p { position:relative; z-index: 2; }
But this way the div will take the height of the text, not the image.
DEMO
div {
position: relative;
}
div img {
position:absolute
}
div p {
position: relative;
top: 0;
left: 0;
color:#fff;
}
UPDATE
OK, that seems to work - but how do I make sure the text items are all
contained within the confines of the image? Is that even possible?
Ideally, I'd like to make the text items appear in two parallel lists.
DEMO
You'd need to set the size of the container div to that of the img. From then, you can control how you want to handle the overflow.
You can use float:left; width:50%; on your p so they display in two columns.
JSFiddle:
JSFiddle of the issue
I'm having a bit of trouble wrapping my head around z-index with relatively positioned elements. Given this html I want the 'active' screen-component to be in front of the other two (yes I know this visually doesn't look good in this example... I've boiled down the problem to the basics):
<div class="parent-container">
<div class="screen-component">
Content inside first screen component
</div>
<div class="screen-component">
Content inside second screen component
</div>
<div class="screen-component active">
Content inside active component.. I want this up top
</div>
</div>
And this css:
.parent-container {
position: relative;
}
.screen-component {
position: relative;
z-index: 2000;
}
.screen-component.active {
position: relative;
z-index: 5000;
}
The desired effect I want is any 'screen-component' with the 'active' class to be positioned in front of the other ones; however right now they all seem to be given new lines, despite the .active class having a z-index higher than the .screen-component class
I think you want something like this:
http://jsfiddle.net/ZCBXA/3/
(The background colors are just for demonstration purposes)
.parent-container {
position: relative;
}
.screen-component {
position: absolute;
z-index: 2000;
top:0px;
left:0px;
background-color: #f00;
}
.active {
z-index: 5000;
background-color: #0f0;
}
If I'm understanding what you're trying to do correctly, you need position: absolute; not position: relative;. Then give the div class a top value so that all divs with that class are the same distance from the top, and a z-index of -1 to hide them. The only thing the active class needs is a higher z-index than the others.
.parent-container {
position: relative;
}
.screen-component {
position: absolute;
top:0;
z-index: -1;
}
.screen-component.active {
z-index: 0;
}