relative positioning items with overlapping z-indices - html

I have a curious issue that's proving difficult. I have five divs stacked vertically in a table cell. I'd like the even-numbered divs to fold behind the middle div but in front of the others with z-indexing so that the stack appears as 1-3-5 by default (and all touching, no whitespace), with the even divs' placement and movement not affecting those of the odd-numbered divs. However, if I put the even divs into the middle div, the z-indexing of the evens is completely ignored and they appear on top of the middle guy instead of under it.
I need everything here positioned relative to the containing table cell. Absolute positioning sends any one of these elements travelling to places they shouldn't go. The cell alignment specs are needed as well. Ultimately I want to be able to expand out and contract in the even items with a mouseover (javascript) without moving the odd ones.
<style type="text/css">
.oddStationary {
position:relative;
width:100px;
height:120px;
z-index:1;
border:solid red;
}
.evenMover {
position:relative;
width:100px;
height:120px;
z-index:2;
border:solid yellow;
}
.middleStationary {
position:relative;
height:300px;
width:200px;
z-index:3;
border:solid orange;
background-color:pink;
}
</style>
<table width="600">
<tr>
<td valign="top" align="center">
<div class="oddStationary"></div>
<div class="evenMover"></div>
<div class="middleStationary"></div>
<div class="evenMover"></div>
<div class="oddStationary"></div>
</td>
</tr>
</table>

You need to establish a common reference point for your absolute positioning. By default absolutes go up the HTML tree until they encounter the first "position:relative", which becomes the new origin. If you don't have one defined, the "origin" becomes the BODY tag. You can either set TD as "position:relative" or wrap the whole thing in a DIV that has "position:relative". That's a good start.

set evenMover position to absolute and then put the evenmover tag inside the div tag of those divs where u want it.
<td valign="top" align="center">
<div class="oddStationary">
<div class="evenMover"></div></div>
<div class="middleStationary">
<div class="evenMover"></div></div>
<div class="oddStationary"></div>
</td>

I didn't get your question properly:
while this is the answer to your question whatever I understand from this article:
May be it's helpful:
<style type="text/css">
.oddStationary {
position:relative;
width:100px;
height:120px;
z-index:1;
border:solid red;
}
.evenMover {
position:absolute;
width:100px;
height:120px;
z-index:2;
border:solid yellow;
}
.middleStationary {
position:relative;
height:300px;
width:200px;
z-index:3;
border:solid orange;
background-color:pink;
}
</style>
<table width="600">
<tr>
<td valign="top" align="center">
<div class="oddStationary">
<div class="evenMover"></div></div>
<div class="middleStationary">
<div class="evenMover"></div></div>
<div class="oddStationary"></div>
</td>
</tr>
</table>

Related

How to fit all available height inside element

Here's an example on JSFiddle.
Excerpt of code:
<table style="height:100%">
<tr height="20"><td></td></tr>
<tr>
<td>This gray cell fits all available height of table</td>
</tr>
<tr height="20"><td></td></tr>
</table>
There is a table with three rows. Row in the middle fits all available height of table.
I took this solution from here.
Problem is that impossible to make overflow-y for middle cell. It seems that the middle cell has a min-height property equals height of it's content.
So does it possible to turn on scrolling (overflow-y:auto) somehow and if it doesn't how to implement this layout in divs?
UPD. Thanks. Seems like this is working example: http://jsfiddle.net/haGWe/6/
But it's still interesting how to implement this with divs.
Here it is.
Basically, add a div inside your td element, add a fixed height (I chose 20px) and overflow: auto.
Wrap the contents of middle row in a div and apply the css to the div.
<div class="widget">
<table cellpadding="0" cellspacing="0">
<tr class="widget-header">
<td>20 px above</td>
</tr>
<tr class="widget-content">
<td><div id="myDiv">This gray cell fits all available height of table. What happens when more text is added to this? Woot, scrolls bars.</div></td>
</tr>
<tr class="widget-footer">
<td>20 px below</td>
</tr>
</table>
</div>
.widget{
position:absolute;
min-width:200px;
width:200px;
outline:1px solid gray;
right:50%;
top:20px;
}
.widget > table{
height:100%;
width:100%;
}
.widget-header{
height:20px;
}
.widget-content{
vertical-align:top;
background:gray;
}
.widget-footer{
height:20px;
}
#myDiv
{
height:40px;
overflow-y:scroll;
}
http://jsfiddle.net/2YvG6/

absolute positioning inside a table

