Any weird rules about z-index I should know about? - css

Sorry I can't post complete code, I'm working on proprietary stuff. Basically I have a problem where a DIV that has z-index 6 is being blocked by an overlay DIV that has a z-index of 5. Is there ANY scenario that would make this happen? I'm wracking my brain trying to figure out why this is happening. It just doesn't make any sense. Anything having to do with nesting DIVs, or CSS position maybe?
I apologize for the vagueness. I tried to recreate in JSFiddle but it works as expected, unfortunately. Only the actual code is wonky.
Structure:
<div id="window">
<div id="wall">
<div class="box" /><div class="box" /> .... many boxes
</div>
</div>
<div id="overlay" />
CSS:
#window {
position: relative;
width: 960px;
height: 700px;
overflow: hidden;
background: #666;
}
#wall {
position: relative;
width: 1640px;
height: 1600px;
-webkit-perspective: 2000;
}
#overlay {
position: absolute;
z-index: 5;
background: #000;
}
.box {
left: 0px;
top: 0px;
position: absolute;
width: 228px;
height: 228px;
color: #fff;
font-family: Helvetica, Arial, sans-serif;
font-weight: bold;
font-size: 0.8em;
-webkit-transform-style: preserve-3d;
z-index: 4;
cursor: pointer;
}
Overlay dimensions are set via jQuery upon a certain event:
$('<div id="overlay"></div>').css({
'left': $('#window').position().left + 'px',
'top': $('#window').position().top + 'px',
'width': $('#window').width() + 'px',
'height': $('#window').height() + 'px',
'opacity': 0.8
}).appendTo('body');
Even though one of the boxes has a z-index of 6, and the overlay is 5, the overlay is still over said box.
The overlay is supposed to go over the window, but let one of its boxes through.
Why the heck does this JSFiddle work but my actual code does not?! http://jsfiddle.net/csaltyj/2gzTc/

z-index only works on elements with position: relative,absolute, or fixed. That seems to trip many people up.
In addition, a child can never be below its parent. This example, also on Jsfiddle illustrates it.
Based on the example you added it's clear the trouble you're having:
z-index is only relative to its parent, which in most cases is the document itself. If the z-index of one sibling is lower than another, nothing you change about first sibling's children can move it above its parents sibling. Read more about stacking context if you're interested.
Here is a visual:
Crossed out in red is what you want to do, and it is not possible with CSS (considering those small boxes are children of the bigger box, with markup which might look like this:
<div class="one">
</div>
<div class="two">
<div> I can never be above "one", if my parent "two" isn't. </div>
</div>
A solution would be to move the "overlay" inside the wall, or better yet use a pseudo element (which is rendered as a child of the element it is applied to), because the overlay sounds like it something presentational, and thus should remain in the domain of CSS if an overlay div would add no semantic meaning.

Related

Why does an absolutely positioned child expand container height and how to prevent this?

Suppose you have a parent div that contains several normal children and one absolute child.
I've read practically everywhere that a child with position: absolute will not influence parent's height, since it is out of the normal flow. However in my case, an absolute element expands the parent, and I can't understand why.
(I tried reading the spec but I'm really lost.)
HTML
<div class="container">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="outsider"></div>
</div>
CSS
.container {
overflow: hidden;
}
.block, .outsider {
width: 100%;
height: 1000px;
}
.block {
background: red;
}
.outsider {
position: absolute;
left: 0;
top: 3000px;
background: green;
opacity: 0.5;
}
Why does the browser let me scroll past the element's supposed height? It seems consistent in Chrome, Safari and Firefox so I presume it's part of the spec.
How do I prevent this behavior? I'd like absolutely positioned element to be cropped if it doesn't fit into the container height “dictated” by “normal” children.
See it live.
You are missing a position on your parent container. Add
.container{
position: relative;
}
The absolutely positioned element will go back up the DOM to find the nearest positioned parent, in this case you don't have one explicitly defined, so it's going back up to <body>

<span> changing layout of website even though position is absolute?

Here is my code.
The HTML:
<div class=column1of4>
<a rel="Appendix" href="images/watermarks/watermark_pic1.jpg" title="Bottle in the mirror"><img src="images/250-width/pic1.jpg" alt="" width="250px" height="250px" id="Bottleinthemirrorpic"></a>
<span id="Bottleinthemirror" class="spanlink"><p>Bottle in the mirror<p></span>
</div>
<div class=column1of4>
<a rel="Appendix" href="images/watermarks/watermark_pic9.jpg" title="The empty glass"><img src="images/250-width/pic9.jpg" alt="" width="250px" height="250px"></a>
</div>
<div class=column1of4>
<a rel="Appendix" href="images/watermarks/watermark_pic10.jpg" title="The last drop"><img src="images/250-width/pic10.jpg" alt="" width="250px" height="250px"></a>
</div>
The CSS:
#Bottleinthemirror {
width: 250px;
height: 90px;
position: absolute;
background-color: rgba(0,0,0,.55);
margin-top: 10px;
color: white;
line-height: 20px;
font-size: 12px;
}
.column1of4 {
margin: 50px;
float: left;
}
The Javascript:
$('#Bottleinthemirror').hide();
$('#Bottleinthemirrorpic, #Bottleinthemirror').hover(function(){
//in
$('#Bottleinthemirror').show();
},function(){
//out
$('#Bottleinthemirror').hide();
});
Basically, I have three pictures, two of them beside each other and the third one is below the first one. Which I hover over the first picture, I want the #bottleinthemirror span to appear, which it does. The problem is, even when the span is hidden, it still rearranges the layout of the website and moves the picture below it to another place even though it's position is set to absolute. Any idea why? When I remove the span, the website layout is normal. It changes when I put in the span even though the spans position is absolute.
Probably the problem is that span can not contain p, and in your code there are technically 2 p elements in the span (both p tags are opening). When browsers fix this incorrect markup, part of the last p may appear outside the span. If there is a need to have p inside .spanlink, it's better to use div instead of span. But is the p really necessary here?
Add
display: block;
to
#Bottleinthemirror
I set this up in a jsfiddle: http://jsfiddle.net/r2XG2/1/ and it appears to be working for me in Chrome. What browser are you in? I would try the following if it's still not working for you:
Set z-index: 100 to see if that will force it to appear over the other elements. You could also try setting the top or left values in css, that may also force it to appear in the correct place. Adding display: block; couldn't hurt either.
Edit: Updated fiddle with latest update from asker it also appears that IE won't load jsfiddle. I added position: relative to the parent div to see if that helps.
#Bottleinthemirror {
width: 250px;
height: 90px;
position: absolute;
background-color: rgba(0,0,0,.55);
margin-top: 10px;
color: white;
line-height: 20px;
font-size: 12px;
z-index: 100;
display: block;
}
.column1of4 {
margin: 50px;
float: left;
position: relative;
}

