Unexpected CSS Positioning Bug - html

I have the following code :
<!DOCTYPE html>
<html>
<head>
<title>Kastflix</title>
<style type="text/css">
.moviepane { background-color: #181816; top: 41px; left: 181px; position: fixed; width: 100%; height: 100%; }
.movietile { background-color: #181816; margin-top: 13px; margin-left: 12px; margin-right: 12px; width: 135px; height: 235px; display:inline-block; vertical-align: top }
.movieposter { width: 135px; height: 197px; border:1px solid #000000; border-radius: 3px; transition: all 0.5s; position: absolute; }
.movieposter:hover { border:1px solid #0094ff; }
.linkoverlay { width: 137px; height: 199px; background-color: #000000; opacity: 0; transition: all 0.5s; pointer-events: none; }
.movieposter:hover + .linkoverlay { opacity: 0.6; }
</style>
</head>
<body>
<div class="moviepane">
<div class="movietile">
<a href="a">
<img class="movieposter" src="\movies\Delivery%20Man%20(2013)%20%5B1080p%5D\Delivery%20Man%20(2013)%20%5B1080p%5D.jpg"></img>
<div class="linkoverlay"></div>
</a>
<p class="moviename">Delivery Man</p>
<p class="movieyear">2013</p>
</div>
</div>
</body>
</html>
When I hover over a movie tile, It looks like this :
As I see it, the movie poster is positioned absolute, so it will be relative to the closest parent container with a non-static position type. But In this case, there is none. So shouldn't it be relative to the document? Why is the movieposter relative to the movietile?
Any help is appreciated!

You haven't specified any offsets on the element despite it being absolutely positioned, so it will not move from its static position regardless of its containing block (i.e. regardless of whether any of its ancestors are themselves positioned or if it is anchored to the initial containing block otherwise).
This is intended behavior; see my answer to this question for why exactly it works this way when the offsets are not specified.
Note however that absolutely positioning this element does affect its following sibling (the overlay), because absolute positioning removes the element from normal flow and so its following sibling is no longer aware of its position.

Related

Mouseover image reveal pushes text despite z-Index

I have my code set up so when you hover over the H2 an image is revealed. Hypothetically, because the text is z-index:2 and the image is z-index:1, the H2 text should stay fixed. However, upon mouseover, the text is still being moved down to make room for the image.
I need the text to stay fixed in the same position and the background image to just appear upon hover without nudging the h2.
You can view the test here:
http://www.rorywolfseydel.com/test3-2
h2 {
line-height: 68px !important;
text-transform: uppercase;
letter-spacing: 2px;
font-size: 80px;
font-weight: 0 !important;
color: #ffffff;
z-index: 12;
}
.artisthover {
display: none
}
h2.two:hover img {
display: block;
z-index: -1;
position: relative;
margin-top: -200px;
margin-left: -250px
}
h2.two a {
color: #ffffff;
}
h2.three:hover img {
display: block;
z-index: -1;
position: relative;
margin-top: -200px;
margin-right: -250px
}
h2.three a {
color: #ffffff;
}
<center>
<h2 class="two">
ABSOLUTELY FREE
<img src="http://lawnyavawnya.com/2018/2019artists/absolutelyfree.jpg" class="artisthover" width="500px">
</h2>
</center>
<center>
<h2 class="three">
BADGE EPOQUE ensemble
<img src="http://lawnyavawnya.com/2018/2019artists/badgeepoque.jpg" class="artisthover" width="500px">
</h2>
</center>
Hypothetically, because the text is z-index:2 and the image is z-index:1, the H2 text should stay fixed. This is an incorrect assumption on how z-index works.
z-index is stacking order of elements, having a higher or lower z-index does not mean that elements with a higher z-index will automatically appear on top of each other. You need to use position for that.
For instance, two elements with different z-index values, but with position relative, are positioned relative to one another - meaning the elements affect each other's positioning, even if one has a higher or lower z-index.
Here's a simple example:
.top {
height: 200px;
background: purple;
position: relative;
z-index: 1;
box-shadow: 0px 0px 20px rgba(0, 0, 0, .5);
}
.top:hover {
z-index: 3;
}
.bottom {
height: 300px;
background: yellow;
position: relative;
z-index: 2;
}
<div class="top">
</div>
<div class="bottom">
</div>
As you can see, the elements have different z-index values, but the position is relative. If you hover the top div, you can see the box-shadow overlapping the bottom div, but the position of the elements does not change in regards to top, right, bottom, left - only the stacking order.
Now for your specific example:
Here we use position: absolute to take the img element out of the document flow, allowing you to take advantage of z-index. Since the image is now out of document flow, it no longer affects any other element around it.
The snippet below is a very simple demonstration with the position changed on the image. It probably doesn't look how you want it to, but it's a starting point.
Couple other things:
The <center> tag is obsolete. You should use text-align: center on the h2 instead.
Depending on your end goal for how you want it to look, I would consider moving the image out of the h2 tags and wrapping the h2 and img in a containing element (e.g. div). This will allow for better control over the placement of the image once it's visible.
h2 {
line-height: 68px !important;
text-transform: uppercase;
letter-spacing: 2px;
font-size: 80px;
font-weight: 0 !important;
color: #000;
z-index: 12;
text-align: center;
}
.artisthover {
display: none
}
h2.two:hover img {
display: block;
z-index: -1;
position: absolute;
margin-top: -200px;
margin-left: -250px
}
h2.two a {
color: #000;
}
h2.three:hover img {
display: block;
z-index: -1;
position: absolute;
margin-top: -200px;
margin-right: -250px
}
h2.three a {
color: #000;
}
<h2 class="two">
ABSOLUTELY FREE
<img src="http://lawnyavawnya.com/2018/2019artists/absolutelyfree.jpg" class="artisthover" width="">
</h2>
<h2 class="three">
BADGE EPOQUE ensemble
<img src="http://lawnyavawnya.com/2018/2019artists/badgeepoque.jpg" class="artisthover" width="500px">
</h2>
<!DOCTYPE html>
<html>
<head>
<style>
.artisthover {
display: none
}
img {
position: absolute;
left: 0px;
top: 0px;
z-index: -1;
}
h2.two:hover img {
display:inline ;
}
h2.three:hover img {
display:inline ;
}
</style>
</head>
<body>
<center>
<h2 class="two">
ABSOLUTELY FREE
<img src="http://lawnyavawnya.com/2018/2019artists/absolutelyfree.jpg" class="artisthover" width="500px">
</h2>
</center>
<center>
<h2 class="three">
BADGE EPOQUE ensemble
<img src="http://lawnyavawnya.com/2018/2019artists/badgeepoque.jpg" class="artisthover" width="500px">
</h2>
</center>
</body>
</html>
Well, to set z-index on the image, the position has to be absolute for the image to stay the same, as well as the display of the outer element be inline....

Absolutely-positioned element is affected by padding on parent

my question is why changing padding in div.container affects div.blueBox? Since blueBox positioning is set to absolute it is taken out of normal flow, and should be positioned with relation to element.
HTML:
<body>
<div class="container">
<div class="box blueBox"></div>
</div>
<div class="box greenBox"></div>
<h1>Understanding CSS Positioning</h1>
<p><em>Absolute positioning</em> takes an element out of document flow, meaning the browser acts as if the element has no width and height, and the other elements on the page move up as if it was never there. The position of the element is then fixed relative to the top level container, or the closest parent with a set positioning.</p>
</body>
CSS:
body {
background-color: #1f1f1f;
height: 2000px;
color: #bfbfbf;
}
h1 {
font-weight: normal;
}
em {
color: #dd740b;
}
.box {
width: 100px;
height: 100px;
margin-bottom: 10px;
}
.blueBox {
background: #627da0;
position: absolute;
}
.greenBox {
background: #5b8054;
}
.container {
background: rgba(0,0,0,.4);
padding: 10px;
}
http://jsfiddle.net/pawelpodsiadly/brdc8dvy/
Absolute positioning puts an element in place with respect to its closest ancestor that also has positioning other than static.
If you want .blueBox positioned relative to the body, set top and left values:
body {
background-color: #1f1f1f;
color: #bfbfbf;
}
.box {
width: 100px;
height: 100px;
margin-bottom: 10px;
}
.blueBox {
background: #627da0;
position: absolute;
top: 0;
left: 0;
}
.container {
background: pink;
padding: 10px;
}
<body>
<div class="container">
<div class="box blueBox"></div>
</div>
<div class="box greenBox"></div>
<h1>Understanding CSS Positioning</h1>
<p><em>Absolute positioning</em> takes an element out of document flow, meaning the browser acts as if the element has no width and height, and the other elements on the page move up as if it was never there. The position of the element is then fixed relative
to the top level container, or the closest parent with a set positioning.</p>
</body>
If you wanted it positioned with respect to .container, you'll need to position .container:
body {
background-color: #1f1f1f;
color: #bfbfbf;
}
.box {
width: 100px;
height: 100px;
margin-bottom: 10px;
}
.blueBox {
background: #627da0;
position: absolute;
top: 0;
left: 0;
}
.container {
background: pink;
padding: 10px;
position: relative;
}
<body>
<div class="container">
<div class="box blueBox"></div>
</div>
<div class="box greenBox"></div>
<h1>Understanding CSS Positioning</h1>
<p><em>Absolute positioning</em> takes an element out of document flow, meaning the browser acts as if the element has no width and height, and the other elements on the page move up as if it was never there. The position of the element is then fixed relative
to the top level container, or the closest parent with a set positioning.</p>
</body>
When adding a position absolute, you need to define:
position: absolute;
left: 0;
top: 0;
You need to define the rest of the position elements. Like top or left, etc.
You may also be wanting relative and not absolute.
.blueBox {
background: #627da0;
position: absolute;
top: 0;
left: 0;
}
Fiddle updated

Floating Div Over An Image

I'm having trouble floating a div over an image. Here is what I am trying to accomplish:
.container {
border: 1px solid #DDDDDD;
width: 200px;
height: 200px;
}
.tag {
float: left;
position: relative;
left: 0px;
top: 0px;
z-index: 1000;
background-color: #92AD40;
padding: 5px;
color: #FFFFFF;
font-weight: bold;
}
<div class="container">
<div class="tag">Featured</div>
<img src="http://www.placehold.it/200x200">
</div>
In this image:
I want the "Featured" box to float over top of the image but instead it seems to "clear" the float and cause the image to wrap to the next line, as though it was displaying as a block element. Unfortunately, I can't figure out what I am doing wrong. Any ideas?
Never fails, once I post the question to SO, I get some enlightening "aha" moment and figure it out. The solution:
.container {
border: 1px solid #DDDDDD;
width: 200px;
height: 200px;
position: relative;
}
.tag {
float: left;
position: absolute;
left: 0px;
top: 0px;
z-index: 1000;
background-color: #92AD40;
padding: 5px;
color: #FFFFFF;
font-weight: bold;
}
<div class="container">
<div class="tag">Featured</div>
<img src="http://www.placehold.it/200x200">
</div>
The key is the container has to be positioned relative and the tag positioned absolute.
Change your positioning a bit:
.container {
border: 1px solid #DDDDDD;
width: 200px;
height: 200px;
position:relative;
}
.tag {
float: left;
position: absolute;
left: 0px;
top: 0px;
background-color: green;
}
jsFiddle example
You need to set relative positioning on the container and then absolute on the inner tag div. The inner tag's absolute positioning will be with respect to the outer relatively positioned div. You don't even need the z-index rule on the tag div.
Actually just adding margin-bottom: -20px; to the tag class fixed it right up.
http://jsfiddle.net/dChUR/7/
Being block elements, div's naturally have defined borders that they try not to violate. To get them to layer for images, which have no content beside the image because they have no closing tag, you just have to force them to do what they do not want to do, like violate their natural boundaries.
.container {
border: 1px solid #DDDDDD;
width: 200px;
height: 200px;
}
.tag {
float: left;
position: relative;
left: 0px;
top: 0px;
background-color: green;
z-index: 1000;
margin-bottom: -20px;
}
Another toue to take would be to create div's using an image as the background, and then place content where ever you like.
<div id="imgContainer" style="
background-image: url("foo.jpg");
background-repeat: no-repeat;
background-size: cover;
-webkit-background-size: cover;
-mox-background-size: cover;
-o-background-size: cover;">
<div id="theTag">BLAH BLAH BLAH</div>
</div>
You've got the right idea. Looks to me like you just need to change .tag's position:relative to position:absolute, and add position:relative to .container.
You can achieve this with relative position.
But why isn't your code working?
An element with position:relative keeps it's position and also still affects all other following elements. That's the reason why your div won't overlap the image by just using z-index.
You'll still need to position the div element with, for example: top:-28px where the amount would be the height of the element with tag class.
Note: top has no effect on non-positioned elements. It works with absolute, relative and sticky.
If you add top:-28px to the tag element it will only overlap the image if the z-index it has a higher number. This is the importance of z-index in this case.
.container {
width: 200px;
height: 200px;
}
.tag {
position: relative;
z-index: 1;
float: left;
padding: 5px;
color: #FFFFFF;
font-weight: bold;
background-color: #92AD40;
}
img{
position:relative;
z-index:0;
top:-28px;
}
<div class="container">
<div id='tag' class="tag">Featured</div>
<img id='img' src="https://i.stack.imgur.com/rUDax.png">
</div>
If you want to play a bit with this concepts
I added some JS code to toggle between different styles
const tag = document.getElementById('tag')
const img = document.getElementById('img')
const label1 = document.getElementById('label1')
const label2 = document.getElementById('label2')
function togglePosition(){
if(!tag.style.position){
tag.style.position = 'relative'
img.style.position = 'relative'
label1.innerHTML = 'Relative position added'
}
else{
tag.style.position = null
img.style.position = null
label1.innerHTML = 'Add relative position'
}
}
function toggleZindex(){
if(!tag.style.zIndex){
tag.style.zIndex = '1'
img.style.zIndex = '0'
label2.innerHTML = 'z-index (1 and 0) added to elements'
}
else{
tag.style.zIndex = null
img.style.zIndex = null
label2.innerHTML = 'Add z-index to elements'
}
}
.container {
margin-top:20px;
width: 200px;
height: 200px;
}
.tag {
float: left;
padding: 5px;
color: #FFFFFF;
font-weight: bold;
background-color: #92AD40;
}
img{
top:-28px;
}
<input type='checkbox' onclick='togglePosition()'/>
<label id='label1'>Add relative position</label>
<br/>
<input type='checkbox' onclick='toggleZindex()'/>
<label id='label2'>Add z-index to elements</label>
<div class="container">
<div id='tag' class="tag">Featured</div>
<img id='img' src="https://i.stack.imgur.com/rUDax.png">
</div>
you might consider using the Relative and Absolute positining.
`.container {
position: relative;
}
.tag {
position: absolute;
}`
I have tested it there, also if you want it to change its position use this as its margin:
top: 20px;
left: 10px;
It will place it 20 pixels from top and 10 pixels from left; but leave this one if not necessary.

z-index not working with position absolute

I opened the console (chrome\firefox) and ran the following lines:
$("body").append("<div id=\"popupFrame\" style=\"width:100%;height:100%;background-color:black;opacity:0.5;position:absolute;top:0;left:0;z-index:1;\" />");
$("body").append("<div id=\"popupContent\" style=\"width:200px;height:200px;z-index:1000;background-color:white;\" >dasdasdsadasdasdasdasdasd</div>");
The #popupContent should be above all but it's affected by the #popupFrame opacity.
The content is not contained in #popupFrame which makes this very weird.
The goal is to create a firefox-like alert box.
The second div is position: static (the default) so the z-index does not apply to it.
You need to position (set the position property to anything other than static, you probably want relative in this case) anything you want to give a z-index to.
Old question but this answer might help someone.
If you are trying to display the contents of the container outside of the boundaries of the container, make sure that it doesn't have overflow:hidden, otherwise anything outside of it will be cut off.
Opacity changes the context of your z-index, as does the static positioning. Either add opacity to the element that doesn't have it or remove it from the element that does. You'll also have to either make both elements static positioned or specify relative or absolute position. Here's some background on contexts: http://philipwalton.com/articles/what-no-one-told-you-about-z-index/
z-index only applies to elements that have been given an explicit position. Add position:relative to #popupContent and you should be good to go.
I faced this issue a lot when using position: absolute;, I faced this issue by using position: relative in the child element. don't need to change position: absolute to relative, just need to add in the child element look into the beneath two examples:
let toggle = document.getElementById('toggle')
toggle.addEventListener("click", () => {
toggle.classList.toggle('change');
})
.container {
width: 60px;
height: 22px;
background: #333;
border-radius: 20px;
position: relative;
cursor: pointer;
}
.change .slide {
transform: translateX(33px);
}
.slide {
transition: 0.5s;
width: 20px;
height: 20px;
background: #fff;
border-radius: 20px;
margin: 2px 2px;
z-index: 100;
}
.dot {
width: 10px;
height: 16px;
background: red;
position: absolute;
top: 4px;
right: 5px;
z-index: 1;
}
<div class="container" id="toggle">
<div class="slide"></div>
<div class="dot"></div>
</div>
This's how it can be fixed using position relative:
let toggle = document.getElementById('toggle')
toggle.addEventListener("click", () => {
toggle.classList.toggle('change');
})
.container {
width: 60px;
height: 22px;
background: #333;
border-radius: 20px;
position: relative;
cursor: pointer;
}
.change .slide {
transform: translateX(33px);
}
.slide {
transition: 0.5s;
width: 20px;
height: 20px;
background: #fff;
border-radius: 20px;
margin: 2px 2px;
z-index: 100;
// Just add position relative;
position: relative;
}
.dot {
width: 10px;
height: 16px;
background: red;
position: absolute;
top: 4px;
right: 5px;
z-index: 1;
}
<div class="container" id="toggle">
<div class="slide"></div>
<div class="dot"></div>
</div>
Sandbox here
If you're a big 'ol dumdum like me (but know your positioning rules are 100% correct) trying to get something like this:
to look like this:
Your solution may be as simple as ensuring your background is not transparent for the element you want in front of/behind the other element.
I had the the same problem, and i tried to solve it by appending the element with absolute position in a div with a sticky position, my problem was with speeddial (reactjs + material), so i dont know if it will work with all cases.
It may be too late, but it can be preferred as an alternative method. The order of layering for displaying elements in the absolute position depends on the order in which the elements are inserted into the parent element. In other words, instead of using z-index, it is possible to send it to the back by adding it with $(parent).prepend(me), and to bring it to the front by adding it with $(parent).append(me).
function BringToFront(){
$("#parent").append($("#me"));
}
function SendToBack(){
$("#parent").prepend($("#me"));
}
#mySister{
position:absolute;
left:25px;
top:25px;
width:100px;
height:100px;
background-color: red;
}
#me{
position:absolute;
left:50px;
top:50px;
width:100px;
height:100px;
background-color: yellow;
}
#myBrother{
position:absolute;
left:75px;
top:75px;
width:100px;
height:100px;
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="parent">
<div id="mySister"> </div>
<div id="me">Hello! this is me!</div>
<div id="myBrother"> </div>
</div>
<button type="button" onclick="BringToFront()">Bring to front</button>
<button type="button" onclick="SendToBack()">Send to back</button>

Why img without position is like "absolute"?

Check this code :
HTML :
<div style="position: absolute; visibility: visible; width: 172px;">
<img class="inf-image" align="right" src="http://www.ilritaglio.it/wp-content/uploads/2012/02/wee.jpg">
<div class="inf-content">
Hello
</div>
</div>
CSS :
.inf-image
{
position: relative;
cursor: pointer;
margin: 3px 8px 0px 0px;
width:20px;
}
.inf-content {
background-color: #FF0000;
padding: 10px;
width: 150px;
height:50px;
}
looks like the div (which is relative) is under the image (which look absolute). Why? It should push the div over its height.
Floating elements (like an <img align="right">) offset only the content of block elements, but not their backgrounds, so the red background of the div is seen under the image.
Its all about the CSS stacking context. If you give an element another position than static it will be moved to its own stacking context. From a logical point of view the .inf-image { position: relative; } is no longer a child of the parent DIV or a sibling to .inf-content. What you have now is a DIV with another DIV (the red one) inside. The image itself "hovers" in its own context right below the document root (HTML) and is just positioned relative to that element, which preceded it in the source.
Which is shown above which element can be determined by a combination of position and z-index.
https://developer.mozilla.org/en/Understanding_CSS_z-index
http://reference.sitepoint.com/css/stacking
According to your css and html your div is positioned absolute while your image is positioned relative. This is your problem.
<div style="position: relative; visibility: visible; width: 172px;">
<img class="inf-image"src="http://www.ilritaglio.it/wp-content/uploads/2012/02/wee.jpg">
<div class="inf-content">
Hello
</div>
</div>
.inf-image
{
position: absolute;
cursor: pointer;
margin: 3px 8px 0px 0px;
width:20px;
right:0;
}
.inf-content {
background-color: #FF0000;
padding: 10px;
width: 150px;
height:50px;
}