Execute :hover and :hover:after animation with keyframes on component load - css

i would like to play this hover animation on component load, because I wrote a JS function that checks if the component is in the viewport and reloads it (changes its class).
You can use Sass (scss) or regular css.
.module .active {
display: inline-block;
position: relative;
color: var(--text-color-dark);
animation: loadInAnimation ease 3s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
#keyframes loadInAnimation { // add :hover and :hover:after event
0% {
// start of animation
}
100% {
// end ofanimation
}
}
.module .active:after { // transform into keyframe animation
content: '';
position: absolute;
width: 100%;
transform: scaleX(0);
height: 2px;
bottom: 0;
left: 0;
background-color: var(--primary-color);
transform-origin: bottom right;
transition: transform 0.25s ease-out;
}
.module .active:hover:after { // transform into keyframe animation
transform: scaleX(1);
transform-origin: bottom left;
}
Thank you for your help!
JS (irrelevant):
<script>
function reveal() {
var reveals = document.querySelectorAll(".reveal");
console.log(reveals);
for (var i = 0; i < reveals.length; i++) {
var windowHeight = window.innerHeight;
var elementTop = reveals[i].getBoundingClientRect().top;
var elementVisible = 150;
if (elementTop < windowHeight - elementVisible) {
reveals[i].classList.add("active");
} else {
reveals[i].classList.remove("active");
}
}
}
window.addEventListener("scroll", reveal);
window.addEventListener("load", reveal);
</script>
HTML (also irrelevant):
<h2 className='heading reveal'>Tennisakademie Vasquez</h2>

I've fixed the animation with an additional element providing the :after feature:
.module .heading {
font-size: 2.75rem;
font-weight: 700;
margin-bottom: 2rem;
font-family: 'Oswald', sans-serif;
font-weight: 200;
color: var(--text-color-dark);
}
.module .active {
display: inline-block;
position: relative;
color: var(--text-color-dark);
animation-iteration-count: 1;
animation-fill-mode: forwards;
.reveal-line {
transform: scaleX(1);
transform-origin: bottom left;
content: '';
position: absolute;
width: 100%;
height: 2px;
bottom: 0;
left: 0;
background-color: var(--primary-color);
transform-origin: bottom right;
transition: transform 0.6s ease-out;
animation: loadInAnimation ease 1.5s;
}
}
#keyframes loadInAnimation {
0% {
width: 0%;
}
100% {
width: 100%;
}
}
<h3 className='heading reveal'>Unsere Angebote<div className='reveal-line' /></h3>

Related

NavBar wont show?

