I need to overlay a child div to cover it's parent div when my drag and drop event starts, but I can't get the child div to be on top of the parent using z-index.
Here is my HTML:
<div class="some-element">
<div class="parent-div">
<div class="child-div">
<p>This should be over the parent</p>
</div>
<h1>Some text lorem ipsum</h1>
</div>
<div class="another-div">
<p>lorem ipsum</p>
</div>
</div>
And here is my CSS
html, body {
height: 100%;
width: 100%;
}
.some-element {
background-color: blue;
width: 100%;
}
.parent-div {
background-color: red;
height: 100%;
position: relative;
width: 100%;
z-index: 1;
}
.child-div {
background-color: green;
height: 100%;
position: relative;
width: 100%;
z-index: 999;
}
Here is a CodePen demonstrating my issue: https://codepen.io/leofontes/pen/LkgJpo
I thought by using z-index and position relative I would be able to achieve what I wanted, but it doesn't seem to stack on top of the parent. Any idea on what is going on?
For .child-div change the positioning to absolute.
.child-div {
background-color: green;
height: 100%;
position: absolute;
width: 100%;
z-index: 999;
}
html,
body {
height: 100%;
width: 100%;
}
.some-element {
background-color: blue;
width: 100%;
}
.parent-div {
background-color: red;
height: 100%;
position: relative;
width: 100%;
z-index: 1;
}
.child-div {
background-color: green;
height: 100%;
position: absolute;
width: 100%;
z-index: 999;
}
<div class="some-element">
<div class="parent-div">
<div class="child-div">
<p>This should be over the parent</p>
</div>
<h1>Some text lorem ipsum</h1>
</div>
<div class="another-div">
<p>lorem ipsum</p>
</div>
</div>
Relative positioning will move something relative from it's current location but continue to take up space in it's original location. Take a look at the example below. When I use relative positioning to move the "text" segment, notice the line of text doesn't collapse down to a single space between "Some" and "here."
span {
position: relative;
top: 20px;
left: 20px;
background-color: yellow;
}
<p>
Some <span>text</span> here.
</p>
When you set an element to absolute positioning you take it out of the normal document flow. Meaning they don't take up space as far as other non absolute positioned elements are concerned. This is why you need to use height: 100%; and width: 100%; to make sure the child element matches the dimensions of the parent when using absolute positioning.
By default padding will add to the 100% dimensions. To prevent this use box-sizing: border-box;.
An alternative to height: 100%; and width: 100%; is to use top: 0; right: 0; bottom: 0; left: 0;. That will stretch the child element to the edges of the parent element.
Related
Is it possible to make a div absolute to a specific relative div rather than just the parent?
For example. I have a div that's contained inside of a row. But, I want it to be absolute in the section rather than the row. Both divs are positioned relative because of a WordPress themes styling. If I use position absolute it will just make it absolute to the row.
How can I get around this issue?
.section {
width: 100%;
height: 100%;
position: relative;
background: #f5f5f5;
}
.row {
width: 80%;
height: 100%;
position: relative;
background: #000000;
margin: 0 auto;
}
.content {
width: 200px;
height: 200px;
background: pink;
position: absolute;
right: 0;
top: 0;
}
<div class="section">
<div class="row">
<div class="content">
</div>
</div>
</div>
This is not how positioning works. A div or any other element is relevant to its parent regarding its positioning. In case you want to position an element inside the section that you have, it's better to construct your code as follows:
<div class="section">
<div class="absoluteDiv">
</div>
<div class="row">
</div>
</div>
You could find some more examples here
Hope it helps,
Konstantinos.
Although you can not make a div absolute to a specific div, one way to get the results you are looking for is to add overflow:visible; to the row and left:100%; to content container. I changed the section height to 300px for demonstration purposes but it will behave the same with 100%.
.section {
width: 100%;
height: 300px;
position: relative;
background: #f5f5f5;
}
.row {
width: 80%;
height: 100%;
position: relative;
background: #000000;
margin: 0 auto;
overflow:visible;
}
.content {
width: 200px;
height: 200px;
background: pink;
position: absolute;
left: 100%;
top: 0;
}
<div class="section">
<div class="row">
<div class="content">
</div>
</div>
</div>
So, I'm trying to build a site that features various different sized images, one at a time, that are centered and size constrained by a parent div, then resized to preserve their ratio.
#grandparent {
display: block;
position: fixed;
width: 70vw;
height: 85vh;
top: 10vh;
left: 15vw;
}
.parent {
position: relative;
display: block;
width: 100%;
height: 70vh;
}
.resizedimage {
max-width: 100%;
max-height: 100%;
display: block;
margin: auto;
}
<div id="grandparent">
<div class="parent">
<img src="1.jpg" class="imageprime">
<div class="description">Words<br>more words</div>
</div>
</div>
I want the description below to stick below the bottom left corner of the image, which it currently does when max-width is the one being constrained, but when max-height is being constrained, it moves past the left of the image. I can't figure out how to keep them in line!
All the methods I've seen revolve around moving a container div to 50% then padding back to -50%, or something like that. But as I depend on the image dictating the width and height dynamically, I don't know how to translate that to a container div, or just to the text below!
It is quite simple: you need a container that will be sized by image in it with position: relative and your description should have position: absolute so it will be positioned against container which, in its turn will be sized by image. Something like this:
#grandparent {
display: block;
position: fixed;
width: 70vw;
height: 85vh;
top: 10vh;
left: 15vw;
}
.parent {
position: relative;
display: block;
width: 100%;
height: 70vh;
}
.image-container {
display: block;
margin: 0 auto;
position: relative;
}
.resizedimage {
max-width: 100%;
max-height: 100%;
}
.description {
position: absolute;
left: 5px;
bottom: 5px;
}
<div id="grandparent">
<div class="parent">
<div class="image-container">
<img src="https://dummyimage.com/300x200/347508/000000.png" class="resizedimage">
<div class="description">Words<br>more words</div>
</div>
</div>
</div>
I'm using particles.js and am trying to fill a relative section with the absolutely positioned particle content.
The problem I'm having is that the height of the relative section is dynamic and I can't seem to get the the absolutely positioned inner div to only fill the relative container.
Been searching and trying various things but haven't found any solutions. Here is a jsfiddle showing the issue: http://jsfiddle.net/awwester/3f6vkef7/1/
<div class="container">
<div class="inner">
</div>
</div>
.container {
height: 200px;
background-color: red;
}
.inner {
position: absolute;
height: 100%;
width: 100%;
background: rgba(0,0,0,0.5);
}
and I can't seem to get the the absolutely positioned inner div to only fill the relative container.
The key is adding the property position: relative to your container.
Try the following example:
.container {
height: 200px;
background-color: red;
position: relative;
}
.inner {
position: absolute;
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.5);
}
<div class="container">
<div class="inner">
</div>
</div>
you forgot to set position: relative; on .container so .inner apply to body/html
.container {
height: 200px;
background-color: red;
position: relative;
}
.inner {
position: absolute;
height: 100%;
width: 100%;
background: rgba(0,0,0,0.5);
}
<div class="container">
<div class="inner">
</div>
</div>
I'm trying to create some static content using a div with position: fixed and then allow a solid div with a background-color to scroll over it and hide the static text below.
HTML:
<div class="container">
<div class="static-background">
<p>Why can I see this through the yellow div?</p>
<p> this should be clickable
</p>
</div>
<div class="overlay"></div>
</div>
CSS:
.container {
position: absolute;
top: 0;
width: 100%;
height: 100%;
}
.static-background {
position: fixed;
}
.overlay {
background-color: yellow;
height: 200%;
margin-top: 200px;
}
But the yellow div just shows the text through from the fixed background.
Why is this?
By setting z-index: -1; in .static-background i get the desired behaviour, except that the link is no longer clickable and the text is not selectable.
How do I make the background of .overlay hide the fixed elements behind while still allowing interaction (until hidden)?
Fiddle here.
.container {
position: absolute;
top: 0;
width: 100%;
height: 100%;
}
.static-background {
position: fixed;
}
.overlay {
background-color: yellow;
height: 200%;
margin-top: 200px;
}
<div class="container">
<div class="static-background">
<p>Why can I see this through the yellow div?</p>
<p> this should be clickable
</p>
</div>
<div class="overlay"></div>
</div>
When you give the element .static-background a negative z-index, it is being placed behind the parent .container element, which is why the element is unclickable.
To work arond this, you need to give the parent element, .container, a z-index to establish a stacking context between the elements.
In this case, you can simply give it a z-index of 1.
Updated Example
.container {
position: absolute;
top: 0;
width: 100%;
height: 100%;
z-index: 1; /* Added */
}
.container {
position: absolute;
top: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.static-background {
position: fixed;
z-index: -1;
}
.overlay {
background-color: yellow;
height: 200%;
margin-top: 200px;
}
<div class="container">
<div class="static-background">
<p>Some text</p>
<p>this should be clickable</p>
</div>
<div class="overlay"></div>
</div>
As an alternative, you could also just give the element .overlay a z-index of 1, and remove the z-indexs from the other elements. (example)
You might want to add some z-index to your elements:
.container {
position: absolute;
top: 0;
width: 100%;
height: 100%;
}
.static-background {
position: fixed;
z-index: 99;
}
.overlay {
background-color: yellow;
height: 200%;
margin-top: 200px;
position: relative;
z-index: 100;
}
Change your css to this...
.container {
position: absolute;
top: 0;
width: 100%;
height: 100%;
}
.static-background {
position: fixed;
z-index:4;
}
.overlay {
background-color: yellow;
height: 200%;
margin-top: 200px;
z-index:5;
position:relative;
}
Working JSFiddle http://jsfiddle.net/DivakarDass/mcdbopj6/3/
html:
<div id="main">
<div style="position: absolute; height: 150px; width: 400px; left: 290px;"><img src="HEAD-IMAGE.jpg" /></div>
<div style="position: absolute; height: 300px; width: 233px; top: 180px;"><img src="LEFT-IMAGE.jpg" />(below head)</div>
<div style="position: absolute; top: 200px; left: 270px;">TEXT (next to left image)</div>
</div>
css:
div#main{
position: absolute;
top: 141px; left: 50%;
height: 100%; width: 960px;
padding: 10px;
margin-left: -490px;
text-align: justify;
background-color: yellow;
}
my padding from #main works for my images but not for my text (right & bottom padding).
Why is this happening?
In your example, only the text div has a top and left property. The two divs containing the images only contain one of these properties:
The header div has left: 290px;, so it gets its y-axis position moved by the top padding.
The left div has top: 180px; so it gets its x-axis position moved by the left padding.
The text div has top: 200px; left: 270px; so its x and y-axis are not affected by the padding.
To illustrate this, for this example the text div has had its left property removed. It is now affected by the left padding of its container:
("Show code snippet" and run it)
#main {
position: absolute;
top: 141px;
left: 50%;
height: 100%;
width: 960px;
padding: 50px;
margin-left: -290px;
text-align: justify;
background-color: yellow;
}
.header {
position: absolute;
height: 150px;
width: 400px;
left: 290px;
background: #F00;
}
.left {
position: absolute;
height: 300px;
width: 233px;
top: 180px;
background: #F00;
}
.text {
position: absolute;
top: 200px;
background: #F00;
}
<div id="main">
<div class="header">
<img src="http://www.placehold.it/200" />
</div>
<div class="left">
<img src="http://www.placehold.it/200" />
</div>
<div class="text">You can't handle the truth, soldier!</div>
</div>
Is position: absolute the best way to layout my elements?
Depends... position: absolute removes elements from the normal flow of the document. That is, each element is essentially invisible to the other. This is particularly problematic if you wish to create a flexible layout, which can re-size in accordance with the users browser height / width.
Can you show me another way to layout HTML elements?
Sure! There are many ways to layout a page without resorting to position: absolute. Here is a basic example using display: flex — a newer way to layout elements. It does not enjoy 100% browser support yet, so this is purely an example of one technique :)
Read more:
about vw and vh units on the MDN
about flexbox over on CSS-Tricks - A Complete Guide to Flexbox
about flexbox browser support
Flex example
Note how the elements resize when the example is made full-screen.
* {
margin: 0;
padding: 0;
}
body {
width: 80vw;
max-width: 800px;
margin: 0 auto;
background: #424242;
}
header {
background: #e91e63;
height: 20vh;
}
.wrap {
display: flex;
}
.left {
background: #fce4ec;
flex: 1;
}
.content {
background: #fafafa;
min-height: 70vh;
flex: 2;
}
footer {
height: 10vh;
background: #c51162;
}
<header>
I am header
</header>
<div class="wrap">
<div class="left">
I am sidebar
</div>
<div class="content">
I am content
</div>
</div>
<footer>
I am footer, hear me roar! RWAR!
</footer>
Define a class .child for your <div>
<div class="child">
and define style accordingly
.child { padding: 10px; }
Use position: relative; on the child divs to make them account for the parent divs padding.
problem is you give left and top to text div that why not accept padding,simply remove left to text div then it will accept the padding...