I need to position something with absolute positioning inside a td. To get around the fact that a td is undefined when setting it to relative, I use a div set to relative inside my td then inside that div I have an inner div set to absolute. This all works great when I have content filling up the td. When I set the content of the td to display none then the absolute positioning gets all screwed up.
Does anyone know why this would be.
HTML:
<table>
<tr>
<td>
<div class="relative">
<div class='absolute'>
<p>A</p>
</div>
</div>
<div class="slot"></div>
<div class="slot"></div>
</td>
<td>
<div class="relative">
<div class='absolute'>
<p>B</p>
</div>
</div>
<div class="slot hidden"></div>
<div class="slot"></div>
</td>
</tr>
</table>
And CSS:
td{
border:1px solid red;
width:100px;
height:60px;
vertical-align:bottom;
}
.slot{
width:100px;
height:29px;
background-color:#999;
border:1px dashed blue;
}
.relative{
position:relative;
}
.absolute{
position:absolute;
top:5px;
left:5px;
}
.hidden{
display:none;
}
And a live version: http://jsfiddle.net/HgEtQ/
In the fiddle above you can see the first table cell works correctly. The absolutely positioned div is in the correct space. The second one has hidden the top slot and now the absolute positioning is not in the top left corner anymore. If you take out both slots then it really screws up the absolute positioning. I need to positioning it absolute because some of the elements will be shifted depending on the element.
There are a couple things going on here.
You have this:
td {
/*...*/
vertical-align:bottom;
}
That will push the content of the cells to the bottom.
Also, an absolutely positioned element is removed from the normal flow so it won't contribute to its parent's height:
It is removed from the normal flow entirely (it has no impact on later siblings). An absolutely positioned box establishes a new containing block for normal flow children and absolutely (but not fixed) positioned descendants.
In particular, this means that your div.relative elements have a height of zero but they will still have an upper left corner so your absolute positioning offsets are anchored somewhere.
Then you have <div class="slot hidden"> and the hidden removes the <div> from the layout so you effectively have just this:
<div class="relative"></div> <!-- Height zero -->
<div class="slot"></div> <!-- Height 29px -->
That combined with the vertical-align: bottom means that your second div.absolute will be positioned 5px from the top of the div.slot and that is 25px from the bottom of the table cell.
The first cell works fine because the two visible div.slot elements push the div.relative right to the top of the cell, then the div.absolute is positioned 5px from the top of the div.relative and that is 5px from the top of the table cell.
Unfortunately, adding position: relative to a <td> is a bit dodgy as far as browsers go so you'll need some hackery to get your positioning right while keeping vertical-align: bottom. You could re-structure the <td>s like this:
<td>
<div class="relative">
<div class='absolute'>
<p>A</p>
</div>
</div>
<div class="nonsense">
<div class="slot"></div>
<div class="slot"></div>
</div>
</td>
And the CSS like this:
td{
border:1px solid red;
width:100px;
height:60px;
vertical-align: top;
}
.slot{
width:100px;
height:29px;
background-color:#999;
border:1px dashed blue;
}
.relative {
position:relative;
}
.nonsense {
height: 62px; /* td[height] + 2 for the borders */
display: table-cell;
vertical-align: bottom;
}
.absolute{
position:absolute;
top:5px;
left:5px;
}
.hidden{
display:none;
}
Live example: http://jsfiddle.net/ambiguous/aV4nT/
Or you could use visibility: hidden:
hidden
The generated box is invisible (fully transparent, nothing is drawn), but still affects layout. Furthermore, descendants of the element will be visible if they have 'visibility: visible'.
instead of display: none for your .hidden class:
.hidden {
visibility: hidden;
}
This will leave both div.slot elements taking up space and affecting the layout but only the second one will be seen.
Live example: http://jsfiddle.net/ambiguous/RcdNh/

Relative positioning, div stacking issue in ie 7