`Hi, My nav bar wont show up in my project. The only thing that shows is the background color. Can anyone help me understand what i am doing wrong? I guess i need to conect it to an icon somehow - but how would that work? i appriciate all suggestions. I can also post the CSS file if needed.
JS:
this is the nav bar and some JS that is suppose to open it up when you press the the icon
import './test.scss';
import {Link} from "react-router-dom";
export function Header () {
//Js
console.clear();
const app = (() => {
let body;
let menu;
let menuItems;
const init = () => {
body = document.querySelector('body');
menu = document.querySelector('.menu-icon');
menuItems = document.querySelectorAll('.nav__list-item');
applyListeners();
}
const applyListeners = () => {
menu.addEventListener('click', () => toggleClass(body, 'nav-active'));
}
const toggleClass = (element, stringClass) => {
if(element.classList.contains(stringClass))
element.classList.remove(stringClass);
else
element.classList.add(stringClass);
}
init();
})();
return (
<>
<div className="menu-icon">
<span className="menu-icon__line menu-icon__line-left" />
<span className="menu-icon__line" />
<span className="menu-icon__line menu-icon__line-right" />
</div>
<div className="nav">
<div className="nav__content">
<ul className="nav__list">
<li className="nav__list-item">Home</li>
<li className="nav__list-item"></li>
<li className="nav__list-item"></li>
<li className="nav__list-item"></li>
</ul>
</div>
</div>
<div className="site-content">
<h1 className="site-content__headline">
text
</h1>
</div>
</>
);
}
thanks
CSS(SCSS) file:
$background--color:#1e2023;
$icon--color:#1e2023;
$font--color:#ffffff;
$font--color--active:#000000;
$font--primary:'Fira Sans', sans-serif;
$transition--length: .8;
body{
background-color: $background--color;
font-family: $font--primary;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.site-content{
max-width: 1100px;
height: 100vh;
margin-left: auto;
margin-right: auto;
display: flex;
align-items: center;
justify-content: center;
&__headline{
font-weight: 200;
color: $font--color;
font-size: calc(2vw + 10px);
text-align: center;
}
}
//default state
.menu-icon{
$size: 30px;
height: $size;
width: $size;
position: fixed;
z-index:2;
left: 50px;
top: 30px;
cursor: pointer;
&__line{
height: 2px;
width: $size;
display: block;
background-color: $font--color;
margin-bottom: 4px;
transition: transform .2s ease, background-color .5s ease;
}
&__line-left{
width: $size / 2;
}
&__line-right{
width: $size / 2;
float: right;
}
}
.nav{
$width: 100vw;
$height: 100vh;
$font--size--calc: calc(2vw + 10px);
$transition--easing: cubic-bezier(.77,0,.175,1);
position: fixed;
z-index:1;
&:before,&:after{
content: "";
position: fixed;
width:$width;
height:$height;
background: rgba(#eaeaea, .2);
z-index: -1;
transition: transform $transition--easing $transition--length + s;
transform: translateX(0%) translateY(-100%);
}
&:after{
background: rgba(#ffffff, 1);
transition-delay: 0s;
}
&:before{
transition-delay: .1s;
}
&__content{
position: fixed;
top:50%;
transform: translate(0%,-50%);
width: 100%;
text-align: center;
font-size: $font--size--calc;
font-weight: 200;
cursor: pointer;
}
&__list-item{
position: relative;
display: inline-block;
transition-delay: $transition--length + s;
opacity: 0;
transform: translate(0%, 100%);
transition: opacity .2s ease, transform .3s ease;
margin-right: 25px;
&:before{
content: "";
position: absolute;
background: $font--color--active;
width: 20px;
height: 1px;
top: 100%;
transform: translate(0%, 0%);
transition: all .3s ease;
z-index: -1;
}
&:hover{
&:before{
width: 100%;
}
}
}
}
//active state
body.nav-active{
$menu--items--count: 4;
.menu-icon{
&__line{
background-color: #000;
transform: translateX(0px) rotate(-45deg);
}
&__line-left{
transform: translateX(1px) rotate(45deg);
}
&__line-right{
transform: translateX(-2px) rotate(45deg);
}
}
.nav{
visibility:visible;
&:before,&:after{
transform: translateX(0%) translateY(0%);
}
&:after{
transition-delay: .1s;
}
&:before{
transition-delay: 0s;
}
&__list-item{
opacity: 1;
transform: translateX(0%);
transition: opacity .3s ease, transform .3s ease, color .3s ease;
#for $i from 0 through $menu--items--count {
&:nth-child(#{$i}){
transition-delay: $transition--length * $i / 8 + .5 + s;
}
}
}
}
}

Stop shaking in CSS animation

So I'm making a tic tac toe game right now and I'm trying to add in an animation for a line that shows who won. When the player wins by getting 3 horizontal things then the animation works perfectly but when they win vertically then there's a slight shake on it. Is there any way I can remove this?
Here is the CSS for the line:
#keyframes grow-left {
0% {
width: 0;
}
100% {
width: 1;
}
}
.winLine {
position: absolute;
width: 300%;
height: var(--borderThickness);
background-color: var(--textColor);
border-radius: 1rem;
transform-origin: center;
z-index: 2;
animation: grow-left 1s ease-in-out 0s;
opacity: 1;
}
To view the website and see what I'm talking about it's live on GitHub at this link https://bartycoding.github.io/Tic-tac-toe/
Try creating another div that increases the height instead of using the transform: rotate(90deg);
You could try with transform: scale():
#keyframes grow-left {
0% {
transform: scale(0,1);
}
100% {
transform: scale(1,1);
}
}
I actually fixed this by having the rotation as a global css variable and then changing that variable from javascript so the css looks like this:
#keyframes grow-left {
0% {
transform: rotate(var(--winLineRotation)) scaleX(0);
}
100% {
transform: rotate(var(--winLineRotation)) scaleX(100%);
}
}
.winLine {
position: absolute;
width: 300%;
height: var(--borderThickness);
background-color: var(--textColor);
border-radius: 1rem;
transform-origin: center;
z-index: 2;
animation: grow-left 1s ease-in-out 0s;
opacity: 1;
transform: rotate(var(--winLineRotation));
}
To prevent that little shake at the end of animations, you need to use : backface-visibility:hidden; to the class of the element that you've defined animation for.
#keyframes grow-left {
0% {
width: 0;
}
100% {
width: 1;
}
}
.winLine {
/* Try this */
backface-visibility: hidden;
position: absolute;
width: 300%;
height: var(--borderThickness);
background-color: var(--textColor);
border-radius: 1rem;
transform-origin: center;
z-index: 2;
animation: grow-left 1s ease-in-out 0s;
opacity: 1;
}

How to disable an animation when opening or refereshing the page

I have made a little animation that add a line under the box from the left to the right when it's hovered and the line go back from the left to the right when the mouse isn't hovering the box, but the issue is that the line goes back from the left to the right when I refresh the page. Is there a solution to disable the animation when I open the page or when I refresh it (if possible without JavaScript)
body {
background-color: black;
}
.box {
width: 100px;
height: 100px;
margin: 40px auto;
background-color: #f44336;
position: relative;
}
.box::after {
content: '';
position: absolute;
bottom: -7px;
width: 100%;
height: 3px;
background-color: #fff;
animation: out 400ms linear forwards;
transform-origin: right center;
}
.box:hover::after {
animation: in 400ms linear;
transform-origin: left center;
}
#keyframes in {
from {
transform: scaleX(0);
}
to {
transform: scaleX(1);
}
}
#keyframes out {
from {
transform: scaleX(1);
}
to {
transform: scaleX(0);
}
}
<div class="box"></div>
I changed your animation to a transition instead. Is this what you're after?
body {
background-color: black;
}
.box {
width: 100px;
height: 100px;
margin: 40px auto;
background-color: #f44336;
position: relative;
}
.box::after {
content: '';
position: absolute;
bottom: -7px;
width: 100%;
height: 3px;
background-color: #fff;
transform: scaleX(0);
transform-origin: right center;
transition: transform 400ms linear;
}
.box:hover::after {
transform: scaleX(1);
transform-origin: left center;
}
<div class="box"></div>
I don't believe this is possible using only css - you can use a css declaration when a mouse-over ends, however it will always trigger upon load.
You can however use simple JS using classes "on" and "off" to differentiate 'page load' and 'hover off'.
The code in this instance would be:
demo
$(".box").hover(
function () {
$(this).removeClass('off').addClass('on');
},
function () {
$(this).removeClass('on').addClass('off');
}
);
body {
background-color: black;
}
.box {
width: 200px;
height: 200px;
margin: 40px auto;
background-color: #f44336;
position: relative;
}
.box::after {
content: '';
position: absolute;
bottom: -7px;
height: 3px;
background-color: #fff;
}
.box.off::after {
width: 100%;
animation: out 400ms linear forwards;
transform-origin: right center;
}
.box.on::after {
width: 100%;
animation: in 400ms linear;
transform-origin: left center;
}
#keyframes in {
from {
transform: scaleX(0);
}
to {
transform: scaleX(1);
}
}
#keyframes out {
from {
transform: scaleX(1);
}
to {
transform: scaleX(0);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box"></div>

Animation CSS with dynamic text

I need to add an animation to this links on hover, I have to deal with the "width" of the link word can change. Is there any way to change dynamically the value of the translate animation?
.link {
text-decoration: none;
padding-left: 15px;
position: relative;
transition: 1s;
&:hover {
padding-left: 0;
.link--decoration {
animation: in 1s ease both;
}
}
}
.link--decoration {
animation: out 1s ease both;
left: 0;
position: absolute;
}
#keyframes in {
to {
transform: translate(calc(100% + 75px), 0);
}
}
#keyframes out {
from {
transform: translate(calc(100% + 75px), 0);
}
to {
transform: translate(0, 0);
}
}
<p><span class="link--decoration">&dash;</span><span class="link--text">Read Article</span></p>
<p><span class="link--decoration">&dash;</span><span class="link--text">Open Hours</span></p>
<p><span class="link--decoration">&dash;</span><span class="link--text">Open Localization</span></p>
https://codepen.io/serrazina/pen/zzEaLE
There are 2 approaches I see to solving this. The first uses left to animate the decoration. Like this:
.link {
text-decoration: none;
padding-left: 15px;
position: relative;
transition: 1s;
}
.link:hover {
padding-left: 0;
}
.link:hover .link--decoration {
animation: in 1s ease both;
}
.link--decoration {
animation: out 1s ease both;
left: 0;
position: absolute;
}
#keyframes in {
to {
left: calc(100% + 5px);
}
}
#keyframes out {
from {
left: calc(100% + 5px);
}
to {
left: 0;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p><span class="link--decoration">&dash;</span><span class="link--text">Read Article</span></p>
<p><span class="link--decoration">&dash;</span><span class="link--text">Open Hours</span></p>
<p><span class="link--decoration">&dash;</span><span class="link--text">Open Localization</span></p>
The second method uses transform to take advantage of hardware acceleration. The difference between this method and yours was adding a width: 100% to the decoration as the translate is based on the width of the element. In your example that meant transform: translateX(100%) was 100% the width of the decoration element, which was about 20px in width. In the demo below I've made the element 100% the width of it's parent element, so transform: translateX(100%) moves it to the right of the parent element.
.link {
text-decoration: none;
padding-left: 15px;
position: relative;
transition: 1s;
}
.link:hover {
padding-left: 0;
}
.link:hover .link--decoration {
animation: in 1s ease both;
}
.link--decoration {
animation: out 1s ease both;
left: 0;
width: 100%;
position: absolute;
}
#keyframes in {
to {
transform: translateX(calc(100% + 5px));
}
}
#keyframes out {
from {
transform: translateX(calc(100% + 5px));
}
to {
transform: translateX(0);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p><span class="link--decoration">&dash;</span><span class="link--text">Read Article</span></p>
<p><span class="link--decoration">&dash;</span><span class="link--text">Open Hours</span></p>
<p><span class="link--decoration">&dash;</span><span class="link--text">Open Localization</span></p>

How to reverse animation on hovering off element?

Im trying to animate a button up to the center of it's parent element on hover using translateY and CSS3 animations, this seems to work fine (although any advice improvements would be great) but the problem is as soon as I hover off the button doesn't reverse the animation instead just resetting back to -50px. Was wondering how I can achieve this?
CSS (Using SCSS + Compass)
#include keyframe(slideIn) {
0%{
//opacity:0;
-webkit-transform:translateY(-50px);
}
60%{
//opacity:1;
//-webkit-transform:translateY(-195px);
}
80%{
-webkit-transform:translateY(-188px);
}
100%{
-webkit-transform:translateY(-175px);
}
}
.box {
width: 300px;
height: 300px;
background: navy;
position: relative;
-webkit-transform: translate3d(0, 0, 0);
overflow: hidden;
&:hover {
.btn {
#include animation(slideIn .45s ease-in-out alternate forwards);
}
}
}
.btn {
width: 50px;
height: 50px;
position: absolute;
bottom: -50px;
}
Codepen - http://codepen.io/styler/pen/fpFlL
You can define 3 css classes:
.box{
//base css here
}
.box.out{
animation-name: out;
animation-duration:.45s;
}
.box.over{
animation-name: in;
animation-duration:.45s;
}
#keyframe in {
//your keyframe animation here
}
#keyframe out {
//reverse animation here
}
Then some javascript to detect hovers:
$(".box").hover(
function () {
$(this).removeClass('out').addClass('over');
},
function () {
$(this).removeClass('over').addClass('out');
}
);
You should put the css animation on the button and not on the hover.
.box {
width: 300px;
height: 300px;
background: navy;
position: relative;
-webkit-transform: translate3d(0, 0, 0);
&:hover {
.btn {
bottom: 150px;
}
}
}
.btn {
width: 50px;
height: 50px;
position: absolute;
bottom: -50px;
-webkit-transition-duration: 0.3s;
-moz-transition-duration: 0.3s;
-o-transition-duration: 0.3s;
transition-duration: 0.3s;
}
http://codepen.io/anon/pen/qGxBh

Resources