Forum Moderators: not2easy

Message Too Old, No Replies

Accordion Style CSS Z-index & relative position.

Advanced CSS positioning layout.

         

wiesel123

4:20 am on Dec 13, 2008 (gmt 0)

10+ Year Member



Hello everyone. I am new to this forum and have joined because I (for the first time) am stuck with my CSS. I believe this is the most advanced problem that I have ever encountered.
I hope that the clever CSS pros on this site can help out. (The answer may benefit many people)
I will try to explain my situation as clearly as possible.
I have a content centred web page using a div titled “wrap” it has a min and max width so when the browser is resized so does my page (to an extent)

Within this expanding and contracting web-page I wish to implement a series of floating images for the banner. There are 5 images that span across the max width of the content area of the website and I wish for them to contract from their positions when the web page is shrunk to the min width. I also want them to Z index over one another. Think if to as an accordion layout (stretch when the page is wide and contract when narrow)
My problem is when I use “position: relative”; - the div containers that I have each image inside overflow the right border of the wrap.
Instead the CSS aligns itself to the right edge of the browser window not the div wrap.

I can send a zip of the images if anyone wishes also.

Thank you in advance for your help

Regards

Brett

CSS


body {
margin:5em;
padding:0;
background-color: #333333;
}
#wrap {
min-width:1000px;
max-width:1200px;
width:auto !important; /*IE6 Hack*/
width:1200px;
margin:0 auto; /*Centre Hack*/
text-align:left; /*Center Hack*/
}
#bnr_middle {
background: #292929;
height:196px;
}
/* BANNER IMAGES */
#bnr_ll {
position: relative;
left: 0;
top: 10px;
z-index:1;
}
#bnr_l {
position: relative;
left: 15%;
top: -170px;
z-index: 2
}
#bnr_m {
position:relative;
left: 35%;
top: -380px;
z-index:3;
}
#bnr_r {
position:relative;
left: 60%;
top: -590px;
z-index:2;
}
#bnr_rr {
position:relative;
left: 80%;
top: -790px;
z-index:1;
}

HTML


<div id="margin">
<div id="wrap">
<div id="bnr_middle">
<div id="bnr_ll">
<img src="images/bnr_ll.png" />
</div><!-- END bnr_-->
<div id="bnr_l">
<img src="images/bnr_l.png" />
</div><!-- END bnr_-->
<div id="bnr_m">
<img src="images/bnr_middle.png" />
</div><!-- END bnr_-->
<div id="bnr_r">
<img src="images/bnr_r.png" />
</div><!-- END bnr_-->
<div id="bnr_rr">
<img src="images/bnr_rr.png" />
</div><!-- END bnr_-->
</div><!-- END bnr Middle-->
</div><!-- END wrap -->
</div><!-- END margin -->

swa66

3:31 pm on Dec 13, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Using absolute positioning instead of relative will make your life a lot easier.

Absolute positioning works in relation to either the viewport or to a (not needed it's a direct) parent that has gained position. The easiest way to make something gain position is to add position:relative to it (but e.g. absolutely positioned elements have position too).

The next "trick" you need in to use margins in combination with percentage positions.
e.g. to center something: "

left: 50%; margin-left: -Xpx;
", where X is half the width of the element. Basically you first move the box to have its left side be in the center and then you move it back half its width.

Basically that's all technique that's needed to make this work.

One more thing: your code suffers from "divititis" (over-use of divs), you can position any element, not just a div.

So I start with some simplified html:


<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>untitled</title>
<style type="text/css">
* {
padding:0;
margin:0;
}
</style>
</head>
<body>
<div id="wrap">
<div id="bnr_middle">
<img id="bnr_ll" src="1.jpg" alt="banner" />
<img id="bnr_l" src="2.jpg" alt="banner" />
<img id="bnr_m" src="3.jpg" alt="banner" />
<img id="bnr_r" src="4.jpg" alt="banner" />
<img id="bnr_rr" src="5.jpg" alt="banner" />
</div><!-- END bnr Middle-->
<p>Ipso lorem</p>
</div><!-- END wrap -->
</body>
</html>

See the far less use of divs ? And it won't hurt one bit.

Now I've no idea how tall nor how wide your images are (and since my test images all differ in size I'm going to nail them down in the CSS)

My test images are jpegs, but pngs should work equally well.

You had some hacks in there that aren't needed with this doctype (and might not work at all as well) , and if we need anything we'll add it in a conditional comment, IE during CSS development only slows you down and gives tons of frustration in my experience.

So the body gets:


body {
margin:5px;
background-color: #333333;
}

and the wrap only needs:


#wrap {
min-width:1000px;
max-width:1200px;
margin:0 auto;
}

We'll use the bnr_middle to have gained position, in order to position the images inside it. WE could use e.g. the wrap just as well, it's a choice to make that's all.


#bnr_middle {
background: #292929;
height:196px;
position:relative; /* to gain position */
}

next our images; they have common settings:

