skip to Main Content

I’m trying to create this transition like in the video. On hover I want the text to slide in from right. I tried to create it but its not sliding through the icons instead behind the icons.

enter image description here

Here is my code. Please any help would be appreciated.

body {
  margin: 3em;
}

.utility-nav-links {
  display: flex;
  justify-content: end;
}

.utility-nav-link {
  margin-left: 18px;
  position: relative;
  transform: translateX(0);
  transition: transform 0.3s ease;
}

.utility-nav-link span {
  position: absolute;
  left: 100%;
  white-space: nowrap;
  opacity: 0;
  transition: 0.3s ease;
  transform: translate(0px);
}

.utility-nav-link:hover {
  width: 35px;
  transform: translateX(-20px);
}

.utility-nav-link:hover span {
  opacity: 1;
  transform: translateX(-10px);
}

.utility-nav-icon {
  background: #888;
  border: 1px solid #888;
  width: 20px;
  height: 20px;
}
<div class="utility-nav-links">

  <a class="utility-nav-link" href="">
    <img class="utility-nav-icon" src="https://picsum.photos/40" alt="">
    <span>search</span>
  </a>
  
  <a class="utility-nav-link" href="">
    <img class="utility-nav-icon" src="https://picsum.photos/42" alt="">
    <span>info</span>
  </a>
  
  <a class="utility-nav-link" href="">
    <img class="utility-nav-icon" src="https://picsum.photos/44" alt="">
    <span>My Housing</span>
  </a>

</div>

2

Answers


  1. You can do this without messing about with positioning. Just transition the width of your text span on hover, between zero and the intrinsic width of the text.

    The first catch is that you can’t smoothly transition the width (or height) of an element between zero and auto. The spec excluded it for performance reasons. In future, we may be able to. But for now, you have to transition between two specific widths. That’s where script comes in handy … from script you can determine the intrinsic width of the element (using its scrollWidth property), then assign this value to a CSS property (variable) which you then refer to in your style rules.

    /* in script, add a property to each span whose value is its intrinsic width */
    
    document.querySelectorAll('.utility-nav-link span').forEach(s => {
      s.style.setProperty('--intrinsicWidth', s.scrollWidth + 'px')
    })
    
    /* in css, on hover, set the span width to the value of the property */ 
    
    .utility-nav-link span {
      width: 0;
      transition: 0.3s;
    }
    .utility-nav-link:hover span {
      width: var(--intrinsicWidth);
    }
    

    The second catch is that because it contains a space, the label “My Housing” will wrap when its width is narrower than its intrinsic width, causing it to consume two lines instead of one. Changing the width therefore also changes the height, which causes the layout to shift and, depending on where the pointer is, can cause rapid oscillation between the hovered and unhovered states. Prevent this by turning off white space wrapping.

    .utility-nav-link span {
      white-space: nowrap;
    }
    

    A snippet to demonstrate:

    document.querySelectorAll('.utility-nav-link span').forEach(s => {
      s.style.setProperty('--intrinsicWidth', s.scrollWidth + 'px')
    })
    body {
      margin: 3em;
    }
    
    .utility-nav-links {
      display: flex;
      justify-content: end;
      gap: 1em;
    }
    
    .utility-nav-link {
      display: flex;
      align-items: center;
      gap: 0.5em;
      overflow: hidden;
    }
    
    .utility-nav-link span {
      width: 0;
      transition: 0.3s;
      white-space: nowrap;
    }
    
    .utility-nav-icon {
      background: #888;
      border: 1px solid #888;
      width: 30px;
      height: 30px;
      border-radius: 4px;
    }
    
    .utility-nav-link:hover span {
      width: var(--intrinsicWidth);  /* value set in script */
    }
    <div class="utility-nav-links">
      <a class="utility-nav-link">
        <img class="utility-nav-icon" src="https://picsum.photos/40">
        <span>search</span>
      </a>
      <a class="utility-nav-link">
        <img class="utility-nav-icon" src="https://picsum.photos/42">
        <span>info</span>
      </a>
      <a class="utility-nav-link">
        <img class="utility-nav-icon" src="https://picsum.photos/44">
        <span>My Housing</span>
      </a>
    </div>
    Login or Signup to reply.
  2. To create a transition where the text slides in from the right on hover, while preventing it from going behind the icons, you need to adjust the z-index and position of the elements involved.
    Here’s the corrected code:

    HTML:

    <div class="row">
      <div class="col-12 col-lg-3 d-none d-md-block">
        <div class="site-header__utility-nav-links">
          <a class="site-header__utility-nav-link" href="">
            <img class="site-header__utility-nav-icon" src="path_to_icon" alt="">
            <span>search</span>
          </a>
          <a class="site-header__utility-nav-link" href="">
            <img class="site-header__utility-nav-icon" src="path_to_icon" alt="">
            <span>info</span>
          </a>
          <a class="site-header__utility-nav-link" href="">
            <img class="site-header__utility-nav-icon" src="path_to_icon" alt="">
            <span>My Housing</span>
          </a>
       </div>
     </div>
    </div>
    

    CSS:

    .site-header__utility-nav-links {
      display: flex;
      justify-content: flex-end;
    }
    
    .site-header__utility-nav-link {
      margin-left: 18px;
      position: relative;
      overflow: hidden; /* Prevents text from going outside */
      transition: transform 0.3s ease;
    }
    
    .site-header__utility-nav-link:hover {
      transform: translateX(-20px);
    }
    
    .site-header__utility-nav-link span {
      position: absolute;
      left: 100%;
      opacity: 0;
      white-space: nowrap;
      transition: transform 0.3s ease, opacity 0.3s ease;
      transform: translateX(20px); /* Start offscreen */
    }
    
    .site-header__utility-nav-link:hover span {
      opacity: 1;
      transform: translateX(0); /* Slide into view */
    }
    
    .site-header__utility-nav-icon {
      width: 20px;
      height: 20px;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search