Sara Ree
Sara Ree

Reputation: 3543

Align keyframe animating text to center of the container

This is a simple revealing text animation code.

I need to use different font sizes and that caused the text to end in different vertical positions (please run the code snippet to see what I mean).

The issue is I want to perfectly align the animating text to the middle of its container vertically and align it to the left horizontally even when font size is changed.

If I remove the position: absolute from textClass the text fades in and out in the middle of the container but I lose the translating animation from bottom to top!

Note: I know the downsides of using viewport units but I really need to use those (vw and vh) or % unit and I'm not allowed to use px em, etc...

let textId = document.getElementById("textId");


      // Text with 1vw font size
      setTimeout(function(){
      //Our Text
      let myText = 'First text here';
      //Define the font size
      textId.style.fontSize = "1vw";
      //append text to the elemnt
      textId.innerHTML = `${myText}`;
      //animate the text
      textId.classList.add("animeShow");
      textId.classList.remove("animeHide");
      }, 1000);
      
      // Hide Text by adding `animeHide` class
      setTimeout(function(){
      textId.classList.remove("animeShow");
      textId.classList.add("animeHide");
      }, 4000);
      
      // Text with 3vw font size
      setTimeout(function(){
  
      let myText = 'Second text here';
  
      textId.style.fontSize = "3vw";
     
      textId.innerHTML = `${myText}`;
     
      textId.classList.add("animeShow");
      textId.classList.remove("animeHide");
      }, 5000);
.container {
    position: absolute;
    overflow: hidden;
    left: 10vw;
    top: 51vh;
    height: 26vh;
    width: 88vw;   
    display: flex;
    justify-content: center;
    align-items: center;
    outline: 0.1vw dashed orange;
}

.textClass {
    position: absolute;
    font-family: 'Open Sans', sans-serif;
    font-weight: bold;
    color: rgb(128, 128, 128);
    left: 0.5vw;
    opacity: 0;
}

.animeShow {
    animation: Show 0.3s ease-in-out;
    animation-delay: 0.5s;
    animation-fill-mode: forwards ;
}

.animeHide {
    animation: Hide 0.3s ease-in-out;  
    animation-fill-mode: forwards ;
}

@-webkit-keyframes Show {
  from { opacity: 0; top: 30vh }
  to   { opacity: 1; top: 0vh }
}

@-webkit-keyframes Hide {
   from { opacity: 1; top: 0vh }
   to   { opacity: 0; top: 30vh }
}
<div class = "container">
 <p id="textId" class="textClass"></p>
</div>

I have used this with no success:

transition: 200ms transform;
transform: translateY(-50%);

Using This too:

@-webkit-keyframes Show {
  from { opacity: 0; top: 0% }
  to   { opacity: 1; top: 50% }
}

Upvotes: 1

Views: 551

Answers (3)

Hiren Karangiya
Hiren Karangiya

Reputation: 94

I think you just have to update this (.textClass) class with the following CSS and this will make vertically center text inside container. I hope this will solve your issue.

.textClass {
    position: absolute;
    font-family: 'Open Sans', sans-serif;
    font-weight: bold;
    color: rgb(128, 128, 128);
    left: 0.5vw;
    opacity: 0;
    margin: 0;
    top: 0;
    bottom: 0;
    display: flex;
    align-items: center;
}

Upvotes: 1

Ahmed Gaafer
Ahmed Gaafer

Reputation: 1661

  • Make the container relatively positioned, which declares it to be a container for absolutely positioned elements.
  • Make the element itself absolutely positioned.
  • Place it halfway down the container with 'top: 50%'. (Note that 50%' here means 50% of the height of the container.)
  • Use a translation to move the element up by its own height (The '100%' in 'translate(0, -100%)' refers to the height of the element itself.)

This will move the text closer to the middle of the container.

Adjust the -100% with a higher negative value to move the element to the top more. but I have found that -100% is the nearest thing to the center

let textId = document.getElementById("textId");


// Text with 1vw font size
setTimeout(function() {
  //Our Text
  let myText = 'First text here';
  //Define the font size
  textId.style.fontSize = "1vw";
  //append text to the elemnt
  textId.innerHTML = `${myText}`;
  //animate the text
  textId.classList.add("animeShow");
  textId.classList.remove("animeHide");
}, 1000);

// Hide Text by adding `animeHide` class
setTimeout(function() {
  textId.classList.remove("animeShow");
  textId.classList.add("animeHide");
}, 4000);

// Text with 3vw font size
setTimeout(function() {

  let myText = 'Second text here';

  textId.style.fontSize = "3vw";

  textId.innerHTML = `${myText}`;

  textId.classList.add("animeShow");
  textId.classList.remove("animeHide");
}, 5000);
.container {
  position: relative;
  overflow: hidden;
  left: 10vw;
  top: 51vh;
  height: 26vh;
  width: 88vw;
  display: flex;
  justify-content: center;
  align-items: center;
  outline: 0.1vw dashed orange;
}

.container p {
  position: absolute;
  font-family: 'Open Sans', sans-serif;
  font-weight: bold;
  color: rgb(128, 128, 128);
  left: 0.5vw;
  opacity: 0;
}

.animeShow {
  animation: Show 0.3s ease-in-out;
  animation-delay: 0.5s;
  animation-fill-mode: forwards;
}

.animeHide {
  animation: Hide 0.3s ease-in-out;
  animation-fill-mode: forwards;
}

@-webkit-keyframes Show {
  from {
    opacity: 0;
    top: 30vh;
  }
  to {
    opacity: 1;
    top: 50%;
    transform: translateY(-100%);
  }
}

@-webkit-keyframes Hide {
  from {
    opacity: 1;
    top: 0vh
  }
  to {
    opacity: 0;
    top: 30vh
  }
}
<div class="container">
  <p id="textId" class="textClass"></p>
</div>

Upvotes: 1

sonic
sonic

Reputation: 1431

I think I got it:

@-webkit-keyframes Show {
  from { opacity: 0; padding-top: 10%; }
  to   { opacity: 1; padding-top: 0%; }
}

@-webkit-keyframes Hide {
   from { opacity: 1; padding-top: 0%; }
   to   { opacity: 0; padding-top: 10%; }
}

I tried to use margin-top but it is already used by elements.

Upvotes: 1

Related Questions