Vertically Stacking Floated Elements

I have a couple elements on my page which use the float property for positioning purposes. I added two absolutely positioned divs inside a relatively positioned div to try to vertically stack the divs using z-index. Now the float property is being ignored.

Please follow this link and look at the div with the ID of main-content. I successfully stacked the child elements of main-content but the footer now ignores the float property and the width of the child elements of the main-content div no longer works.

How do I position my divs without using float, flex, or flexbox as they are not supported by all browsers?

Hi there oangodd,

does this helpā€¦

<!DOCTYPE HTML>
<html lang="en">
<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">

<title>untitled document</title>

<link rel="stylesheet" href="screen.css" media="screen">

<style media="screen">
body, html{
    margin: 0; 
    padding: 0; 
    background: #000;
    font: 100% / 160% verdana, arial, helvetica, sans-serif;
 }

#container {
    width: 60%;
    margin: auto;
 }

#banner, #footer{
    display: table;
    width: 100%;
    border-spacing: 0.25em;
 }

#banner div, #footer div {
    display: table-cell;
    width: 33.333%;
    padding: 1em;
    background-color: #00f;
 }

#footer div {
    background-color: #ff0;
 }

#main-content div:nth-of-type(1) {
    padding: 1em;
    margin:0  0.25em 0.25em  0.25em;
    background-color: #808080;
 }

#main-content div:nth-of-type(2) {
    padding: 1em;
    margin:0  0.25em 0  0.25em;
    background-color: #fff;
 }
</style>

</head>
<body> 
<div id="container">

 <div id="banner">
  <div></div>
  <div></div>
  <div></div>
 </div>

 <div id="main-content">    
  <div></div>
  <div></div>    
 </div>

 <div id="footer"> 
  <div></div>
  <div></div>
  <div></div>
 </div>

<!-- #containe --></div>

</body>
</html>

coothead

1 Like

Coot gave you a good solution, but I will explain what is probably happening to your original code, for educational purposes ;).

Before I start, I would recommend you donā€™t get in the habit of using IDs as selectors unless they are absolutely necessary. They are will really mess with the specificity of your rules down the line.

Now to your code.

When you position something absolutely, you take it out of the normal ā€˜flowā€™. this means that as far as#parent is concerned #child-1 and #child-2 do not exist ( so itā€™s essentially empty) and itā€™s collapsing.

UNLIKE float you canā€™t clear absolutely positioned elements ( again, they are as if they didnā€™t exist in the normal flow)

Your child elements are overflowing #parent and thus you are getting what you see.

Absolute positioning is NOT really good for laying out content grids ( or much of anything for that matter)

Also ā€¦
Vertical stacking is the default behavior in HTML block elements. You really donā€™t have to do anything to vertically stack divs.

3 Likes

It is supported by all current browsers, the ones that matter, though IE11 has a few issues.

Using absolute positioning for layout is unlikely to result in a responsive layout that is compatible with modern mobile browsers.

2 Likes

Hi, thank you so much for replying and attempting to help. I think that you misunderstood what I meant when I said vertically stacking DIVs. What I meant was that the DIV with the highest Z-Index value will be placed on the top most layer of the stack and the one with the second highest Z-Index will be hidden just one layer below it on the stack and so on.

The only way I know how to stack DIVs like that is to place the DIVs to be stacked in a relatively positioned parent DIV. Then the Divs to be stacked are given absolute positioning.

Cootā€™s suggestion does not work. I am looking for a way to stack DIVs using Z-Index where the DIV with the highest Z-Index value is on top of the stack and the only one visible. All other DIVs are hidden below the DIV with the highest Z-Index value. How do I do that without using relative and absolute positionings?

I think people got the wrong idea when you say ā€œVerticallyā€ as they will think of that as the y axis (up and down the page). But it sounds like you do mean z. So yes you probably will need some positioning for that.

Looking at the fiddle, Iā€™m struggling to visualise that layout you intend on, and why you want to stack the elements.
Perhaps if you could explain why and maybe give a simple sketch of the intended layout an answer could be offered.

1 Like

Here is one possible solutionā€¦

<!DOCTYPE HTML>
<html lang="en">
<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">

<title>untitled document</title>

<link rel="stylesheet" href="screen.css" media="screen">

<style media="screen">
body, html{ 
    background-color: #f0f0f0;
    font: 100% / 160% verdana, arial, helvetica, sans-serif;
 }

#container {
    width: 60%;
    margin: auto;
    border: 1px solid #999;
    background-color: #333;
    box-shadow: 0.4em 0.4em 0.4em rgba( 0, 0, 0, 0.3 );
    overflow-x: hidden;
 }

.banner, 
.footer {
    display: table;
    width: 100%;
    border-spacing: 1px;
 }