z-index between Children and Parents

I'm having problems working out the z-index order for an application we're working on, i have two root parents, a nav bar and a map, and one child, the map tooltip. The navbar should be visible above the map, so it has a higher z-index, but the problems is to make the tooltip in the map container to be displayed over the sidebar as well, a bit hard to explain, so you can visualize the case on http://jsbin.com/afakak/2/edit#javascript,html,live :
<div id="nav-bar">
The nav bar
</div>
<div id="map-container">
This is the map container
<div id="tooltip">
This is the Tooltip
</div>
</div>
Thanks for any help.
If #map-container is positioned (i.e. not static), this is not possible, because of the way z-index is compared:
body (or any other positioned parent element) is the reference for both #map-container and #nav-bar. Any z-index you give them is calculated in respect to the parent element. So the one of the 2 elements with the higher z-index will be rendered above the other one and all its child elements. Z-index of #tooltip will only be compared with other children of #map-container.
You could do as Nacho said and statically position #map-container. You can simulate fixed positioning via Javascript, if you like.
If you cannot do that, you need to change your markup, so that #nav-bar and #tooltip have a common positioned parent element. Either move #nav-bar inside #map-container, or #tooltip out of it.
Below solution should work but I don't know if you have a requirement like keeping nav-bar outside map-container. If so I don't think that there is a workaround for that.
CSS:
#tooltip-helper{
position:relative;
/*below properties are to demonstrate the helper*/
width:10px;
height:10px;
background-color:green;
top:200px;
left:200px;
}
#tooltip
{
position:absolute;
top:10px;/*this is just to make sure helper is visible*/
left:-100px;/*this is to center the tooltip*/
width: 200px;
height: 200px;
background-color: yellow;
color: black;
padding: 10px;
z-index: 15;
}
HTML:
<div id="map-container">
<div id="nav-bar">
The nav bar
</div>
This is the map container
<div id="tooltip-helper">
<div id="tooltip">This is the Tooltip</div>
</div>
</div>
You have to absolutely position nav-bar and tooltip (otherwise z-index won't be taken in account), and maintain map-container static positioned
#map-container{
...
position: static;
...
}
#nav-bar{
...
position: absolute;
}
#tooltip{
...
position: absolute
}
I think the only way you can do this with a position: fixed on the #map-container is to restructure your tool tips to display outside the #map-container. So on click of the icon "inside" the map container, the tool-tip itself is displayed above both (with a proper z-index set).
<div id="nav-bar">
The nav bar
</div>
<div id="map-container">
This is the map container
</div>
<div id="tooltip">
This is the Tooltip
</div>
After going through, your codes, i noticed this.
#tooltip{
background-color: yellow;
width: 200px;
height: 200px;
color: black;
padding: 10px;
z-index: 15;
}
Your #tooltip has a z-index, but it's not positioned. Z-index property will only work if it's has one of the position property value. And considering you want the tooltip to stand out, you should use the absolute position value like this.
#tooltip{
position: absolute;
background-color: yellow;
width: 200px;
height: 200px;
color: black;
padding: 10px;
z-index: 15;
}
HTML
<div id="map-container">
<div id="nav-bar">
The nav bar
</div>
This is the map container
<div id="tooltip">
This is the Tooltip
</div>
</div>
This keeps the #tooltip on top....
For future readers with similar problems -
If your conflicting child items are position: fixed, consider setting the height of the parent containers to 0px, and then shifting any parent background display settings onto a mutual grandparent of the conflicting children.
This solved my analogous delimma.
If, in the real page, the tooltip has to be shown only on hovering the map container, you could just change dynamically its z-index like so:
#map-container:hover
{
z-index: 16
}
Otherwise you need to change the position of the tooltip so that the nav-bar doesn't overlap it.

