skip to Main Content

I need help understanding how z-index of elements is affected by nesting or not nesting elements inside eachother. I have managed to get my code working (which should have a clickable image (image which redirects user to some other page/section) which when hovered should have an overlay displayed over the image.

However when i change the html code as such the overlay is displayed differntly:(moved i move the closing tag from line 2 to line 4 the overlay isnt displayed correctly anymore and i dont understand why)

original: (part of working code, overlay displays on top of image as expected)

<div class="image">
    <a href="www.google.com" class="image__link"></a>
         <img class="image__img" src="https://www.slntechnologies.com/wp-content/uploads/2017/08/ef3-placeholder-image.jpg" />
     

after moving closing Anchor tag: (not working properly, image displays on top of overlay and overlay is not visible)

 <div class="image">
     <a href="www.google.com" class="image__link">
         <img class="image__img" src="https://www.slntechnologies.com/wp-content/uploads/2017/08/ef3-placeholder-image.jpg" />
     </a>

I did not change the CSS, did not change the z-index of the elements, only changed the location of closing anchor tag. The overlay opacity is still changed when user hovers (as can be seen when changing opacity of .image__img class to <1). But for some reason the overlay isn’t displayed above the image anymore..

Please can someone explain why this is happening?

Thank you!

Codepen 1: (overlay displays in front of image/is visible (desired result))
https://codepen.io/domipomi123/pen/ExemymY
Codepen 2: (overlay displays behind image)(changed image opacity to 0.5 to make overlay visible even when behind image)
https://codepen.io/domipomi123/pen/eYLWpLO

2

Answers


  1. The issue is that the ruleset shown below moves the link (and it’s children) above the overlay which only has a z-index of 99. And, as you noticed, if you don’t have the anchor on top, it doesn’t register the hover because the mouse event is captured by the overlay on top.

    #imageTextGrid a.image__link {
      position: absolute;
      height: 100%;
      width: 100%;
      z-index: 100; /* <-- higher than the overlay */
    }
    

    To fix this, I removed the absolute positioning on the anchor and I added pointer-events: none; to the overlay so that it wouldn’t interfere with registering when you hover on the anchor tag. As a general rule, try and keep positioned elements to a minimum. Here, the only thing you need to position is the overlay and the "grid" element that is set to relative.

    Another best practice is to not use ids in CSS to keep CSS specificity to a minimum level, so I removed the unnecessary ids and stuck to your BEM conventions.

    /* mini-reset */
    
    * {
      box-sizing: border-box;
    }
    
    html, body {
      height: 100%;
      margin: 0;
    }
    
    /* Component styles */
    
    .grid {
      padding-top: 80px;
      max-width:95vw;
      display:grid;
      grid-template-columns: repeat(auto-fit, minmax(750px, 1fr));
      gap: 40px;  
      opacity: 0;
      position: relative;
      left: -80%;
      margin: auto;
      animation: slide-in 1s forwards;
      transition: opacity 1s;
    }
    
    .image {
      width: 750px;
      height: 500px;
      position: relative;
    }
    
    .image__img {
      display: block;
      height: 100%;
      width: 100%;
      object-fit: cover;
    }
    
    .image__overlay {
      position: absolute;
      inset: 0;
      background-color: rgba(41, 139, 16, 0.651);
      color: black;
      opacity: 0;
      pointer-events: none;
      transition: opacity .25s ease-in-out;
    }
    
    .image__link:hover + .image__overlay{
      opacity: 1;
    }
    
    .image__textContainer {
      display:flex;
      flex-direction: column;
      position: absolute;
      gap: 8px;
      bottom: 30px;
      left: 30px;
    }
    
    .image__title{
      font-size: 2em;
      font-weight: bold;
    }
    
    @keyframes slide-in {
      to {
        left: 50%;
        transform: translateX(-50%);
        opacity:1;
      }
    }
    <div id="imageTextGrid" class="grid">
      <div class="image">
        <a href="www.google.com" class="image__link">
          <img class="image__img" src="https://www.slntechnologies.com/wp-content/uploads/2017/08/ef3-placeholder-image.jpg" />
        </a>
        <div class="image__overlay">
          <div class="image__textContainer">
            <div class="image__title">Tiny-House in tuin</div>
            <p class="image__description">Gastenverblijf in Zweedse Stijl</p>
          </div>
        </div>
      </div>
    </div>
    Login or Signup to reply.
  2. Here is a quick example of a Call To Action (CTA) layout. I threw together with some ugly color and borders just to show where things are.

    • I have multiple sections and a footer; all optional.
    • I made multiple sections; some use the mouse hover
    • Notice how the CTA footer uses only the two right columns.
    • I used classes only not an ID so you can use multiple with one set of CSS.
    • Also there is no challenges with "position" only the z-index for the hover effect.
    • No dealing with challenging positioning; just say where you want it. – Try with "full screen" here and then set the browser to use a mobile view option to see how it reacts.
    • A production level version of this should have less CSS than this
    body {
      padding: 0;
      margin: 0;
      font-size: 16px;
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(40%, 45vw));
      column-gap: 1rem;
      row-gap: 2rem;
    }
    
    .cta-card-wrapper {
      box-sizing: border-box;
      border: 2px dashed blue;
      background-color: #0000ff08;
      padding: 1rem;
    }
    
    .cta-container {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      grid-template-rows: repeat(2, 1fr) auto;
      grid-template-areas: "a b c" "d e f" "h i j" ". ctafooter ctafooter";
      border: 2px dashed cyan;
      grid-gap: 1rem;
    }
    
    .cta-image-container {
      /* image covers entire grid */
      grid-row-start: a;
      grid-row-end: f;
      grid-column-start: a;
      grid-column-end: f;
    }
    
    .cta-text-overlay {
      /* text over last two grid blocks */
      /* could be h and j instead for last one */
      grid-row-start: d;
      grid-row-end: j;
      grid-column-start: d;
      grid-column-end: j;
    }
    
    .cta-header-container {
      grid-row-start: a;
      grid-row-end: a;
      grid-column-start: a;
      grid-column-end: c;
    }
    
    .cta-body {
      grid-row-start: d;
      grid-row-end: f;
      grid-column-start: d;
      grid-column-end: f;
      display: flex;
      flex-direction: column;
    }
    
    .cta-text-overlay~.cta-body {
      grid-row-start: h;
      grid-row-end: j;
      grid-column-start: h;
      grid-column-end: j;
      display: flex;
      flex-direction: column;
    }
    
    .cta-footer {
      grid-row-start: ctafooter;
      grid-row-end: ctafooter;
      grid-column-start: ctafooter;
      grid-column-end: ctafooter;
      display: grid;
      place-items: center;
      border-top: 1px solid red;
    }
    
    .cta-image-container {
      border: 0.25rem outset lime;
      z-index: 3;
    }
    
    
    /* just styling from here */
    
    .cta-header-container {
      border: 0.5rem inset lime;
    }
    
    .cta-text-overlay {
      color: black;
      background-color: rgba(41, 139, 16, 0.651);
      opacity: 0.2;
      border: 2px dashed green;
      padding: 0.5rem;
    }
    
    .cta-body {
      color: blue;
      background-color: #298b1044;
      border: 2px dashed purple;
      padding: 0.5rem;
    }
    
    .cta-image-container:hover+.cta-text-overlay {
      transition: 1s;
      opacity: 1;
    }
    
    .cta-image-container:hover {
      opacity: 0;
    }
    
    .cta-image-link {
      border: 4px dotted magenta;
      padding: 0.25rem;
      background-color: #88008811;
      display: grid;
      place-items: center;
    }
    
    .cta-image {
      box-sizing: border-box;
      height: 95%;
      width: 95%;
      opacity: 0.5;
      border: solid blue 4px;
      background-color: #FFFF3388;
      padding: 0.5rem;
    }
    
    .cta-overlay-text-container {
      display: flex;
      flex-direction: column;
      column-gap: 0.5em;
    }
    
    .cta-overlay-text-container>* {
      border: solid 2px orange;
    }
    
    .cta-body-text-container {
      display: flex;
      flex-direction: column;
      column-gap: 1em;
    }
    
    .cta-overlay-title {
      font-size: 2em;
      font-weight: bold;
    }
    
    .cta-overlay-description {
      font-size: 1.5em;
    }
    
    .cta-body-title {
      font-size: 2em;
      font-weight: bold;
    }
    
    .cta-body-description {
      font-size: 1.5em;
    }
    
    .cta-button {
      background-color: #0000FF44;
      border-radius: 0.5rem;
      padding: 0.5rem;
      border: 1px solid;
      border-color: #0000ff88;
      color: #FF8C00;
    }
    <div class="cta-card-wrapper">
      <div class="cta-container" name="overview">
        <div class="cta-image-container">
          <a href="www.google.com" class="cta-image-link">
            <img class="cta-image" src="https://www.slntechnologies.com/wp-content/uploads/2017/08/ef3-placeholder-image.jpg" />
          </a>
        </div>
        <div class="cta-text-overlay">
          <div class="cta-overlay-text-container">
            <div class="cta-overlay-title">Tiny-House in tuin</div>
            <p class="cta-overlay-description">Gastenverblijf in Zweedse Stijl</p>
          </div>
        </div>
      </div>
    </div>
    <div class="cta-card-wrapper">
      <div class="cta-container" name="overview">
        <div class="cta-image-container">
          <a href="www.google.com" class="cta-image-link">
            <img class="cta-image" src="https://www.slntechnologies.com/wp-content/uploads/2017/08/ef3-placeholder-image.jpg" />
          </a>
        </div>
        <div class="cta-text-overlay">
          <div class="cta-overlay-text-container">
            <div class="cta-overlay-title">It's huge!</div>
            <p class="cta-overlay-description">Castle Green</p>
          </div>
        </div>
        <div class="cta-body">
          <div class="cta-body-text-container">
            <div class="cta-body-title">CTA is for marketing</div>
            <div class="cta-body-description">A CTA is Call To Action HTML block</div>
          </div>
          <button class="cta-button" type="button">I am a CTA button</button>
        </div>
        <div class="cta-footer"><span>Large Castle footer</span></div>
      </div>
    </div>
    
    <div class="cta-card-wrapper">
      <div class="cta-container" name="overview">
        <div class="cta-header-container">
          <a href="www.google.com" class="cta-image-link">
            <img class="cta-image" src="https://www.slntechnologies.com/wp-content/uploads/2017/08/ef3-placeholder-image.jpg" />
          </a>
        </div>
        <div class="cta-body">
          <div class="cta-body-text-container">
            <div class="cta-body-title">CTA is for Boats!</div>
            <div class="cta-body-description">We already said this; let's talk about boats now!</div>
          </div>
          <button class="cta-button" type="button">Get a new boat!</button>
        </div>
        <div class="cta-footer"><span>Free boats footer</span></div>
      </div>
    </div>
    
    <div class="cta-card-wrapper">
      <div class="cta-container" name="overview">
        <div class="cta-header-container">
          <a href="www.google.com" class="cta-image-link">
            <img class="cta-image" src="https://www.slntechnologies.com/wp-content/uploads/2017/08/ef3-placeholder-image.jpg" />
          </a>
        </div>
        <div class="cta-body">
          <div class="cta-body-text-container">
            <div class="cta-body-title">Call to Action!</div>
            <div class="cta-body-description">Go Hiking</div>
          </div>
          <button class="cta-button" type="button">Go get some BOOTS!</button>
        </div>
        <div class="cta-footer"><span>Waling boots</span></div>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search