I have written a simple code with a main box containing two smaller boxes inside.
I have set the position of the smaller boxes to absolute, in order to set their positioning according to their parent.
What i would like to do is to bring the son2 div in front, since now is hidden by sondiv
I tried the z-index property but (as i expected) my element gets under the parent element, and not under the small blue box
#parent {
position: absolute;
background-color: red;
width: 100px;
height: 100px;
margin-top: 200px;
margin-left: 200px;
}
#son2 {
position: absolute;
background-color: green;
width: 50px;
height: 50px;
margin-top: 20px;
}
#son {
position: absolute;
background-color: blue;
width: 50px;
height: 50px;
margin-top: 10px;
}
<div id="parent">
<div id="son2"></div>
<div id="son"></div>
</div>
Demo on Codepen: https://codepen.io/mattiasu96/pen/KbpyNQ
Tiny change (just add z-index: 1; to son2).
By the way you don't want to set position: absolute for the parent unless you need to change its position from the natural one as well, otherwise go with position: relative so that it's rendered normally but the absolute positioned children still behave as intended.
I've removed the margins from the parent just so you don't have to scroll in the snippet in order to see the divs, but no difference if you need that in your original problem.
#parent {
position: relative;
background-color: red;
width: 100px;
height: 100px;
}
#son2 {
position: absolute;
background-color: green;
width: 50px;
height: 50px;
margin-top: 20px;
z-index: 1;
}
#son {
position: absolute;
background-color: blue;
width: 50px;
height: 50px;
margin-top: 10px;
}
<div id="parent">
<div id="son2"></div>
<div id="son"></div>
</div>
Related
I'm pretty new to CSS so I was trying out some CSS-Battles just to learn some basics.
I was trying to get a circle with two mountains in it and had the idea to generate two divs, rotate them 45deg and then position them so they would match up with the picture needed.
For testing I painted the second mountain div black.
* {
margin: 0;
padding: 0;
}
.background {
align-items: center;
justify-content: center;
display: flex;
width: 100vw;
height: 100vh;
background-color: #293462;
}
.circle {
position: relative;
display: flex;
background-color: #FFF1C1;
width: 200px;
height: 200px;
border-radius: 50%;
overflow: hidden;
}
.mountain {
position: relative;
background-color: #FE5F55;
transform: rotate(45deg);
height: 200px;
width: 200px;
}
.mountain-1 {
background-color: #FE5F55;
top: 100px;
left: 41px;
}
.mountain-2 {
background-color: black;
top: 170px;
right: 70px
}
<div class="background">
<div class="circle">
<div class="mountain mountain-1">
</div>
<div class="mountain mountain-2">
</div>
</div>
</div>
Result
This was my first attempt. Then I noticed that when I set display of .mountain-1 to none the position of mountain-2 changes which I don't want and don't understand even after searching for solutions.
CSS changed
.mountain-1{
background-color: #FE5F55;
top: 100px;
left: 41px;
display: none;
}
Result
Also when I change the order of the two divs inside the HTML the result changes as well which in my mind makes not the most sense.
The main reason the two <div> elements are dependent on each other is because they both have the position CSS property set to relative. They inherit this from the parent element CSS .mountain.
This means the top, left, right, and bottom properties will be relative to other elements within the same container. To fix this, you need to set each mountain's position property to absolute. This means the position is set purely based on the values you use in top, left, right, or bottom. Also as a side note, if you do not have the parent element's position set to relative, using position: absolute will place the element based on the <body> element. So if you want the element's position to be based on the bounds of its parent, also set its parent's position to relative.
*{
margin: 0;
padding: 0;
}
.background{
align-items: center;
justify-content: center;
display: flex;
width: 100vw;
height: 100vh;
background-color: #293462;
}
.circle{
position:relative;
display: flex;
background-color: #FFF1C1;
width: 200px;
height: 200px;
border-radius: 50%;
overflow: hidden;
}
.mountain{
position: relative;
background-color: #FE5F55;
transform: rotate(45deg);
height: 200px;
width: 200px;
}
.mountain-1{
position: absolute;
top: 105px;
left: 40px;
}
.mountain-2{
position: absolute;
top:170px;
right: 70px
}
<div class="background">
<div class="circle">
<div class="mountain mountain-1">
</div>
<div class="mountain mountain-2">
</div>
</div>
</div>
How to shift a child block?
How to shift the blue block so that it stretches the parent block?
.main {
width: 400px;
min-height: 300px;
background: red;
position: relative;
}
.preMain {
width: 60px;
height: 60px;
background: blue;
position: absolute;
top: 350px;
}
<div class="main">
<div class="preMain">
</div>
</div>
Your issue is that your child block has position: absolute; meaning it no longer affects the parent div. If you want to shift the child block down but still have it affect the parent block you need to change the position of the child. Try something like this:
.main {
width: 400px;
min-height: 300px;
background: red;
position: absolute;
}
.preMain {
width: 60px;
height: 60px;
background: blue;
position: relative;
margin: 350px 0px 10px 10px;
}
Admittedly not a perfect solution but you should be able to achieve the result you're looking for.
Alternately, look to this post here
Hope this helps.
You are using position: absolute, which allows to use bottom and left to position the element correctly.
.main {
width: 400px;
min-height: 300px;
background: red;
position: relative;
}
.preMain {
width: 60px;
height: 60px;
background: blue;
position: absolute;
bottom: 10px;
left: 10px
}
<div class="main">
<div class="preMain">
</div>
</div>
This question already has answers here:
Why can't an element with a z-index value cover its child?
(5 answers)
Closed 3 years ago.
I have a constraint: these 2 parent divs cannot be "one is higher than the other", they are both equal in importance.
I have 2 main divs, they're both z-index: 2. Inside the first div, I have a child whose z-index is 99999, now, because both relative and static are treated by the browser in a first-come-last-important fashion, that is to say, div2 has a higher order than div1, my absolute child inside div1 will be behind div2. Watch:
#item1 {
width: 100%;
height: 200px;
background-color: gray;
position: relative;
z-index: 2;
}
#child {
position: absolute;
bottom: -15px;
width: 50px;
height: 50px;
border-radius: 50%;
background: white;
z-index: 15;
}
#item2 {
width: 100%;
height: 200px;
background-color: green;
position: relative;
z-index: 2;
}
<div id="item1">
<div id="child">
</div>
</div>
<div id="item2">
</div>
What am I missing here? The web is supposedly full of divs that are relative and come one after another and they have absolute divs inside of them.
Increase z-index of parent item (#item1) or remove z-index from both parent. It will work.
Actually you don't need to use z-index in parent elements, if you need to use z-index then give first parent higher, Browser give higher priority(z-index) on second element than first because browsers need to show 2nd element over first element.
#item1 {
width: 100%;
height: 200px;
background-color: gray;
position: relative;
}
#child {
position: absolute;
bottom: -15px;
width: 50px;
height: 50px;
border-radius: 50%;
background: white;
z-index: 15;
}
#item2 {
width: 100%;
height: 200px;
background-color: green;
position: relative;
}
<div id="item1">
<div id="child">
</div>
</div>
<div id="item2">
</div>
enter code here
#item1 {
width: 100%;
height: 200px;
background-color: gray;
position: relative;
z-index: 2;
}
#child {
position: absolute;
top: -15px;
width: 50px;
height: 50px;
border-radius: 50%;
background: white;
z-index: 9999;
}
#item2 {
width: 100%;
height: 200px;
background-color: green;
position: relative;
z-index: 2;
}
<div id="item1">
</div>
<div id="item2">
<div id="child">
</div>
</div>
These position: absolute; divs placed inside/around a position: relative; parent receive height/width from the size and length of the contained text.
However, if one of them extends beyond the right border of the relative parent, its width appears to truncate.
How can I make the div which extends beyond the right side of the relative parent behave as the others which don't, using only css? (Should work on all major browsers including Edge but not IE)
Here is a fiddle, but I will also copy the code + screenshot below:
HTML:
<div id="relative">
<div id="absolute-working-left">
My width and height are determined by my text content.
</div>
<div id="absolute-working-middle">
Mine, too.
</div>
<div id="absolute-problem">
But not me... I am a problem, because my width is truncated when I extend beyond the right side of my 'relative' parent. WHY???
</div>
</div>
...and the styles. Note that I want the absolute div width to reach a max of 200px before wrapping. Otherwise, the width should be determined by the length of the contained text:
#relative {
position: relative;
width: 100px;
height: 100px;
margin-left: 300px;
background-color: white;
}
#absolute-problem,
#absolute-working-left,
#absolute-working-middle {
position: absolute;
top: 45px;
font-size: 12px;
max-width: 200px;
}
#absolute-working-left {
background-color: lightblue;
left: -300px;
}
#absolute-working-middle {
background-color: lightgreen;
}
#absolute-problem {
background-color: red;
left: 80px;
}
This issue arose while implementing a tooltip which, when used by a developer, needs to position itself WRT an offsetParent (or the body, if no preceding offsetParent exists in its DOM branch).
Edit: How can I achieve the desired behavior using only css?
The solution needs to work on all major browsers including Edge, but not IE. And just to reiterate, the width of the absolute divs' cannot be predicted as it should be determined by the length of the texts... the only exception being that there will be a max-width (in this example, it is 200px).
The #absolute-problem div has a left set to a particular value, an auto width and an auto right. According to this rule in ยง10.3.7 of the spec, this would shrink the div's width to fit its contents.
'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right'.
While there doesn't seem to be a reliable way to achieve the exact desired behavior (as there aren't enough properties set to calculate the width), following are some ways to work around this problem.
Set a width for the absolute div
A trivial solution would be to set its width, so that it doesn't shrink.
#absolute-problem {
background-color: red;
left: 80px;
width: 100px;
}
body {
background: #EEE;
}
#relative {
position: relative;
width: 100px;
height: 100px;
margin-left: 300px;
background-color: white;
font-size: 12px;
}
#absolute-problem,
#absolute-working-left,
#absolute-working-middle {
position: absolute;
top: 45px;
font-size: 12px;
max-width: 200px;
}
#absolute-working-left {
background-color: lightblue;
left: -300px;
}
#absolute-working-middle {
background-color: lightgreen;
}
#absolute-problem {
background-color: red;
left: 80px;
width: 100px;
}
<div id="relative">
relative parent
<div id="absolute-working-left">
My width and height are determined by my text content.
</div>
<div id="absolute-working-middle">
Mine, too.
</div>
<div id="absolute-problem">But not me... I am a problem, because my width is truncated when I extend beyond the right side of my 'relative' parent. WHY???</div>
</div>
Set a right for the absolute div
It the width of your div is unknown, one way to get around this is to set the right as well. This adjusts the width of your div accordingly.
#absolute-problem {
background-color: red;
right: -80px;
left: 80px;
}
body {
background: #EEE;
}
#relative {
position: relative;
width: 100px;
height: 100px;
margin-left: 300px;
background-color: white;
font-size: 12px;
}
#absolute-problem,
#absolute-working-left,
#absolute-working-middle {
position: absolute;
top: 45px;
font-size: 12px;
max-width: 200px;
}
#absolute-working-left {
background-color: lightblue;
left: -300px;
}
#absolute-working-middle {
background-color: lightgreen;
}
#absolute-problem {
background-color: red;
left: 80px;
right: -80px;
}
<div id="relative">
relative parent
<div id="absolute-working-left">
My width and height are determined by my text content.
</div>
<div id="absolute-working-middle">
Mine, too.
</div>
<div id="absolute-problem">But not me... I am a problem, because my width is truncated when I extend beyond the right side of my 'relative' parent. WHY???</div>
</div>
Set the width to fit-content/max-content
Another way would be to use a fit-content or max-content (limited browser compatibility) for the absolute div, instead of setting its right. This helps if the content of your div doesn't necessarily extend to the maximum width.
#absolute-problem {
background-color: red;
right: -80px;
width: fit-content;
}
body {
background: #EEE;
}
#relative {
position: relative;
width: 100px;
height: 100px;
margin-left: 300px;
background-color: white;
font-size: 12px;
}
#absolute-problem,
#absolute-working-left,
#absolute-working-middle {
position: absolute;
top: 45px;
font-size: 12px;
max-width: 200px;
}
#absolute-working-left {
background-color: lightblue;
left: -300px;
}
#absolute-working-middle {
background-color: lightgreen;
}
#absolute-problem {
background-color: red;
left: 80px;
width: fit-content;
}
<div id="relative">
relative parent
<div id="absolute-working-left">
My width and height are determined by my text content.
</div>
<div id="absolute-working-middle">
Mine, too.
</div>
<div id="absolute-problem">But not me...</div>
</div>
Set min-width and max-width
A realistic approach would be to give the the ability to adjust its size within a given range, in order to keep its overflow in check.
#absolute-problem {
background-color: red;
left: 80px;
min-width: 50px;
max-width: 200px;
}
body {
background: #EEE;
}
#relative {
position: relative;
width: 100px;
height: 100px;
margin-left: 300px;
background-color: white;
font-size: 12px;
}
#absolute-problem,
#absolute-working-left,
#absolute-working-middle {
position: absolute;
top: 45px;
font-size: 12px;
max-width: 200px;
}
#absolute-working-left {
background-color: lightblue;
left: -300px;
}
#absolute-working-middle {
background-color: lightgreen;
}
#absolute-problem {
background-color: red;
left: 80px;
min-width: 50px;
max-width: 200px;
}
<div id="relative">
relative parent
<div id="absolute-working-left">
My width and height are determined by my text content.
</div>
<div id="absolute-working-middle">
Mine, too.
</div>
<div id="absolute-problem">But not me...</div>
</div>
I met this problem in one of my projects too and I found a simple solution to this. Just add a negative margin-right to the box.
#absolute-problem {
margin-right: -9999999px;
}
This should work in that situation. The 9999999px is very high so that the box will extend to the right as long as the content is. If you want a limit, give it a reasonable length will work.
I have a kind of "range display", where I use elements to display the current position within a range. See the example https://jsfiddle.net/juwxdb5m/ or the following code.
HTML:
<h1>Range display with fixed sizes (works correctly)</h1>
<div class="my-fixed-frame">
<div class="my-fixed-chart">
<div class="my-fixed-point" style="bottom:0%;left:0%;"></div>
<div class="my-fixed-point" style="bottom:50%;left:50%;"></div>
<div class="my-fixed-point" style="bottom:100%;left:100%;"></div>
</div>
</div>
<h1>Range display with relative sizes (works incorrectly)</h1>
<div class="my-relative-frame">
<div class="my-relative-chart">
<div class="my-relative-point" style="bottom:0%;left:0%;"></div>
<div class="my-relative-point" style="bottom:50%;left:50%;"></div>
<div class="my-relative-point" style="bottom:100%;left:100%;"></div>
</div>
</div>
CSS:
.my-fixed-frame {
background-color: gray;
height: 90px;
position: relative;
width: 160px;
}
.my-fixed-chart {
background-color: silver;
display: inline-block;
bottom: 8px; left: 8px; right: 8px; top: 8px;
margin: auto;
position: absolute;
}
.my-fixed-point {
background-color: lime;
height: 16px;
margin-bottom: -8px;
margin-left: -8px;
position: absolute;
width: 16px;
}
.my-relative-frame {
background-color: gray;
height: 90px;
position: relative;
width: 160px;
}
.my-relative-chart {
background-color: silver;
display: inline-block;
bottom: 25%; left: 25%; right: 25%; top: 25%;
margin: auto;
position: absolute;
}
.my-relative-point {
background-color: lime;
height: 50%;
margin-bottom: -25%;
margin-left: -25%;
position: absolute;
width: 50%;
}
When I use fixed sizes, I can implement the design as desired. The "point" elements are within the parent element, respectively within its frame.
But I didn't found a solution, when I use relative sizes for the child elements.
Maybe this is what you want:
https://jsfiddle.net/xoq95xaa/
The main changes are that I took the green squares out of the inner container (which is what you kind of did using negative margins in the first version), removed any margins, inserted a forth element (reacting to your comment), changed the size to 25% width and height and changed the bottom and left values to 25% steps (0, 25, 50, 75).
I found a solution which works as desired, see also https://jsfiddle.net/juwxdb5m/1/.
HTML:
<h1>Range display with relative sizes</h1>
<div class="range-display">
<div class="range-cocoon">
<div class="range-point" style="bottom:0%;left:0%;"></div>
<div class="range-point" style="bottom:33.333%;left:33.333%;"></div>
<div class="range-point" style="bottom:66.666%;left:66.666%;"></div>
<div class="range-point" style="bottom:100%;left:100%;"></div>
</div>
</div>
CSS:
.range-display {
background-color: gray;
height: 90px;
position: relative;
width: 160px;
}
.range-cocoon {
background-color: silver;
bottom: 0;
height: 75%;
left: 0;
position: absolute;
width: 75%;
}
.range-point {
background-color: lime;
height: 33.333%;
position: absolute;
width: 33.333%;
}