Is it possible to create an animation with CSS so that a given element (in the example, an h2 tag) when hovered moves a bit and fades out, and come back a few moments later fading in with a larger font-size.
Ideally:
This would occur on hover and the inverse when no longer hovering.
Without specifying the initial font size (in the example 2rem).
I've been trying some solutions with animations but so far nothing close to what I'm looking for.
Thanks
Edit: added short animation of what I was looking for (line is there for geometric reference of the text's position):
Edit2: the GIF if looping, but the text is supposed to remain large while the container element is hovered.
:root {
height: 100%;
background-color: lightgrey;
padding: 30px;
text-align: center;
}
h2 {
font-family: Arial;
font-size: 2rem;
}
:root:hover h2 {
font-size: 5rem;
animation: text 1s forwards ease-out;
}
#keyframes text {
0% {
transform: translateY(-30px);
opacity: 1;
}
50% {
opacity: 0;
}
100% {
}
}
<h2>TEXT</<h2>
Thank you for providing a snippet. Not sure this is what you opted for. I added a flex container to center the text, but this is optional.
:root {
height: 100%;
background-color: lightgrey;
padding: 30px;
text-align: center;
}
h2 {
font-family: Arial;
}
:root:hover h2 {
animation: text 1s forwards ease-out;
}
#keyframes text {
0% {
transform: translateY(0px);
opacity: 1;
}
25% {
transform: translateY(-30px);
opacity: 0;
font-size: 1rem;
}
50% {
opacity: 0;
}
75% {
opacity: 0;
transform: translateY(0px);
}
100% {
font-size: 5rem;
opacity: 1;
}
}
<div style="height: 150px; display:flex; align-items: center; justify-content: center;">
<h2>TEXT</h2>
</div>
UPDATE: Attempting doing the gif animation
:root {
height: 100%;
background-color: lightgrey;
padding: 30px;
text-align: center;
}
h2 {
font-family: Arial;
font-size: 2em;
margin-bottom: 0;
line-height: 1;
position: absolute;
bottom: 0;
text-align: center;
width: 100%
}
:root:hover h2 {
animation: text 1s forwards ease-out;
}
#keyframes text {
0% {
transform: translateY(0px);
opacity: 1;
}
25% {
transform: translateY(+50px);
opacity: 0;
}
50% {
opacity: 0;
font-size: 2em;
}
75% {
opacity: 0;
font-size: 5em;
transform: translateY(+50px);
}
100% {
font-size: 5rem;
transform: translateY(0px);
opacity: 1;
}
}
<div style="height: 100px; position: relative; border: 1px solid red;">
<h2>TEXT</h2>
</div>
<hr>
The root element confuses me. Nevertheless, you can add a font-size and oppacity 0 at 50 percent. The element will return to the original place afterwards. The margin-top keeps the element with the bigger font size in place. Not sure if this is the ideal solution.
Maybe just personal preference. I have changed the animation to ease-in-out, see https://www.w3schools.com/css/css3_transitions.asp
:root {
height: 100%;
background-color: lightgrey;
text-align: center;
}
h2 {
font-family: Arial;
padding: 0px;
}
:root:hover h2 {
animation: text 3s forwards ease-in-out;
}
#keyframes text {
0% {
opacity: 1;
}
50% {
opacity: 0;
font-size: 2rem;
}
100% {
opacity: 1;
margin-top: 1.5rem;
font-size: 3.5rem;
}
}
<h2>TEXT</<h2>
I don't think I double posted but if I did, sorry.
I have a problem with my CSS code:
I want the second text to show up when the first animation is finished.
So it will be something like:
First animation starting, second text hidden, then first animation finished, and then second text shown.
I think the problem are coming from the blinking animation (second_text_anim)
Here is my HTML code:
* {
padding: 0;
margin: 0;
font-family: sans-serif;
}
body {
background: white;
}
.container {
text-align: center;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
}
.container span {
text-transform: uppercase;
display: block;
}
.first_text {
color: white;
font-size: 60px;
font-weight: 700;
letter-spacing: 8px;
margin-bottom: 20px;
background: black;
position: relative;
animation: first_text_anim 3s 1;
}
/* The second text should be displayed at the
end of the first animation */
.second_text {
font-size: 30px;
color: darkcyan;
display: block;
animation: second_text_anim 1s 3s linear infinite;
}
#keyframes first_text_anim {
0% {
color: black;
margin-bottom: -40px;
}
30% {
letter-spacing: 25px;
margin-bottom: -40px;
}
85% {
letter-spacing: 8px;
margin-bottom: -40px;
}
}
#keyframes second_text_anim {
50% {
opacity: 0;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Animation Text</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<span class="first_text">First animation</span>
<span class="second_text">Second animation, should be displayed at the end </span>
</div>
</body>
</html>
Your animation-delay works but you also need to set animation-fill-mode.
Also, Change 50% to from for the second title, so it will set its initial state to opacity: 0;.
One last thing: To enable your blinking animation, add alternate to the shorthand.
This is the final result:
*{
padding: 0;
margin: 0;
font-family: sans-serif;
}
body{
background:white;
}
.container{
text-align: center;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 100%;
}
.container span{
text-transform: uppercase;
display: block;
}
.first_text{
color: white;
font-size: 60px;
font-weight: 700;
letter-spacing: 8px;
margin-bottom: 20px;
background: black;
position: relative;
animation: first_text_anim 3s 1;
}
/* The second text should be displayed at the end of the first animation */
.second_text{
font-size: 30px;
color: darkcyan;
display: block;
animation:second_text_anim 1s 3s linear infinite alternate both;
}
#keyframes first_text_anim {
0%{
color: black;
margin-bottom: -40px;
}
30%{
letter-spacing: 25px;
margin-bottom: -40px;
}
85%{
letter-spacing: 8px;
margin-bottom: -40px;
}
}
#keyframes second_text_anim {
from {
opacity: 0;
}
}
<div class="container">
<span class="first_text"> > First animation </span>
<span class="second_text"> > Second animation, Should be displayed at the end </span>
</div>
you can use animation-delay.
here the code that iterate the second text every 3s
also this value order is not correct:
animation:second_text_anim 1s 3s linear infinite;
in animation short method you must order value, like this example:
div {
animation-name: example;
animation-duration: 5s;
animation-timing-function: linear;
animation-delay: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
div {
animation: example 5s linear 2s infinite alternate;
}
so in your code you must use it like this:
animation:second_text_anim 3s linear 4s infinite;
*{
padding: 0;
margin: 0;
font-family: sans-serif;
}
body{
background:white;
}
.container{
text-align: center;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 100%;
}
.container{
text-transform: uppercase;
}
.first_text{
color: white;
font-size: 60px;
font-weight: 700;
letter-spacing: 8px;
margin-bottom: 20px;
background: black;
position: relative;
animation: first_text_anim 3s 1;
}
/* The second text should be displayed at the end of the first animation */
.second_text{
font-size: 30px;
color: darkcyan;
display: block;
opacity:0;
animation:second_text_anim 3s linear 4s infinite;
}
#keyframes first_text_anim {
0%{
color: black;
margin-bottom: -40px;
}
30%{
letter-spacing: 25px;
margin-bottom: -40px;
}
85%{
letter-spacing: 8px;
margin-bottom: -40px;
}
}
#keyframes second_text_anim {
50% {
opacity: 1;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Animation Text</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<span class="first_text"> > First animation < </span>
<span class="second_text"> > Second animation, Should be displayed at the end < </span>
</div>
</body>
</html>
I have a simple animation running on an element which loops moving a "star" element from place to place using absolute positioning. It fades in and out briefly using opacity before moving to the next location, then repeating. This works fine in Chrome and Firefox, but of course IE/Edge is having issues. It can best be seen here: Codepen
Issue: In IE/Edge the animation runs correctly through the first iteration, but as soon as the animation starts looping, the opacity and absolute position changes get out of sync to the point where the "star" is fading in/out WHILE it's moving which shouldn't be the case. Chrome shows the ideal animation steps: Fade In, Fade out, Move, Stop, Repeat.
Here's the code:
#import url(https://fonts.googleapis.com/css?family=Mr+Dafoe);
#-webkit-keyframes star-effect {
0% {
left: -7%;
top: 44%;
opacity: 0;
}
5% {
opacity: 1;
}
10% {
left: -7%;
top: 44%;
opacity: 0;
}
35% {
left: 44%;
top: 0%;
opacity: 0;
}
40% {
opacity: 1;
}
45% {
left: 44%;
top: 0%;
opacity: 0;
}
70% {
left: 90%;
top: 6%;
opacity: 0;
}
75% {
opacity: 1;
}
80% {
left: 90%;
top: 6%;
opacity: 0;
}
100% {
left: -7%;
top: 44%;
opacity: 0;
}
}
body{
background: #000;
margin: 0;
padding: 50px;
font-size: 16px;
width: 100%;
font-family: "Helvetica Neue",helvetica,Arial,sans-serif;
overflow-x: hidden;
}
h1{
position: relative;
height: 1.35em;
line-height: 1;
font-size: 10rem;
margin: 0;
transition: font-size .2s linear;
}
h1 > span:nth-child(1){
position: absolute;
padding-left: 30px;
padding-right: 50px;
top: 0px;
font-family: 'Mr Dafoe', cursive;
font-size: .87em;
margin-top: 0px;
margin-bottom: 0;
color: #fd5afa;
text-shadow: -2px -2px 0 #FFBAF2;
-webkit-filter: drop-shadow(3px 3px 1px #441F62);
-webkit-transform: skew(-5deg,-5deg);
font-weight: normal;
z-index: 2;
-webkit-backface-visibility: hidden;
}
h1 span.star{
position: absolute;
display: block;
left: -7%;
top: 44%;
width: 80px;
height: 80px;
z-index: 4;
opacity: 0;
-webkit-animation-name: star-effect;
animation-name: star-effect;
-webkit-animation-duration: 6s;
animation-duration: 6s;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
}
h1 span.star:before{
position: absolute;
content: '';
background-image: -webkit-radial-gradient(#fff 20%, transparent 80%);
width: 100%;
height: 2px;
display: block;
top: 50%;
}
h1 span.star:after{
position: absolute;
content: '';
background-image: -webkit-radial-gradient(#fff 0%, transparent 90%);
width: 2px;
height: 100%;
display: block;
left: 50%;
}
<body>
<h1>
<span>Word<span class="star"></span></span>
</h1>
</body>
Hi I have a problem trying to getting the animation at the left hand side of the button when user mouse over the button. One of the example that explain as below:
HTML:
<div class="block">
<div class="normal">
<span>Follow me...</span>
</div>
<a target="_BLANK" class="hover" href="http://twitter.com/benoitboucart" title="My twitter profile">
on Twitter
</a>
CSS:
/**
* CSS3 balancing hover effect
* Read the tutorial here: http://webbb.be/blog/little-css3-3d-hover-effects/
*/
body {background: #f06;background: linear-gradient(45deg, #f06, yellow);min-height: 100%;}
.block {
width: 150px; color: #fff; margin: 30px auto; text-transform: uppercase; text-align: center; font-family: Helvetica;
position: relative;
perspective: 350;
}
.block .normal {
background: gray; padding: 15px; cursor: pointer;
position:relative; z-index:2;
}
.block .hover {
background: #00aced; margin-top:-48px; padding: 15px; display: block; color: #fff; text-decoration: none;
position: relative; z-index:1;
transition: all 250ms ease;
}
.block:hover .normal {
background: #0084b4;
}
.block:hover .hover {
margin-right: 0;
transform-origin: top;
/*
animation-name: balance;
animation-duration: 1.5s;
animation-timing-function: ease-in-out;
animation-delay: 110ms;
animation-iteration-count: 1;
animation-direction: alternate;
*/
animation: balance 1.5s ease-in-out 110ms 1 alternate;
}
#keyframes balance {
0% { margin-top: 0; }
15% { margin-top: 0; transform: rotateX(-50deg); }
30% { margin-top: 0; transform: rotateX(50deg); }
45% { margin-top: 0; transform: rotateX(-30deg); }
60% { margin-top: 0; transform: rotateX(30deg); }
75% { margin-top: 0; transform: rotateX(-30deg); }
100% { margin-top: 0; transform: rotateX(0deg);}
}
https://jsfiddle.net/9dwk8vzg/
Original link:http://dabblet.com/gist/5559193
But for this example is at the bottom instated of at the left hand side of the button, I tried using margin-right and padding-left still unable to get the mouse over appeal div tag to be on the right hand side, may I know what do I miss to get the div tag to appeal on the right hand side/
/**
* CSS3 balancing hover effect
* Read the tutorial here: http://webbb.be/blog/little-css3-3d-hover-effects/
*/
body {background: #f06;background: linear-gradient(45deg, #f06, yellow);min-height: 100%;}
.block {
width: 150px; color: #fff; margin: 30px auto; text-transform: uppercase; text-align: center; font-family: Helvetica;
position: relative;
perspective: 350;
}
.block .normal {
width: 100%;
background: gray; padding: 15px; cursor: pointer;
position:relative; z-index:2;
}
.block .hover {
width: 100%;
background: #00aced;
padding: 15px;
display: block;
position:absolute;
color: #fff;
text-decoration: none;
z-index:1;
transition: all 250ms ease;
right: -30px;
top: 0;
}
.block:hover .normal {
background: #0084b4;
}
.block:hover .hover {
right: 100%;
transform-origin: top;
/*
animation-name: balance;
animation-duration: 1.5s;
animation-timing-function: ease-in-out;
animation-delay: 110ms;
animation-iteration-count: 1;
animation-direction: alternate;
*/
animation: balance 1.5s ease-in-out 110ms 1 alternate;
}
#keyframes balance {
15% { width: 95%; }
30% { width: 105%; }
45% { width: 97%; }
60% { width: 103%; }
75% { width: 97%; }
100% { width: 100%; }
}
<div class="block">
<div class="normal">
<span>Follow me...</span>
</div>
<a target="_BLANK" class="hover" href="http://twitter.com/benoitboucart" title="My twitter profile">
on Twitter
</a>
</div>
Im struggling a bit with this project that I am working on. Essentially I have a chat interface built in angular, im having a problem getting the CSS styling right. At the moment the chat starts at the top, then scrolls down off the screen as the conversation grows. I can scroll with the conversation but this isnt very good UX.
I am trying to make it so the 'Send Message' box starts in the bottom third of the screen and is fixed. Then, as the conversation grows, the messages move upwards/away instead of downwards. Ideally I want this in a container that disappears (behind a header, etc).
I've been trying to wrap my brain around this for the past few days with not much luck. CSS isnt really a strong point of mine. Any help would be greatly appreciated
CSS & Image of current setup below (there is also a separate styling sheet but this is only for the button/message stylings:
<body><style>
body { background: #FFFFFF; color: #727272; }
h1, h2, h3, h4, { background: #FFFFFF; color: #212121; } body { background: #FFFFFF; color: #727272; }
html, body, form, strong, button, small, input, p, div, h1, h2, h3, h4
{ outline: 0; margin: 0; padding: 0; border: 0; font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; line-height: 1.4em; font-size: 100%; } !important;
a, a:active
{ color: #F8F8F8; text-decoration: none; }
a:hover { text-decoration: underline; }
button,
a { cursor: pointer; } strong { font-weight: 500; }
p, h1, h2, h3, h4 { margin-top: 1em; margin-bottom: 1em; }
h1, h2, h3, h4 { font-weight: 200; font-size: 32px; }
html, body, p, div { font-weight: 200; font-size: 17px; } .clear { clear: both }
.container { padding-right: 7vw; padding-left: 7vw; margin-right: auto; margin-left: auto; height: 100vh; }
</style><style>
/* .header { overflow: hidden; position: relative; min-height: 100vh; padding-bottom: 0vh; text-align: center; color: #F8F8F8; background: linear-gradient( to left, rgba(122,214,184,0.0) 0%, rgba(122,214,184,0.7) 100% ), linear-gradient( to bottom, rgb(60,240,80) 0%, rgb(122,214,184) 100% ); } */
.header { overflow: hidden; position: relative; min-height: 100vh; padding-bottom: 0vh; text-align: center; color: #F8F8F8; background: linear-gradient( to left, rgba(204,52,148,0.0) 0%, rgba(239,45,86,0.7) 100% ), linear-gradient( to bottom, rgb(204,52,148) 0%, rgb(204,52,148) 100% ); }
input::-webkit-input-placeholder { color: rgba(200,255,255,0.5) !important; } .header .signup { margin-top: 4em; } .header
input { background: transparent; color: #F8F8F8; border: 0; border-bottom: 1px solid rgba(255,255,255,0.8); line-height: 2em; font-size: 1.4em; text-align: center; width: 12em; }
/* .angularjs-chat-bubble-white { position: absolute; display: inline-block; background: transparent url(https://i.imgur.com/3Sdc2xD.png); background-size: 100%; background-repeat: no-repeat; } */
.bothello-bubble { position: absolute; display: inline-block; background: transparent url(https://i.imgur.com/kN9kf2o.png); background-size: 100%; background-repeat: no-repeat; }
.header .bubble-one { top: 15vh; left: 10vw; width: 30px; height: 30px; opacity: 0.1; transform-origin: 70% 400%; animation: bubble-move 3s ease-in-out 0s infinite alternate; }
.header .bubble-two { top: 44vh; left: 6vw; width: 100px; height: 100px; opacity: 0.1; transform-origin: 60% 400%; animation: bubble-move 4s ease-in-out 0s infinite alternate; }
.header .bubble-three { top: 75vh; left: 22vw; width: 20px; height: 20px; opacity: 0.2; transform-origin: 30% 120%; animation: bubble-move 2s ease-in-out 0s infinite alternate; }
.header .bubble-four { top: 14vh; left: 28vw; width: 15px; height: 15px; opacity: 0.1; transform-origin: 20% 400%; animation: bubble-move 2s ease-in-out 0s infinite alternate; }
.header .bubble-five { top: 30vh; left: 66vw; width: 14px; height: 14px; opacity: 0.2; transform-origin: 90% 100%; animation: bubble-move 5s ease-in-out 0s infinite alternate; }
.header .bubble-six { top: 8vh; left: 75vw; width: 23px; height: 23px; opacity: 0.2; transform-origin: 80% 200%; animation: bubble-move 2s ease-in-out 0s infinite alternate; }
.header .bubble-seven { top: 33vh; left: 84vw; width: 120px; height: 120px; opacity: 0.2; transform-origin: 100% 90%; animation: bubble-move 6s ease-in-out 0s infinite alternate; }
.header .bubble-eight { top: 72vh; left: 85vw; width: 360px; height: 360px; opacity: 0.2; transform-origin: -100% 100%; animation: bubble-move 7s ease-in-out 0s infinite alternate; }
/* .messagebox { padding-top: 90vh; position: fixed;} */
#keyframes bubble-move { 0% { opacity: 0.6; transform: scale(1.0) rotate(-8deg) translate(-1px,-2px); } 70% { opacity: 0.3; transform: scale(1.04) rotate(10deg) translate(2px,1px); } 100% { opacity: 0.4;
transform: scale(0.94) rotate(-18deg) translate(-3px,-1px); } }
</style>
<div class="header">
<!-- <div class="container"> -->
<div class="bothello-bubble bubble-one"></div>
<div class="bothello-bubble bubble-two"></div>
<div class="bothello-bubble bubble-three"></div>
<div class="bothello-bubble bubble-four"></div>
<div class="bothello-bubble bubble-five"></div>
<div class="bothello-bubble bubble-six"></div>
<div class="bothello-bubble bubble-seven"></div>
<div class="bothello-bubble bubble-eight"></div>
<div class="container">
<ng-container *ngFor="let message of messages | async">
<div class="message" [ngClass]="{ 'from': message.sentBy === 'bot',
'to': message.sentBy === 'user' }">
{{ message.content }}
</div>
</ng-container>
<div class="messagebox">
<label for="nameField">Your Message</label>
<input [(ngModel)]="formValue" (keyup.enter)="sendMessage()" type="text">
<button (click)="sendMessage()">Send</button>
</div>
<!-- </div> -->
</div>
</div>
</body>
Thanks so much.
Jay
You're looking for:
.container {
display: flex;
flex-direction: column;
}
.container>ng-container {
flex-grow: 1;
overflow: auto;
}
.container>.messagebox {
flex-shrink: 0;
margin-bottom: 3px;
}
You'll also need a small function to scroll <ng-container> to bottom whenever a message gets added to chat, something along these lines:
function scrollToBottom() {
let elem = document.querySelector('ng-container');
elem.scrollTop = elem.scrollHeight;
}
I don't know for sure what are best practices for manipulating DOM nodes in Angular2 (and above) and if there are any favored techniques over .querySelector.
Also note .querySelector can (and should) be used on any DOM node, so you probably want to use it on your ViewContainer rather than on the entire document.
But, since you haven't posted anything related to the JS part, I can't help you more there.