Search code examples
htmlcsscss-transitions

p:hover::after/::before smooth transition


I am creating a Grid gallery. Under each img I have p with a short name of a picture.

<div id="projects-grid">
  <figure class="project-tile">
    <a href="">
      <img src="Portfolio_project_img_1.png" alt="">
      <p>Tribute Page</p>
    </a>
  </figure>
</div>

Before and after each p I need these characters to appear when hovering over p: "<" - before; "/>" - after I need this transition to be smooth, like ease-in-out, 0.3s

I currently have this CSS code:

#projects-grid p:hover::after {
  content: " />";
  font-size: 1.1rem;
  vertical-align: baseline;
  color: orange;
}
#projects-grid p:hover::before {
  content: "< ";
  font-size: 1.1rem;
  vertical-align: 5%;
  color: orange;
}

I have tried to add transition to #projects-grid p:hover::after and #projects-grid p:hover::before but it wouldn't work.

So, how can I target specifically those characters in :hover::after and :hover::before?


Solution

  • You need to use a CSS property that supports gradual transitions.

    Your problem was likely that you tried to "make a pseudo-element exist gradually" which doesn't work. (You might have been looking at some jQuery functions that sort of achieved this)

    Or you used a CSS-property which doesn't support gradual transitions. (visibility is one example. You can set transition:visibility 1s but it will not work as expected - it will instantly flip from visibility:hidden to visibility:visible instead of gradually transitioning during 1 second)

    My solution is to transition from opacity:0 to opacity:1

    One benefit of this is that the layout will not be jumping around on hover.

    The pseudo-element has been rendered, it is taking up space but it's just not visually visible until you hover, which makes it gradually become visually visible.

    #projects-grid p::after {
      content: " />";
      vertical-align: baseline;
    }
    
    #projects-grid p::before {
      content: "< ";
      vertical-align: 5%;
    }
    
    #projects-grid p::before,
    #projects-grid p::after {
      font-size: 1.1rem;
      color: orange;
      transition: opacity 0.3s ease;
      opacity: 0;
    }
    
    #projects-grid p:hover::after,
    #projects-grid p:hover::before {
      opacity: 1;
    }
    <div id="projects-grid">
      <figure class="project-tile">
        <a href="">
          <img src="Portfolio_project_img_1.png" alt="">
          <p>Tribute Page</p>
        </a>
      </figure>
    </div>

    Sidenote: It can be tricky to find a list of CSS props that support gradual transitions. Most lists like https://www.quackit.com/css/css3/animations/animatable_properties/ include visibility which is kind of a lie - since it cannot gradually animate the way you expect it to, it just flips instantly from visible to invisible