.banner div, 
.footer div {
    display: table-cell;
    width: 33.333%;
    padding: 1em;
    background-color: eef;
    background-image: linear-gradient( to bottom, #eef, #889 );
    text-align: center;
 }

.footer div {
    background-color: #ffe;
    background-image: linear-gradient( to bottom, #ffe, #998 );
 }

.main-content {
    display: table;
    width: 200%;
    cursor: pointer;
 }

.main-content div:nth-of-type( 1 ),
.main-content div:nth-of-type( 2 )  {     
    display: table-cell;
    width: 50%;
    padding: 1em;
    border: 1px solid #666;
    background-color: #fff;
    background-image: linear-gradient( to bottom, #fff, #999 );
    box-shadow: inset 0 0 1em rgba( 0, 0, 0, 0.5 );
 }

.main-content div:nth-of-type( 2 ) {
    background-color: #ddd;
    background-image: linear-gradient( to bottom, #ddd, #777 );
 }

.main-content:hover {
    margin-left: -100%;
 }
</style>

</head>
<body> 
<div id="container">

 <div class="banner">
  <div>*</div>
  <div>banner</div>
  <div>*</div>
 </div>

 <div class="main-content">    
  <div>
   <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit.  
    Curabitur sit amet sem sed libero bibendum tempus faucibus       
    quis mi.
   </p>
  </div>
  <div>
   <p>
    Donec vehicula diam non leo efficitur, id euismod odio 
    tincidunt. Vivamus auctor viverra purus vitae lobortis. Sed 
    et libero non diam tempor sagittis. Quisque vel egestas 
    ipsum. Integer sed elit eu orci blandit commodo in in erat.
   </p>
<!-- #main-content --></div>    

 </div>

 <div class="footer"> 
  <div>*</div>
  <div>footer</div>
  <div>*</div>
 </div>

<!-- #container --></div>

</body>
</html>

coothead

Hi, thanks again for your help. Using negative margin to show and hide will work if I only have two DIVs to show and hide. However, on my web page I have several DIVs which I would like to show and hide randomly. This is done by randomly setting the Z-index of each DIV every 5 seconds with Javascript. I think it will be difficult to use negative margin to show and hide DIVs randomly using Javascript.

Hi there oangodd,

here you goā€¦

<!DOCTYPE HTML>
<html lang="en">
<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">

<title>untitled document</title>

<link rel="stylesheet" href="screen.css" media="screen">

<style media="screen">
body, html{ 
    background-color: #f0f0f0;
    font: 100% / 160% verdana, arial, helvetica, sans-serif;
 }

#container {
    width: 60%;
    margin: auto;
    border: 1px solid #999;
    background-color: #333;
    box-shadow: 0.4em 0.4em 0.4em rgba( 0, 0, 0, 0.3 );
    overflow-x: hidden;
 }

.banner, 
.footer {
    display: table;
    width: 100%;
    border-spacing: 1px;
 }

.banner div, 
.footer div {
    display: table-cell;
    width: 33.333%;
    padding: 1em;
    background-color: #eef;
    background-image: linear-gradient( to bottom, #eef, #889 );
    text-align: center;
 }

.footer div {
    background-color: #ffe;
    background-image: linear-gradient( to bottom, #ffe, #998 );
 }

.main-content {
    display: table;
    width: 600%;
    cursor: pointer;
    transition: 0.5s ease-in-out;
 }

.main-content div:nth-of-type( 1 ),
.main-content div:nth-of-type( 2 ),
.main-content div:nth-of-type( 3 ),
.main-content div:nth-of-type( 4 ),
.main-content div:nth-of-type( 5 ),
.main-content div:nth-of-type( 6 )  {     
    display: table-cell;
    width: 16.666%;
    padding: 1em;
    border: 1px solid #666;
    background-color: #fff;
    background-image: linear-gradient( to bottom, #fff, #999 );
    box-shadow: inset 0 0 1em rgba( 0, 0, 0, 0.5 );
 }

</style>

</head>
<body> 
<div id="container">

 <div class="banner">
  <div>*</div>
  <div>banner</div>
  <div>*</div>
 </div>

 <div class="main-content">    
  <div class="mini-content">
   <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit.  
    Curabitur sit amet sem sed libero bibendum tempus faucibus       
    quis mi.
   </p>
  </div>
  <div class="mini-content">
   <p>
    Donec vehicula diam non leo efficitur, id euismod odio 
    tincidunt. Vivamus auctor viverra purus vitae lobortis. Sed 
    et libero non diam tempor sagittis. Quisque vel egestas 
    ipsum. Integer sed elit eu orci blandit commodo in in erat.
   </p>
  </div> 
     <div class="mini-content">
   <p>
    3.
   </p>
  </div>
  <div class="mini-content">
   <p>
    4
   </p>
  </div>
  <div class="mini-content">
   <p>
    5
   </p>
  </div>
  <div class="mini-content">
   <p>
    6
   </p>
  </div>

<!-- #main-content --></div>

 <div class="footer"> 
  <div>*</div>
  <div>footer</div>
  <div>*</div>
 </div>

<!-- #container --></div>
<script>
 ( function( d ) {
   'use strict';

   var delay = 5000, temp = 0;
   var obj = d.querySelector( '.main-content' );
   var num = d.querySelectorAll( '.mini-content' ).length;
   function Moveit() {
      var rnd = Math.floor( Math.random() * num ) * 100; 
         if ( temp === rnd ) {
              moveit();
            }
         else {
              obj.style.marginLeft = - rnd + '%';
              temp = rnd;
            }
     }
   setInterval( Moveit,  delay );

 }( document ) );
</script>
</body>
</html>

coothead

2 Likes

Thank you so much, your solution works great. I was tinkering with another solution which simply shows and hides DIVs using display:block and display:none and it works as well. I will definite use your solution in my own work.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.