Say I have a button positioned inside a div:
.parentDiv {
width: 100px;
height: 50px;
background-color: #B9DEED;
}
.childButton {
position: absolute;
left: 90px;
opacity: .5;
}
<div class="parentDiv">
<button class="childButton">Childbutton</button>
</div>
This gets rendered like so:
Is there a way to display the button so that it is constrained to the div, i.e. it gets cut off after the "C"?
That's not a button positioned inside a div, that's a button (that happens to be child of a div) positioned within the page. For the button to positioned within the div, the div needs to be positioned itself.
Once the parent has position, the overflow: hidden will start to work.
div {
outline: 1px solid blue;
width: 100px;
height: 50px;
position: relative;
overflow: hidden;
}
button {
position: absolute;
left: 90px;
}
<h3>Sample</h3>
<div>
<button>Childbutton</button>
</div>
Core take-away: position is always related to the closest ancestor (it does not have to be the direct parent) that has position. If there is none, it is related to the page. Setting position: relative on a parent establishes a frame of reference without taking the parent out of the document flow.
You can see the difference if you set top: 10px on the button. Try with and without position: relative on the div to verify the frame of reference.
You can use the style overflow: hidden to hide everything outside the parent-element.
This does, however, not apply to position: absolute elements. You would need to use position. relative for that.
Related
I have an element that gets position: fixed while dragging. This element is inside a modal that is a direct child of the body element.
On the image below, the modal is gray, the rest of the body is black, and the button is blue. When I add the following styles to the button:
position: fixed;
top: xxxpx;
left: -100px;
It positions the button relative to the modal, not the viewport. Is that even possible that an element with position: fixed be positioned relative to something but the viewport? It acts like an absolutely positioned element instead.
'normally' position fixed fixes relative to the viewport.
But there are exceptions. See MDN
The element is removed from the normal document flow, and no space is created for the element in the page layout. It is positioned relative to the initial containing block established by the viewport, except when one of its ancestors has a transform, perspective, or filter property set to something other than none (see the CSS Transforms Spec), in which case that ancestor behaves as the containing block. (Note that there are browser inconsistencies with perspective and filter contributing to containing block formation.) Its final position is determined by the values of top, right, bottom, and left.
Here's a simple example:
body {}
.parent {
position: relative;
margin: 100px;
transform: scale(1);
width: 50vw;
height: 10vw;
background: black;
rfilter: blur(1);
}
.child {
position: fixed;
top: 0px;
left: 0px;
width: 100px;
height: 100px;
background-color: blue;
}
<body>
<div class="parent">
<div class="child"></div>
</div>
</body>
Notice that the blue child element is placed at the top left of its parent. Its parent has a transform - and as it's scale(1) we might assume it doesn't do much. But it does create the parent as the containing block.
I think your problem is the transform on the parent.
This question already has an answer here:
How can i make an element from a bottom stacking context stays in front of another higher stacking context? [duplicate]
(1 answer)
Closed 4 years ago.
#twitter{
width:50px;
height:50px;
position: absolute;
right: 0%;
bottom: 0%;
background-color: orange;
z-index:-2;
}
#socialButton {
position: relative;
width: 80px;
height: 80px;
background-color: green;
z-index: 2;
}
#socialButtonRoot {
width: 100px;
height: 100px;
top:20%;
left:20%;
position: absolute;
background-color: hotpink;
z-index: 5;
}
<div id="socialButtonRoot">
<div id="socialButton">
<div id="twitter"></div>
</div>
</div>
This is a simplified version.
In my react project there's component created some Dom nodes, after that I set the styles for them in the CSS file, most styles works fine, but only the z-index style doesn't work, people said we should set the position, yes I've all of them set, but it still doesn't work. So I think it maybe something to do with React or JS, but after I extracted code from React and JS and test it on jsfiddle, z-index still doesn't work. Then, I changed changed the z-index value from 2 to "2" (a string ) , it works, but I can see the value "2" is invalid in the chrome's debug console.
It should be div socialButtonRoot on the front which have highest z-index(5) and div socialButton in the middle which have the second high z-index(2) and div twitter in the back, which have the lowest z-index.
but in the result below, it shows, div twitter on the front and div socialButton in the middle and div socialButtonRoot on the back, which isn't right.
What's the problem here?
See The Stacking Context on MDN.
A stacking context is formed, anywhere in the document, by any element in the following scenarios: … Element with a position value "absolute" or "relative" and z-index value other than "auto".
…
Within a stacking context, child elements are stacked according to the same rules previously explained. Importantly, the z-index values of its child stacking contexts only have meaning in this parent. Stacking contexts are treated atomically as a single unit in the parent stacking context.
The z-index positions an element inside the stacking context it is associated with.
Giving an element position: absolute or position: relative establishes a new stacking context.
Thus #twitter is positioned inside the 3-d box represented by #socialButton.
The z-index is for that box, and not for the entire document.
(And #socialButton is inside #socialButtonRoot in the same way).
If you want A to be rendered below B then either:
Do not position A or
Do not make B a descendant of A
When you place an element inside another element, The child element will display on top of its parent element. This is the same for many nested elements and is the default CSS behaviour. Even setting a higher z-index for the parent than its child element won't change the result. In your example:
<div id="socialButtonRoot">
<div id="socialButton">
<div id="twitter"></div>
</div>
</div>
#socialButtonRoot will be displayed at the bottom. #socialButton will display on top of #socialBuuttonRoot. On top of all, #twitter will show. The z-index will be ignored as it only affects elements of the same level.
I suggest you create a parent <div> and place all three <div>s inside:
#parent {
position: relative;
width: 100px;
height: 100px;
margin-top: 20vh;
margin-left: 20vw;
}
#socialButtonRoot {
position: absolute;
width: 100px;
height: 100px;
z-index: 5;
background-color: hotpink;
}
#socialButton {
position: relative;
width: 80px;
height: 80px;
z-index: 2;
background-color: green;
}
#twitter {
position: absolute;
width: 50px;
height: 50px;
right: 20%;
bottom: 20%;
background-color: orange;
z-index: -2;
}
<div id="parent">
<div id="socialButtonRoot"></div>
<div id="socialButton"></div>
<div id="twitter"></div>
</div>
I used position:relative for the parent <div> so that I can position the children <div>s using percentages. I also used margin-top and margin-left instead of top and left respectively, since the latter don't work with relatively positioned elements.
Since #socialButtonRoot is the largest <div> and is placed in front of the other two, it is the only one that appears when you run the snippet. You can change the z-index for each <div> as you wish
I have two divs that I would like to place one on top of the other, so I can create a tab system in an applet I am making. These two divs reside within a parent div, that uses auto height because I do not know the exact height of the other two divs (both children will be of same height). I can position the two divs one on top of the other with absolute positioning when the parent uses relative positioning, but the auto height doesn't respond (most likely because of absolute positioned children) creating a border line of an empty div instead of a wrapper with elements inside.
See problem here: http://jsfiddle.net/h5bjt69s/
<div id = "parent">
<div id = "redDiv"></div>
<div class = "clearfix"></div>
<div id = "blueDiv"></div>
</div>
I tried modeling a solution from this, but I believe the auto height throws things off.
Position absolute but relative to parent
How can I wrap the two divs with the parent div and still maintain the overlaying of the two children?
This:
both children will be of same height
Actually solves your problem:
Position one div using position: static; it will determine the height of the parent
Position the other div(s) using position: absolute (it will appear on top)
Updated Fiddle
Here are the changes
#blueDiv {
background-color: blue;
width: 100%;
height: 50px;
position: relative;/*changed*/
top: 0px;
left: 0px;
z-index:2;/*added*/
opacity:0.7;
}
DEMO
Another Style
#blueDiv {
background-color: blue;
width: 100%;
height: 50px;
/*position: relative;removed*/
opacity:0.7;
}
#redDiv {
background-color: red;
width: 100%;
height: 50px;
visibility: visible;
position: absolute;
top: 0px;
left: 0px;
z-index: 0;/*added*/
}
Updated
I've got a div that contains a photo tiling style I've been working on. The parent div over all the photos is position:relative while the divs inside holding the photos are position:absolute
I have to use 'position:absolute` for the children to get the layout I want but the problem arises when the parent div (either .daddy or .floatcont) doesn't register with a height and appears empty.
How can I make the parent register a height so I can put content below it on the page?
Code here: http://codepen.io/jeremypbeasley/pen/iBgsp
.floatcont {
position: relative;
background: pink;
width: 90%;
margin: 5%;
}
.floatpic {
position: absolute;
width: 40%;
margin-bottom: 10vh;
}
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.
In your case, I have come up with one solution. Update your .sixth class like below.
.floatpic.sixth {
top: 270vh;
width: 50%;
z-index: 6;
position:relative;
}
Updated CodePen
I'm trying to get a div to show as a partial background below the inline content of is containing div but above the background of its container. If I set the z-index of just the partial background to -1 it appears behind the background. But if i set the containing divs z-index to 1 while the contained div's z-index is -1 it displays as desired.
Can someone explain to me why this is and if this is a reliable method or not?
.container {
position: relative;
width: 80%;
height: 18px;
padding: 6px 10px;
background: #666;
z-index: 1;
}
.partialbg {
position: absolute;
left: 0px;
top: 0px;
height: 30px;
width: 80%;
background: #0CC;
z-index: -1;
}
<div class="container">Text here
<div class="partialbg"></div>
</div>
The reason this is occurring, is because there is a child and a parent. If you set a z-index on the parent, the child is going to be the same, since the z-index is stacked.
Thus, by setting a z-index of 1 on the parent, the child is now also 1.
It is systematically impossible for the child to be behind the parent, as that doesn't make any sense. However, the text is a sibling of the child. By setting a z-index of -1 on the child, there is essentially no effect between the child and the parent, however since the sibling is effected, the child now goes behind the sibling.