I have a problem with my CSS regarding div positions.
I have a parent div which is set to position:relative and a child div set to position:absolute
But for some reason the child div is displaying below and outside the borders of the parent div...
This is my CSS:
.big{
position:relative;
width:40%;
border:1px solid black;
display:inline-block;
}
.small{
position:absolute;
width:75px;
height:75px;
border:1px solid green;
}
The HTML:
<div class="big">
<p align="center">Test</p>
<div class="small"></div>
</div>
<div class="big">
<p align="center">Test</p>
<div class="small"></div>
</div>
I have provided a JSFiddle to show you it in action:
http://jsfiddle.net/j6VLc/1/
How do i fix it to make the child div be inside the parent div whilst using position:absolute for it?
You can't do this using position: absolute as it removes the element from the normal document flow. position: relative on the parent will change where the position: absolute is positioned relative to, but it will not expand to contain the position: absolute. You will need to set a fixed height or using position: relative instead.
Note, if using position: relative in your example, you will need to add a margin-bottom equal to the value of top to make it expand to contain the position: relative.
.big {
position: relative;
width: 40%;
border: 1px solid black;
display: inline-block;
}
.small {
position: relative;
width: 75px;
height: 75px;
border: 1px solid green;
top: 50px;
left: 40px;
margin-bottom: 50px;
margin-right: 40px;
}
<div class="big">
<p align="center">Test</p>
<div class="small"></div>
</div>
<div class="big">
<p align="center">Test</p>
<div class="small"></div>
</div>
As you have given a height of 75px to the child div and inside the parent div you have also given <p> which is a block element so the <p> tag is making its space and after that your child div is appearing....Make the div height of parent element larger than child and style the <p> tag to display: inline;
.big {
position: relative;
width: 40%;
height: 100px;
border: 1px solid black;
display: inline-block;
}
.small {
position: absolute;
width: 75px;
height: 75px;
border: 1px solid green;
}
p {
display: inline;
}
Hope this will get you to what you want.
Related
I have a child div, who's position is absolute and the left property is like -20px (just negative). The parent div has overflow:scroll but it does not allow to scroll to the left.
I've tried to delete parents or add wrappers, tried without the position properties, etc...
html
<div class="container">
<div class="levels">
<div class="level">
<div class="node">Node1</div>
<div class="node">Node2</div>
<div class="node">Node3</div>
<div class="node">Node4</div>
<div class="node">Node5</div>
</div>
</div>
</div>
css
.container {
border: 1px solid red;
margin: 20px;
height: 200px;
width: 900px;
overflow: scroll;
}
.levels {
width: 100%;
height: 100%;
position: relative;
}
.level{
border: 2px solid black;
width: 536px;
position: absolute;
left: -20px;
}
.node {
background-color: blue;
border: 2px green solid;
width: 100px;
display: inline-block;
}
I've simulated a scenario in a CodePen
Id like to have more of those 'level' divs and even more aligned to the left, so i can simulate like a flow tree. If this isn't the way to go i'd like to hear.
This has me stumped. I applied a border-right, border-left, and border-bottom to a div which has another Green BG color div inside of it. I set the z-index: 1 and position: relative on the parent div with the borders.
However, as you can see in the photo, only the LEFT border gets the z-index applied to it, whereas the RIGHT border doesn't get the z-index and falls behind the green div.
This ONLY happens if I have a width set on the inner-div wider than the outer div, and it only seems to prevent the first border-right from coming above the bg, as a repeating element doesn't suffer from this issue.
This makes no sense, and it's consistent across Chrome, Firefox, and Edge.
Is this some weird quirk / bug with CSS that I just discovered? Or am I somehow completely messing this up?
.flex-div {
display: flex;
}
.outer-div {
position: relative;
border-right: 7px solid #cccccc;
border-bottom: 1px solid #cccccc;
border-left: 7px solid #cccccc;
z-index: 1;
max-width: 200px;
flex: 0 0 200px;
}
.mid-div {
width: 600px;
z-index: -1;
position: relative;
}
.inner-div {
background-color: #00b989;
width: 250px;
height: 50px;
display: inline-block;
z-index: -1;
position: relative;
}
<div class="flex-div">
<div class="outer-div"> outer
<div class="mid-div">
<div class="inner-div">inner</div>
<div class="inner-div">inner</div>
</div>
</div>
<div class="outer-div"> outer </div>
<div class="outer-div"> outer </div>
<div>
Could you help me diagnose the reason why this is happening, and any workaround to get the borders on both the left and right of the outer-div to overlay the -inner-div?
You cannot control the z-index in relation to its children because they are contained so (in a sense) inherit the z-index.
But you can make the children go behind their parent by setting their z-index to -1.
.outer-div {
position: relative;
flex: 0 0 200px;
border: 7px solid #cccccc;
max-width: 200px;
}
.inner-div {
background-color: #00b989;
width: 250px;
height: 50px;
position:relative;
z-index:-1;
}
<div class="outer-div"> outer
<div class="inner-div">inner</div>
</div>
or you could apply overflow:hidden on the parent so that the green bar is hidden when larger (if that suits your needs)
.outer-div {
flex: 0 0 200px;
border: 7px solid #cccccc;
max-width: 200px;
overflow:hidden;
}
.inner-div {
background-color: #00b989;
width: 250px;
height: 50px;
}
<div class="outer-div"> outer
<div class="inner-div">inner</div>
</div>
To fix your issue you need to apply z-index to child elements not to parent element (keep the parent with z-index auto)
All the border on the top:
.flex-div {
display: flex;
}
.outer-div {
border-right: 7px solid #cccccc;
border-bottom: 1px solid #cccccc;
border-left: 7px solid #cccccc;
max-width: 200px;
flex: 0 0 200px;
}
.mid-div {
width: 600px;
z-index: -1;
position: relative;
}
.inner-div {
background-color: #00b989;
width: 250px;
height: 50px;
display: inline-block;
z-index: -1;
position: relative;
}
<div class="flex-div">
<div class="outer-div"> outer
<div class="mid-div">
<div class="inner-div">inner</div>
<div class="inner-div">inner</div>
</div>
</div>
<div class="outer-div"> outer </div>
<div class="outer-div"> outer </div>
<div>
All the border on the bottom
.flex-div {
display: flex;
}
.outer-div {
border-right: 7px solid #cccccc;
border-bottom: 1px solid #cccccc;
border-left: 7px solid #cccccc;
max-width: 200px;
flex: 0 0 200px;
}
.mid-div {
width: 600px;
z-index: 1;
position: relative;
}
.inner-div {
background-color: #00b989;
width: 250px;
height: 50px;
display: inline-block;
z-index: -1;
position: relative;
}
<div class="flex-div">
<div class="outer-div"> outer
<div class="mid-div">
<div class="inner-div">inner</div>
<div class="inner-div">inner</div>
</div>
</div>
<div class="outer-div"> outer </div>
<div class="outer-div"> outer </div>
<div>
To understand your initial issue you need to consider painting order and stacking context. By applying z-index to parent element you create a stacking context and since all of them have the same z-index they will be painted considering the tree order. So we print the first element and ALL its content then the second and ALL its content and so on.
Following this logic you will see the left border of the first and the right one will be hidden due to the overflow of the content then you will see the left border of the second element on the top of all the previous content and so on.
Here is a basic example to better illustrate your issue:
.box {
border-left:10px solid red;
border-right:10px solid red;
height:50px;
width:100px;
display:inline-block;
vertical-align:top;
position:relative;
z-index:1;
}
.box > div {
width:130%;
height:60%;
background:blue;
}
<div class="box">
<div></div>
</div><div class="box" style="margin-top:20px;">
<div></div>
</div><div class="box" style="margin-top:30px;">
<div></div>
</div>
Added some offset to parent element so you can clearly identify the painting order.
Now if you set positive z-index to only child elements they will all get painted on the top of the all the parent elements.
.box {
border-left:10px solid red;
border-right:10px solid red;
height:50px;
width:100px;
display:inline-block;
vertical-align:top;
}
.box > div {
width:130%;
height:60%;
background:blue;
position:relative;
z-index:1;
}
<div class="box">
<div></div>
</div><div class="box" style="margin-top:20px;">
<div></div>
</div><div class="box" style="margin-top:30px;">
<div></div>
</div>
And if you apply negative z-index they will all get painted behind:
.box {
border-left:10px solid red;
border-right:10px solid red;
height:50px;
width:100px;
display:inline-block;
vertical-align:top;
}
.box > div {
width:130%;
height:60%;
background:blue;
position:relative;
z-index:-1;
}
<div class="box">
<div></div>
</div><div class="box" style="margin-top:20px;">
<div></div>
</div><div class="box" style="margin-top:30px;">
<div></div>
</div>
Applying any z-index value to parent element will make what you want impossible since the child elements will get trapped inside the stacking context of their parent.
Related question for more details: Why can't an element with a z-index value cover its child?
The relative and absolute positioning are great tools, but they take elements out of the flow and this leads to some restrictions in their use. I think I just encountered one of them but I'd love someone to prove me wrong.
To state it clearly: I have a div positioned relatively to its parent. The problem is, under certain conditions, this out-of-flow element can go further than the top element (e.g. the body) and add a horizontal scrollbar. Demo below:
.top-container {
width: 80%;
height: 100px;
margin: auto;
border: dashed 2px red;
}
.container {
width: 80%;
height: 50px;
margin: 25px auto;
border: dotted 1px blue;
position: relative;
}
.absolute {
width: 100%;
background-color: black;
color: white;
position: absolute;
top: 30%;
right: -50%;
}
<div class="top-container">
<div class="container">
<div class="absolute">
absolutely
</div>
</div>
</div>
My question is: is there a way to tell CSS absolutely positioned elements should not go further left or right than the borders of .top-container? Something that would behave like a sort of max-left/max-right.
(e.g. in my example, move the black div so that it does not go outside of the red dashed line)
If you decided to position the element in an exact position - you can't say that you want it to be positioned somewhere. You can use right/left margin (or position with percentages).
Another option is to use the overflow option to set the scroller on the container (or to specify that if the element is getting out of it's container it should be hidden):
.top-container {
width: 80%;
height: 100px;
margin: auto;
border: dashed 2px red;
}
.container {
width: 80%;
height: 50px;
margin: 25px auto;
border: dotted 1px blue;
position: relative;
overflow: auto;
}
.hidden-overflow {
overflow: hidden;
}
.absolute {
width: 100%;
background-color: black;
color: white;
position: absolute;
top: 30%;
right: -50%;
}
<div class="top-container">
<div class="container">
<div class="absolute">
absolutely
</div>
</div>
</div>
<div class="top-container">
<div class="container hidden-overflow">
<div class="absolute">
absolutely
</div>
</div>
</div>
There is a simple example where a div element contains h3.
But the h3 element drops down its parent div when h3 has position relative.
Changing h3 position to absolute solves this problem.
What is the reason?
.personal-details{
background-color: green;
}
.personal-image{
display: inline-block;
width: 150px;
height: 150px;
background-color: white;
}
.personal-description {
display: inline-block;
width: 150px;
height: 150px;
background: black;
}
.personal-description h3 {
position: relative; /*absolute solves the problem*/
}
<div class="personal-details">
<div class="personal-image"></div>
<div class="personal-description"><h3 class="name">My Name</h3></div>
</div>
This is caused by the default vertical-align: baseline; property of inline-block elements.
Overriding the default with vertical-align: top for your element will get you somewhere like correct:
.personal-details {
background-color: green;
vertical-align: middle
}
.personal-image {
display: inline-block;
width: 150px;
height: 150px;
background-color: green;
}
.personal-description {
display: inline-block;
width: 150px;
height: 150px;
background: black;
vertical-align: top;
}
.personal-description h3 {
position: relative;
background: yellow;
}
<div class="personal-details">
<div class="personal-image"></div>
<div class="personal-description"><h3 class="name">My Name</h3></div>
</div>
Notice I say "somewhere like correct" as you will still have issues with space around the elements (notice the gap below the black square and space between the two child divs). But that is out of the scope of your question and has been dealt with many times before.
.personal-details{
background-color: red;
}
.personal-image{
display: inline-block;
width: 150px;
height: 150px;
background-color: green;
margin:0;
}
.personal-description {
float:left;
display: inline-block;
width: 150px;
height: 150px;
background: black;
margin:0;
padding:0;
}
.personal-description h3 {
margin:0;
background-color:blue;
padding:0;
position: relative; /*absolute solves the problem*/
}
<div class="personal-details">
<div class="personal-image"></div>
<div class="personal-description"><h3 class="name">My Name</h3></div>
</div>
May be your are familiar with all the positioning.Firstly, you need to understand about it.There are four possible useful positioning in css which are given below.
Static
Relative
Absolute.
Fixed
-Static positioning:
It is basically a default position of every element or tag, use of this position will never effect on your element’s state or position.In static we can not use top,left, bottom & right properties.
position:static;
-Relative:
Relative positioning,makes element or tag movable.Yes, we can move it any where on container.By default it works like an static but we can use left,top,bottom & right in it.
position: relative;
top:50px;
left:50px;
-Absolute:
Absolute positioning, get the space according to browser window or container(that may be parent or ancestor) window.If container window’s position set to relative than absolute will get the position according to container.
position:absolute;
left:0px;
right:0px;
Task: Now, make a parent div and it’s two child's and check both relative and absolute.
/* Example */
</div>
<div class='box2'>
<h3>Here my name</h3>
</div>
</div>
.parent_box{
background-color:grey;
margin-top: 20px;
}
.box1{
height:200px;
width: 200px;
background-color:red;
display: inline-block;
}
.box2{
height: 200px;
width: 200px;
background-color:yellow;
display: inline-block;
position: relative;
}
.box2 h3{
position: absolute;
/* Working according to it's parent because it's parent div contains relative position now check it by given it left top and remove the position relative of box2*/
}
I have a relative parent div and a fixed child div. i would like the relative parent to get the width from the child div.
<div id="parent">
<div id="child">
</div>
</div>
Css Code;
#parent {
position: relative;
top: 40px;
left: 20px;
background-color: #F1A323;
padding: 20px;
box-shadow: 10px 10px 5px #0F0F0F;
border:2px solid;
border-radius:25px;
-webkit-border-radius: 25px;
behavior: url(pie/PIE.htc);
}
#child{
position: fixed;
background-color: #FDF0DA;
height: 100px;
}
#parent{width:500px;}
#child{width:100%}
It may help.
Use the following:
#child{
width:100%;
}
If that doesnot work, use:
#child{
min-width:100%;
max-width:100%;
}
Give the width to parent div(which you want to give to the child div)
#parent {
width: 650px;
}
#child {
width: 100%;
}
the parent and child div are always equal.