Firefox (multiple versions) aligns div to the right

Given the following CSS:
body {
font-family: Corbel, Calibri, Verdana, Helvetica, sans-serif;
font-size: 9pt;'
}
.heb {
font-family: Bwhebb;
}
.heb, .eng {
font-size: 25pt;
cursor: pointer;
display:none;
}
.slideshow, .cardface, .card {
width: 100%;
height: 15%;
text-align: center;
position: absolute;
}
and the following HTML
<div class="card" id="wordID">
<span class='heb cardface'>
some word
</span>
<br />
<div class='eng cardface'>
some translation
<br />
<a href='#' class='right' >correct</a> |
<a href='#' class='wrong' >incorrect</a>
</div>
</div>
I get two different results on Chrome and Firefox. Chrome centers everything on the page while Firefox places the span .heb .cardface WAAAAAYYYYYYYYYYYYYYY to the right.
I am pretty sure I'm doing something wrong, could you help me figure it out?
If I remove position: absolute; from your CSS, in the last line, having .slideshow, .cardface, .card {width: 100%; height: 15%; text-align: center;}, it is all centered.
Is that what you're after?
You have an absolutely positioned div with an auto left offset. That means its left edge should be placed where it would go if its position were static.... and since the parent element has centered text, that means at the center of the parent element. Chrome gets this right if you have any text in the parent element, but wrong if the parent element has only positioned kids. See the testcases at https://bugzilla.mozilla.org/show_bug.cgi?id=671491
Oh, and the upshot is that left: 0 should do what you want, I would assume.
The problem in firefox is that <div class="card" id="wordID"> is in absolute position, and <span class='heb cardface'>some word</span> is also in absolute position.
You can either remove the absolute positionning, according to #Nightfirecat suggestion.
Or you can remove the absolute positionning for either .card or .cardface. It's better if you remove it from .cardface, since then, .card content will be what's inside .cardface (Remember : Positionning something in absolute moves it out of it context! Aka, the parent element won't use it to define it's size/will act quirky.)

How to display a number (generated dynamically) into a square using CSS

I'm new to CSS. I need to display a number (generated dynamically through ASP.NET MVC action method) on to a Square (normal image , whose face needs to be replaced with the dynamic number ).
Can someone assist me in doing this . I am sure it will just take a minute for some one who knows CSS.
Thanks,
Vijay
The easiest way would be to create a <div> that uses your image as a background-image property. Then it would just be a matter of writing the number into that div:
HTML
<div class="square">
123
</div>
CSS
.square {
/* following are width and height of your background image */
width: 100px;
height: 100px;
background: url(yourimg.png) no-repeat 0 0;
}
If you have to use an <img> tag, it's a little trickier, but still possible:
HTML
<div class="square">
<span>123</span>
<img src="yourimg.png" />
</div>
CSS
.square {
/* following are width and height of your background image */
width: 100px;
height: 100px;
position: relative;
}
.square img {
position: relative;
z-index: 1;
}
.square span {
position: absolute;
z-index: 2;
/* Use to position your number */
top: 10px;
left: 10px;
}
The above works by creating a stack of elements, with the <img> on the bottom (on account of lower z-index) and the number positioned absolutely above it. This works because the number's parent (<div class="square">) has position relative so it becomes the coordinate system.
using CSS background and putting an image behind the number?
You should be able to this using a coloured div and text (the number) within the div. You might need to adjust the CSS a bit to make a perfect square though.
<div style="border: 1px solid black; background-color: red; color: white; font-size: 18px; padding: 15px;">
<%: Model.RandomNumber %>
</div>

Resources