This is my example code which is not working as expected in IE7 - I think position:relative; is the issue for IE7
.oner {
position:relative;
height:50px;
background:#fff;
border:5px solid #e4e4e4;
height:200px;
margin-top:20px;
}
.onea {
position:absolute;
height:500px;
right:0;
width:200px;
background: #eee;
z-index:999;
}
.onet {
position:absolute;
height:500px;
left:0;
width:200px;
background:red;
z-index:999;
}
HTML:
<div style="height:500px;width:900px;margin:auto;">
<div class="oner">
<div class="onea">IE IE7 this div goes behind the "oner" div below </div>
</div>
<div class="oner">
<div class="onet">My name is Sumit Kumar Ray my email is ..</div>
</div>
</div>
What happens is that the onea div goes behind the following oner div, but in other browsers it overlays it
setting a z-index on a div is actually supposed to create a stacking context, not simply bring the div, it's applied to, above another.. so while I do think IE7 didn't get it quite right, (surprise!)
I think it would be better to make the oner divs the ones that create the start of the stack by setting the z-index on them, and what you want it for the first oner to have a higher z-index than the second
<div style="height:500px;width:900px;margin:auto;">
<div class="oner" style="z-index: 1;">
<div class="onea">IE IE7 this div goes behind the "oner" div below </div>
</div>
<div class="oner">
<div class="onet">My name is Sumit Kumar Ray my email is ..</div>
</div>
</div>
with this there is no need for the Absolutely Positioned children to have a z-index at all, as those divs now take their "z level" from their relatively positioned parent - IE and the stack can be quite confusing!
CSS:
.oner {
position:relative;
height:50px;
background:#fff;
border:5px solid #e4e4e4;
height:200px;
margin-top:20px;
}
.onea {
position:absolute;
height:500px;
right:0;
width:200px;
background: #eee;
}
.onet {
position:absolute;
height:500px;
left:0;
width:200px;
background:red;
}
However it does mean that if you have more than two as in this example you need to set the levels on all the oner divs with the first one being the highest.. (that's why I put the oner style inline in the HTML if you have more you might need some more classes to separate them)
Since both the inner divs have a zindex of 999 the second should overlay the first, although zindex results can be unpredictable across browsers. Really you should set different zindex values to accurately control depth.

CSS Layout Question

I'm having trouble defining the CSS styles necessary in order to achieve the following layout:
Ideally, I'd like to have the left two divs be of width 200px. div#image will always have a height of 100px. However, I would like div#sidebar and div#mainContent to have lower borders which lie on the same horizontal level. Their sizes should be large enough to contain their respective content, which is determined when the page is being served. Hence, the one with more content will cause the other div to extend down to the same distance.
The problem is that with absolute positioning, the div#sidebar and div#mainContent elements don't seem to acknowledge the flow of their child elements. Perhaps I don't fully understand absolute positioning. Also, it seems like bad form to use Javascript in order to set the inline style of elements on the page. Is there a way of accomplishing this solely with CSS?
I've also tried floating the div#image and div#sidebar, and setting a margin-left property on div#mainContent, but wasn't able to get it to work...
Any help will be much appreciated!
Andrew
demo: http://jsfiddle.net/TRa35/
html
<div id="wrapper">
<div id="div-image">div image</div>
<div id="div-maincontent">
<div id="div-sidebar">
div sidebar
</div>
div maincontent
<button>click to add content</button>
<br />
<span></span>
</div>
</div>
css
html, body {
margin:0;
padding:0;
}
#wrapper {
position:relative;
}
#div-image {
position:absolute;
left:0;
top:0;
width:200px;
height:100px;
background-color:#cef;
}
#div-sidebar {
position:absolute;
left:-200px;
top:100px;
bottom:0;
width:200px;
background-color:#efc;
}
#div-maincontent {
position:absolute;
left:200px;
right:0;
top:0;
background-color:#fce;
min-height:300px;
}
This almost solves the problem. In fact, to be more precise, it does solve the problem in Google Chrome and Firefox, but IE 9 seems to have problems recognizing the height of cells and/or rows. I can't really mark it as an answer because of this, but I'm just posting it in case anyone can use something from it. It uses an html table element.
CSS:
#mainContentCell
{
background-color: Blue;
}
#imageCell
{
width: 200px;
height: 100px;
background-color: Yellow;
}
#sidebarCell
{
background-color: Red;
}
HTML:
<table id="layoutTable" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td id="imageCell">
Image
</td>
<td id="mainContentCell" rowspan="2">
Main Content
</td>
</tr>
<tr>
<td id="sidebarCell">
Sidebar
</td>
</tr>
</table>
Also, if anyone can make this work in IE 9, I'll gladly mark their response as the answer.
Note: This has been abandoned as "unsolvable", a reasonable answer is given below, but the original problem question remains without a definite solution.
JS Fiddle: http://jsfiddle.net/steve/gHrce/
Does almost everything, may help put you on the right track.
CSS:
#img {
background:green;
float:left;
height:100px;
width:200px;
}
#sidebar {
background:red;
clear:both;
float:left;
width:200px;
}
#mainContent {
background:yellow;
margin-left:200px;
}
HTML:
<div id='img'>
IMG
</div>
<div id='sidebar'>
SIDEBAR
<br />
<br />
<br />
</div>
<div id='mainContent'>
MAIN CONTENT
<br style='clear:both' />
</div>
That extra <br /> at the bottom forces the height of the main content to whatever the sidebar height is.
The <br /> tags in the sidebar are just to provide some extra height for demonstration purposes.
Of course, you can add Javascript pretty easily to expand the sidebar's height, but it smells strongly of hack:
if($('mainContent').offsetHeight > $('sidebar').offsetHeight + 100) {
$('sidebar').style.height = $('mainContent').offsetHeight - 100 + 'px';
}
#Andrew
for my suggestion, you should use 960 grid system CSS. pls check on this link http://960.gs/
I think you may more easier to develop and maintain.
Whew! After searching tons of articles. I hope this could help you.
<style type="text/css">
#wrapper{
background:blue;
position:relative;
min-height:400px;
}
#img{
background:green;
position:absolute;
left:0;
height:100px;
width:200px;
}
#some-panel{
background:orange;
position:absolute;
width:200px;
top:100px;
left:0;
bottom:0;
}
#main-content{
background:yellow;
margin-left:200px;
}
</style>
<div id="wrapper">
<div id="img">img img</div>
<div id="some-panel">some panel</div>
<div id="main-content">
main content main
</div>
</div>

