skip to Main Content

I have looked at Move HTML element upwards on hover and I know how to define the CSS animation I want, however given the other animations at play in this snippet I am running into issues animating a child element on parent hover.

Snippet:

html,
body {
  padding: 0;
  margin: 0;
  font-family: "sequel-sans-roman", -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}

.container {
  padding: 0 2rem;
}

.main {
  min-height: 100vh;
  padding: 4rem 0;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

a {
  color: inherit;
  text-decoration: none;
}

* {
  box-sizing: border-box;
}

.navIcon {
  display: inline-block;
  flex-grow: 1;
}

.nav {
  display: flex;
  justify-content: space-between;
  width: 100%;
  margin-top: 2.4em;
  /* coordinates w height of line away from link, MUST BE = */
}

.snip1168 {
  text-align: center;
  text-transform: uppercase;
}

.snip1168 * {
  box-sizing: border-box;
}

.snip1168 li {
  display: inline-block;
  list-style: outside none none;
  margin: 0 1.5em;
  padding: 0;
}

.snip1168 a {
  padding: 2.4em 0 0.5em;
  /* height of line away from link */
  color: rgba(0, 0, 0, 1);
  position: relative;
  text-decoration: none;
}

.snip1168 a:before,
.snip1168 a:after {
  position: absolute;
  -webkit-transition: all 0.35s ease;
  transition: all 0.35s ease;
}

.snip1168 a:before {
  top: 0;
  display: block;
  height: 3px;
  width: 0%;
  content: "";
  background-color: black;
}

.snip1168 a:hover:before,
.snip1168 .current a:before {
  opacity: 1;
  width: 100%;
}

.snip1168 a:hover:after,
.snip1168 .current a:after {
  max-width: 100%;
}

.mainText {
  text-transform: uppercase;
  font-size: 1.1rem;
}
<div class='container'>
  <main class='main'>
    <div class='nav'>
      <div class='navIcon'>
        <img src="https://picsum.photos/40" height={40} width={40} />
      </div>
      <ul class='snip1168'>
        <li class='current'><a href="#" data-hover="Work">Work</a></li>
        <li><a href="#" data-hover="Recs">Recs</a></li>
        <li><a href="#" data-hover="Say Hi">Say Hi</a></li>
      </ul>
    </div>
  </main>
</div>

This is the animation I want to apply to only the text of the nav bar (not the animated lines) on hover of the whole <li> :

transition: transform ease 400ms;
transform: translate(0, -10px);

Without breaking the existing line animations, how can I animate move only the text of these nav items on hover of each parent <li>?

2

Answers


  1. If you don’t want to restructure your html to circumvent this, you could apply the same but opposite animation on the lines.
    In this case transitioning down 10px with the same duration.
    that would make it appear as if the line is not moving.

    html,
    body {
      padding: 0;
      margin: 0;
      font-family: "sequel-sans-roman", -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
    }
    
    .container {
      padding: 0 2rem;
    }
    
    .main {
      min-height: 100vh;
      padding: 4rem 0;
      flex: 1;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
    }
    
    a {
      color: inherit;
      text-decoration: none;
    }
    
    * {
      box-sizing: border-box;
    }
    
    .navIcon {
      display: inline-block;
      flex-grow: 1;
    }
    
    .nav {
      display: flex;
      justify-content: space-between;
      width: 100%;
      margin-top: 2.4em;
      /* coordinates w height of line away from link, MUST BE = */
    }
    
    .snip1168 {
      text-align: center;
      text-transform: uppercase;
    }
    
    .snip1168 * {
      box-sizing: border-box;
    }
    
    .snip1168 li {
      display: inline-block;
      list-style: outside none none;
      margin: 0 1.5em;
      padding: 0;
      transition: transform ease 400ms;
    }
    
    .snip1168 a {
      padding: 2.4em 0 0.5em;
      /* height of line away from link */
      color: rgba(0, 0, 0, 1);
      position: relative;
      text-decoration: none;
    }
    
    .snip1168 a:before,
    .snip1168 a:after {
      position: absolute;
      -webkit-transition: all 0.35s ease;
      transition: all 0.35s ease;
    }
    
    .snip1168 a:before {
      top: 0;
      display: block;
      height: 3px;
      width: 0%;
      content: "";
      background-color: black;
    }
    
    .snip1168 a:hover:before,
    .snip1168 .current a:before {
      opacity: 1;
      width: 100%;
      transform: translate(0, 10px);
    }
    
    .snip1168 li:hover,
    .snip1168 .current {
      transform: translate(0, -10px);
    }
    
    .snip1168 a:hover:after,
    .snip1168 .current a:after {
      max-width: 100%;
    }
    
    .mainText {
      text-transform: uppercase;
      font-size: 1.1rem;
    }
    <div class='container'>
      <main class='main'>
        <div class='nav'>
          <div class='navIcon'>
            <img src="https://picsum.photos/40" height={40} width={40} />
          </div>
          <ul class='snip1168'>
            <li class='current'><a href="#" data-hover="Work">Work</a></li>
            <li><a href="#" data-hover="Recs">Recs</a></li>
            <li><a href="#" data-hover="Say Hi">Say Hi</a></li>
          </ul>
        </div>
      </main>
    </div>

    I would still recommend to restructure your html.
    having a separate element for the ‘bar’ instead of using a :before rule on the <a> tag.
    IE: moving that :before to be on the <li> and then moving the <a> up by 10px would achieve the same.

    Login or Signup to reply.
  2. You could move the line drawing part to the li rather than the a element and on the a element put the translate upwards. That way you don’t have to alter the HTML.

    html,
    body {
      padding: 0;
      margin: 0;
      font-family: "sequel-sans-roman", -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
    }
    
    .container {
      padding: 0 2rem;
    }
    
    .main {
      min-height: 100vh;
      padding: 4rem 0;
      flex: 1;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
    }
    
    a {
      color: inherit;
      text-decoration: none;
    }
    
    * {
      box-sizing: border-box;
    }
    
    .navIcon {
      display: inline-block;
      flex-grow: 1;
    }
    
    .nav {
      display: flex;
      justify-content: space-between;
      width: 100%;
      margin-top: 2.4em;
      /* coordinates w height of line away from link, MUST BE = */
    }
    
    .snip1168 {
      text-align: center;
      text-transform: uppercase;
    }
    
    .snip1168 * {
      box-sizing: border-box;
    }
    
    .snip1168 li {
      display: inline-block;
      list-style: outside none none;
      margin: 0 1.5em;
      padding: 0;
      background: ppink;
    }
    
    .snip1168 li {
      padding: 2.4em 0 0.5em;
      /* height of line away from link */
      color: rgba(0, 0, 0, 1);
      position: relative;
      text-decoration: none;
      background: pink;
      display: inline-block;
    }
    
    .snip1168 li:before,
    .snip1168 li:after {
      position: absolute;
      -webkit-transition: all 0.35s ease;
      transition: all 0.35s ease;
    }
    
    .snip1168 li:before {
      top: 0;
      display: inline-block;
      height: 3px;
      width: 0%;
      content: "";
      background-color: black;
    }
    
    .snip1168 li:hover:before,
    .snip1168 .current a:before {
      opacity: 1;
      width: 100%;
    }
    
    .snip1168 li:hover:after,
    .snip1168 .current li:after {
      max-width: 100%;
    }
    
    .mainText {
      text-transform: uppercase;
      font-size: 1.1rem;
    }
    
    .snip1168 li a {
      transition: transform ease 400ms;
      transform: translate(0, 0);
      display: inline-block;
    }
    
    .snip1168 li:hover a {
      transition: transform ease 400ms;
      transform: translate(0, -10px);
    }
    <div class='container'>
      <main class='main'>
        <div class='nav'>
          <div class='navIcon'>
            <img src="https://picsum.photos/40" height={40} width={40} />
          </div>
          <ul class='snip1168'>
            <li class='current'><a href="#" data-hover="Work">Work</a></li>
            <li><a href="#" data-hover="Recs">Recs</a></li>
            <li><a href="#" data-hover="Say Hi">Say Hi</a></li>
          </ul>
        </div>
      </main>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search