CodePen

HTML

            
              <!-- http://css-tricks.com/well-rounded-compound-shapes-css/  -->

<div class="page-wrap">
  
<div class="red">relative, z: -1</div>
<div class="green">static</div>
<div class="blue">static</div>

<div style="clear:both; margin-bottom: 30px;">
<h2>Z-index: &ldquo;It&rsquo;s a Trap!&rdquo;</span></h2> 

<p>If you don't pay attention to stacking context, you can paint yourself into a <span class="nobr">z-index</span> corner.</p>
  
<p>Red square is given <code>position:relative</code> in order to position the yellow square absolutely. But that raises it in the stacking order over non-positioned elements (static).</p> 
  
<p>So we add <code>z-index:-1</code> to tuck it back behind. Only now it's impossible to raise the yellow square above the green one. It's trapped within the stacking context of its red parent element. (Pseudo-elements are content of their parent element&#8201;&#8212;&#8201;sometimes that's easy to lose track of.)</p>
  <p>Stacking order can be unexpected if you're unaware of its peculiarities: Try declaring opacity on the .green square&#8201;&#8212;&#8201;anything below 1&#8201;&#8212;&#8201;it renders it above non-positioned elements in the stacking order! (If you want to know more, Philip Walton wrote a <a href="http://philipwalton.com/articles/what-no-one-told-you-about-z-index/" target="\_blank">helpful article</a>.)</p>
  <p>So how do we get yellow to overlap green? One solution is to remove the z-index from .red and add position:relative to both .green and .blue.</p>
</div>
<div class="red2">relative</div>
<div class="green2">relative</div>
<div class="blue2">relative</div>

<!--<div style="clear:both"></div>-->

</div>
            
          
!

↑ Insert the most common viewport meta tag

CSS

            
              .red, .green, .blue, .red2, .green2, .blue2 {
  margin-left: -50px;
  float: left;
  height: 180px;
  width: 180px;
  padding: 10px;
  }

.red { 
  /* positioned elements (relative, fixed, absolute) 
     render after (above) non-positioned (static) */
  position: relative;
  /* z-index:-1 tucks red behind green square, 
     but then traps yellow child element in 
     stacking context: it can't overlap green */
  z-index:-1;
  margin-left: 0;
  background: red;
  }

.red:after { 
  /* don't forget pseudo-elements are 
     still the content of their parent */
  content: "absolute";
  display: block;
  position: absolute;
  /* stacking context established by parent (.red) -  
     can't raise this above green square */
  z-index: 10000000;
  top: 25px;
  left: 80px;
  height: 100px;
  width: 100px;
  padding: 10px;
  background: yellow;
  }

.green { 
  /* non-positioned elements render before 
     positioned elements, so red overlaps if 
     given position:relative */
  /*position: relative;*/
  margin-top: 25px;
  background: #0b0;
  /* opacity also affects stacking order! */
  /*opacity: .999999;*/
  }

.blue { 
  /*position: relative;*/
  margin-top: 50px;
  background: blue;
  }

.red2 { 
  position: relative;
  margin-left: 0;
  background: red;
  }

.red2:after { 
  content: "absolute";
  display: block;
  position: absolute;
  z-index: 1;
  top: 25px;
  left: 80px;
  height: 100px;
  width: 100px;
  padding: 10px;
  background: yellow;
}

.green2 { 
  position: relative;
  margin-top: 25px;
  background: #0b0;
  text-align: center;
  /* opacity also affects stacking order! */
  /*opacity: .999999;*/
}

.blue2 { 
  position: relative;
  margin-top: 50px;
  background: blue;
  }

/* PRESENTATIONAL CSS BELOW */

.page-wrap {
  margin: 0 auto;
  width: 80%;
  padding: 20px;
  min-width: 500px;
  max-width: 900px;
  overflow: auto;
  }
            
          
!
? ?
? ?
Must be a valid URL.
+ add another resource
via CSS Lint

JS

            
              
            
          
!
Must be a valid URL.
+ add another resource
via JS Hint
Loading ..................