CSS Center Element in 3 Column Layout

So I have a 3-column layout on my webpage, but I can't get the things in the middle column to be centered. The columns on the left and right are of fixed width, so I created a container for the middle column and set its borders to equal the size of the left and right columns. Then, I used the margin:auto property on the div tag inside the middle container that has everything that I want in the middle column. If possible, I want this to work on all browser window sizes. This is my CSS:
#top
{
width:100%;
background-color:#FF0000;
height:30px;
overflow: auto;
width: 100%
}
#right
{
float:right;
width:100px;
background-color:#CCC;
height:100%;
}
#middleCont
{
margin-left:150px;
margin-right:100px;
}
#middle
{
margin:auto;
text-align:left;
}
#left
{
float:left;
width:150px;
height:100%;
}
And since I can't post html without the browser rendering it for some reason, I uploaded the relevant code in a text file: http://www.mediafire.com/?a89kr1bb4uwb4cf
Thanks in advance for the help.
Yes, for one, under #middle, you said text-align: left rather than text-align: center. The instant I changed this, it worked fine.
I inserted different types of tags into the document, including p, div, blockquote, a list, a table, and an image. The only problem I noticed is that the table did not center. Looking at a number of articles, I found that you had already implemented the recommended way of centering a table in CSS. I think that maybe, the only solution to this problem is either to make a table using the center tag or create a new block of text in your CSS file.
You can do what you like, but the recommended way is this:
#center {
margin: auto;
}
Then make a new table with #center as its ID.
<table id="center">
...
</table>
If you choose to use the center tag, you implement it like this:
<center>
<table>
...
</table>
</center>
Hope I helped a little. Good luck.
I do it this way. Working even for internet explorer 6.
<table border="0" cellspacing="0" cellpadding="0" width="100%" style="width:100.0%;">
<tr>
<td width="50%" valign="top" style="width:50.0%;">
</td>
<td valign="top" style="width:900px;">
<div style="width:900px; border:1px solid white;"></div>
</td>
<td width="50%" valign="top" style="width:50.0%;">
</td>
</tr>
</table>
I suppose you can change the text-align:left to text-align:center for the selector #middle
If you want to use the method margin:0 auto for the #middle (and not margin:auto as you have it) then you have to set a fixed width, something like width:400px; or width:20%;.
If you want a fixed width center column then
#middle
/*this will keep the column width constant wile letting the space on either side expand*/
{
margin:auto;
text-align:left;
width: 600px; /* what ever width you want */
}
or specify fixed margins
#middle
/*this wil keep the space on either side constant wile letting the column expand*/
{
margin-left: 150px; /*to center column just keep the left and right margins equal*/
margin-right: 150px;
text-align:left;
}
I hope that answers your question.
P.S. It would have helped if you had posted the html too.
I am not sure if I follow exactly what you are trying to do - but what about if you use percentages rather than pixels for the width of all four divs?
#top
{
width:100%;
background-color:#FF0000;
height:30px;
overflow: auto;
width: 100%
}
#right
{
float:right;
width:25%;
background-color:#CCC;
height:100%;
}
#middleCont
{
margin-left:36%;
margin-right:26%;
}
#middle
{
margin:auto;
text-align:left;
}
#left
{
float:left;
width:35%;
height:100%;
background-color:#CCC;
}