#bnr_ll, #bnr_l, #bnr_m, #bnr_r, #bnr_rr {
position:absolute;
top:10px;
height: 170px ; /* not sure how high your images are */
width: 240px; /*no idea how wide they are (this is 1200/5)*/
}

The easiest are the far left and far right ones:

#bnr_ll {
left: 0;
z-index:1;
}
#bnr_rr {
right: 0;
z-index:1;
}

A bit harder is the center one, but the trick as discussed before to center helps:


#bnr_m {
left: 50%;
margin-left: -120px; /* half it's width */
z-index:3;
}

Note setting both left and right to 0 and settign a width would result in centering in standards compliant browsers, but we can;t use that technique for the next ones.

The two in between there need a variant on the centered one (using one half of the effect):


#bnr_l {
left: 25%;
margin-left: -60px; /* a quarter of it's width */
z-index: 2
}
#bnr_r {
right: 25%;
z-index:2;
margin-right: -60px; /* a quarter of it's width */
}

Combined this yields:


<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>untitled</title>
<style type="text/css">
* {
padding:0;
margin:0;
}
body {
margin:5px;
background-color: #333333;
}
#wrap {
min-width:1000px;
max-width:1200px;
margin:0 auto;
}
#bnr_middle {
background: #292929;
height:196px;
position:relative; /* to gain position */
}
#bnr_ll, #bnr_l, #bnr_m, #bnr_r, #bnr_rr {
position:absolute;
top:10px;
height: 170px ; /* not sure how high your images are */
width: 240px; /*no idea how wide they are (this is 1200/5) */
}
#bnr_ll {
left: 0;
z-index:1;
}
#bnr_l {
left: 25%;
margin-left: -60px; /* a quarter of it's width */
z-index: 2
}
#bnr_m {
left: 50%;
margin-left: -120px; /* half it's width */
z-index:3;
}
#bnr_r {
right: 25%;
z-index:2;
margin-right: -60px; /* a quarter of it's width */
}
#bnr_rr {
right: 0;
z-index:1;
}
</style>
</head>
<body>
<div id="wrap">
<div id="bnr_middle">
<img id="bnr_ll" src="1.jpg" alt="banner" />
<img id="bnr_l" src="2.jpg" alt="banner" />
<img id="bnr_m" src="3.jpg" alt="banner" />
<img id="bnr_r" src="4.jpg" alt="banner" />
<img id="bnr_rr" src="5.jpg" alt="banner" />
</div><!-- END bnr Middle-->
<p>Ipso lorem</p>
</div><!-- END wrap -->
</body>
</html>

Checking it in FF, safari and opera yields no surprises.

Now we'll need to have a look at what IE made of it, as IE isn't without trouble in many cases.

Let's first take IE7, which I expect no problems with this.
IE6 however doesn't support min-width nor max-width, while often you can use width as an alternative to min-width, in this case that doesn't help at all.

So we could add some expressions in a conditional comment or use scripted improvements like IE7.js. The choice is basically yours, but the expressions risk to crash IE, so I'm going to try IE7.js:


<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>untitled</title>
<style type="text/css">
* {
padding:0;
margin:0;
}
body {
margin:5px;
background-color: #333333;
}
#wrap {
min-width:1000px;
max-width:1200px;
margin:0 auto;
}
#bnr_middle {
background: #292929;
height:196px;
position:relative; /* to gain position */
}
#bnr_ll, #bnr_l, #bnr_m, #bnr_r, #bnr_rr {
position:absolute;
top:10px;
height: 170px ; /* not sure how high your images are */
width: 240px; /*no idea how wide they are (this is 1200/5) */
}
#bnr_ll {
left: 0;
z-index:1;
}
#bnr_l {
left: 25%;
margin-left: -60px; /* a quarter of it's width */
z-index: 2
}
#bnr_m {
left: 50%;
margin-left: -120px; /* half it's width */
z-index:3;
}
#bnr_r {
right: 25%;
z-index:2;
margin-right: -60px; /* a quarter of it's width */
}
#bnr_rr {
right: 0;
z-index:1;
}
</style>
<!--[if lt IE 7]>
<script src="http://ie7-js.googlecode.com/svn/version/2.0(beta3)/IE7.js"
type="text/javascript"></script>
<![endif]-->
</head>
<body>
<div id="wrap">
<div id="bnr_middle">
<img id="bnr_ll" src="1.jpg" alt="banner" />
<img id="bnr_l" src="2.jpg" alt="banner" />
<img id="bnr_m" src="3.jpg" alt="banner" />
<img id="bnr_r" src="4.jpg" alt="banner" />
<img id="bnr_rr" src="5.jpg" alt="banner" />
</div><!-- END bnr Middle-->
<p>Ipso lorem</p>
</div><!-- END wrap -->
</body>
</html>

HTH

wiesel123

10:01 pm on Dec 13, 2008 (gmt 0)

10+ Year Member



AMAZING!

swa66, I thank you so much for this. I have also taken note regarding the overuse of div's; I will go through my entire template page and try to remove them. I’m sure there’s a ton of things you would be able to point out to me, so I will keep this thread active. Thank you so much once again!

Brett