I am studying CSS animation. I want my animation moving one by one, as I don't know JS I want to do it by CSS only. How can I do this? I faced the problem of rules from and to in animations, when I change them the animations don't work as expected.
I have the following HTML
body {
margin: 0;
background: grey;
}
main {
font-family: Open Sans;
text-transform: uppercase;
line-height: 1;
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
background: transparent;
}
.animation {
width: 20em;
height: 4em;
margin: 1em auto;
position: relative;
}
.squares {
margin: auto;
background: red;
/* display: flex;
flex-wrap: wrap;
justify-content: center;*/
}
.small_square {
width: 10px;
height: 10px;
background-color: white;
text-align: center;
display: block;
text-align: center;
position: relative;
margin: 0;
padding: 0;
left: 48%;
animation: appearance_small 1s ease-in-out;
animation: move_around 3s ease-in-out;
*/
}
.big_square {
margin: auto;
width: 40px;
height: 40px;
background-color: black;
display: block;
position: relative;
top: 30px;
animation: appearance_big 1.3s ease-in-out;
animation-delay: 2s;
animation: spin 3s ease-in-out;
forwards;
}
#keyframes appearance_big {
0% {
transform: scale(0%);
}
100% {
opacity: 1;
}
}
#keyframes appearance_small {
0% {
opacity: 0;
transform: scale(0%);
top: 50px;
}
100% {
opacity: 1;
top: 0px;
}
}
#keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(180deg);
}
}
#keyframes move_around {
from {
transform: translate(50%, 50px) rotate(0turn) translate(-50%, -50px);
}
to {
transform: translate(50%, 50px) rotate(0.50turn) translate(-0%, -50px);
}
<main>
<div id="animation" class="animation">
<div class="squares">
<div class="small_square"></div>
<div class="big_square"></div>
</div>
</main>
I am very new to this and trying to animate my "rd" class but I can not figure out why it is not animating.
My final goal is when I scroll down to next page the items on the first page will fade out.
I would appreciate any help.
here what I got so far:
Codepen
.rd {
display: flex;
flex-direction: column;
justify-items: center;
align-items: center;
overflow: visible;
height: 100%;
opacity: 100%;
animation: RD 5s infinite;
}
#keyframes rd {
0% {
left: 0px; opacity:100%;
}
50% {
left: 200px; opacity:0%;
}
100% {
left: 0px; opacity:100%;
}
}
.crown {
height: 200px;
}
.heart {
position: relative;
transform: rotateZ(45deg);
animation: heart 1s infinite;
margin-top: -50px;
}
#keyframes heart {
0% {
height: 100px;
width: 100px;
}
50% {
height: 50px;
width: 50px;
}
100% {
height: 100px;
width: 100px;
}
}
<div id="fullpage">
<section class="vertical-scrolling">
<div class="rd">
<img class="crown" src="https://m.media-amazon.com/images/I/6176t0uwOEL._SL1200_.jpg" alt="crown" />
<img class="heart" src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f1/Heart_coraz%C3%B3n.svg/1920px-Heart_coraz%C3%B3n.svg.png">
</d>
</div>
</section>
</div>
There are two small things you are missing.
Both are in your .rd class properties
animation: RD 5s infinite;
Your keyframe is named rd with small letters, in your animation property you are using RD with uppercase letters. Both need to match, so either both lower case or uppercase
-> animation: rd 5s infinite;
left property needs position: relative | absolute
Your animation is doing a "left" position change. In order to change positions (top | left | bottom | right), your element need to be position: relative or position: absolute
In your case relative is enough
.rd {
display: flex;
flex-direction: column;
justify-items: center;
align-items: center;
overflow: visible;
height: 100%;
opacity: 100%;
animation: rd 5s infinite;
position: relative;
}
#keyframes rd {
0% {
left: 0px;
}
50% {
left: 200px;
}
100% {
left: 0px;
}
}
.crown {
height: 200px;
}
.heart {
position: relative;
transform: rotateZ(45deg);
animation: heart 1s infinite;
margin-top: -50px;
}
#keyframes heart {
0% {
height: 100px;
width: 100px;
}
50% {
height: 50px;
width: 50px;
}
100% {
height: 100px;
width: 100px;
}
}
<div id="fullpage">
<section class="vertical-scrolling">
<div class="rd">
<img class="crown" src="https://m.media-amazon.com/images/I/6176t0uwOEL._SL1200_.jpg" alt="crown" />
<img class="heart" src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f1/Heart_coraz%C3%B3n.svg/1920px-Heart_coraz%C3%B3n.svg.png">
</d>
</div>
</section>
</div>
While building a loader icon, I noticed odd behavior in IE11 compared to Chrome, using this animation:
#keyframes loader-2 {
0% {
transform: translateX(0);
}
50% {
transform: translateX(-1.6rem);
}
100% {
transform: translateX(0);
}
}
The element correctly translates to the side at first, but then shifts super far before translating back. This only behaves this way in IE11 (works fine in Chrome/Firefox), and only on a pseudo-element (::after).
See this fiddle (or below code snippet) for an example. The top dot is a span, which works fine, the bottom dot is an ::after element, which behaves weirdly.
html {
font-size: 62.5%;
}
.splash {
align-items: center;
display: flex;
height: 100vh;
justify-content: center;
width: 100vw;
}
#keyframes loader-2 {
0% {
transform: translateX(0);
}
50% {
transform: translateX(-1.6rem);
}
100% {
transform: translateX(0);
}
}
.loader {
display: inline-block;
height: 3.2rem;
padding: 4rem 0;
position: relative;
width: 3.2rem;
border: 1px solid red;
}
.loader span {
animation: loader-2 1.5s ease infinite;
background: #024;
border-radius: 50%;
bottom: 0;
display: block;
height: 1.6rem;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0;
width: 1.6rem;
}
.loader div::after {
animation: loader-2 1.5s ease infinite;
background: #024;
border-radius: 50%;
bottom: 0;
content: '';
display: block;
height: 1.6rem;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 3.2rem;
width: 1.6rem;
}
<div class="splash">
<div class="loader">
<span></span>
<div></div>
</div>
</div>
I'm able to work around this by not using pseudo-elements of course, but I would still like to know what causes this issue.
Animation and transition for pseudo-elements is not supported by IE11, check here:
https://caniuse.com/#feat=mdn-css_selectors_after_animation_and_transition_support
To work around this issue, you can try to use ID for the div and write CSS for it and avoid using pseudo.
Modified code:
html {
font-size: 62.5%;
}
.splash {
align-items: center;
display: flex;
height: 100vh;
justify-content: center;
width: 100vw;
}
#keyframes loader-2 {
0% {
transform: translateX(0);
}
50% {
transform: translateX(-1.6rem);
}
100% {
transform: translateX(0);
}
}
.loader {
display: inline-block;
height: 3.2rem;
padding: 4rem 0;
position: relative;
width: 3.2rem;
border: 1px solid red;
}
.loader span {
animation: loader-2 1.5s ease infinite;
background: #024;
border-radius: 50%;
bottom: 0;
display: block;
height: 1.6rem;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0;
width: 1.6rem;
}
.loader #abc {
animation: loader-2 1.5s ease infinite;
background: #024;
border-radius: 50%;
bottom: 0;
content: '';
display: block;
height: 1.6rem;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 3.2rem;
width: 1.6rem;
}
<div class="splash">
<div class="loader">
<span></span>
<div id="abc"></div>
</div>
</div>
Output in IE 11 browser:
I'm trying to add text inside a pulsating dot.
Here's my current HTML (data inside h4 and p tags is dynamic)
<div class="pulsating-circle">
<h4>two lines title</h4>
<p>two lines of text</p>
</div>
And here's my CSS (scss) (https://jsfiddle.net/24cdn65x/):
.pulsating-circle {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
width: 232px;
height: 232px;
&:before {
content: '';
position: relative;
display: block;
width: 150%;
height: 150%;
box-sizing: border-box;
margin-left: -25%;
margin-top: -25%;
border-radius: 150%;
background-color: #ccc;
animation: pulse-ring 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}
&:after {
content: '';
position: absolute;
left: 0;
top: 0;
display: block;
width: 100%;
height: 100%;
border-radius: 232px;
background-color: #ccc;
animation: pulse-dot 1.25s cubic-bezier(0.455, 0.03, 0.515, 0.955) -.4s infinite;
}
}
The problem is that I'm not being able to properly locate the text inside the div.
I've tried wrapping the pulsating circle on a relative div and also the content inside the pulsating circle inside a relative div.
Here's an example of what I'm trying to achieve
I hope someone can help me
Just give the text div a z-index of 1 and an absolute position:
.pulsating-circle {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
width: 232px;
height: 232px;
}
.pulsating-circle:before {
content: '';
position: relative;
display: block;
width: 150%;
height: 150%;
box-sizing: border-box;
margin-left: -25%;
margin-top: -25%;
border-radius: 150%;
background-color: #ccc;
animation: pulse-ring 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}
.pulsating-circle:after {
content: '';
position: absolute;
left: 0;
top: 0;
display: block;
width: 100%;
height: 100%;
border-radius: 232px;
background-color: #ccc;
animation: pulse-dot 1.25s cubic-bezier(0.455, 0.03, 0.515, 0.955) -0.4s infinite;
}
.text{
position: absolute;
top: 68px;
left: 90px;
z-index: 1;
}
#keyframes pulse-ring {
0% {
transform: scale(0.33);
}
80%, 100% {
opacity: 0;
}
}
#keyframes pulse-dot {
0% {
transform: scale(0.8);
}
50% {
transform: scale(1);
}
100% {
transform: scale(0.8);
}
}
<div class="first-color pulsating-circle">
<div class="text">
<h4>test title</h4>
<p>text text</p>
</div>
</div>
Alright, this is what I came up with. Looks to be completely dynamic, as long as you don't put in an insane amount of copy. Setting the parent div pulsating-circle to position:relative, and simply aligning it via margin will give you way more leeway when trying to center your text. After this, you can put your content in its own div and set its position to absolute, therefor using the parents height as the determining factor.
<div class="first-color pulsating-circle">
<div class="first-text">
<h4>test title that cant test title that cant</h4>
<p>texttext text text text text</p>
</div>
</div>
.pulsating-circle {
position: relative;
margin: 0 auto;
margin-top: 100px;
width: 232px;
height: 232px;
}
.first-text {
position: absolute;
right: 0;
left: 0;
text-align: center;
z-index: 2;
font-family: sans-serif;
color: white;
display: inline-block;
top: 50%;
transform: translateY(-50%);
}
https://jsfiddle.net/yjtqenz0/16/
Sorry for the jumbled properties!
If you need to use the html you have then you can do this:
<div class="pulsating-circle">
<h4>Here is a Header</h4>
<p>two lines of text two lines of text</p>
</div>
.pulsating-circle {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
width: 232px;
height: 232px;
border-radius: 232px;
background-color: #ccc;
animation: pulse-dot 1.25s cubic-bezier(0.455, 0.03, 0.515, 0.955) -.4s infinite;
}
.pulsating-circle h4{
position: absolute;
top: 25%;
left: 30%;
z-index: 1;
}
.pulsating-circle p{
position: absolute;
top: 40%;
left: 30%;
width: 150px;
z-index: 1;
}
https://jsfiddle.net/wpybjdks/
Here's a version that allows for some dynamic text and centers the h4 and p vertically/horizontally. I added a class to the inner div (.inner) to target it a little easier in the CSS.
A fiddle to play with:
https://jsfiddle.net/fgyovexw/
.pulsating-circle {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
width: 232px;
height: 232px;
text-align: center;
z-index: 1;
}
.pulsating-circle:before {
content: '';
position: absolute;
display: block;
width: 150%;
height: 150%;
box-sizing: border-box;
margin-left: -25%;
margin-top: -25%;
border-radius: 150%;
background-color: #ccc;
animation: pulse-ring 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}
.pulsating-circle:after {
content: '';
position: absolute;
left: 0;
top: 0;
display: block;
width: 100%;
height: 100%;
border-radius: 232px;
background-color: #ccc;
animation: pulse-dot 1.25s cubic-bezier(0.455, 0.03, 0.515, 0.955) -0.4s infinite;
}
.inner {
position: relative;
z-index: 5;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 140px;
}
.inner>h4 {
margin-top: 0;
}
.inner>p {
margin-bottom: 0;
}
#keyframes pulse-ring {
0% {
transform: scale(0.33);
}
80%,
100% {
opacity: 0;
}
}
#keyframes pulse-dot {
0% {
transform: scale(0.8);
}
50% {
transform: scale(1);
}
100% {
transform: scale(0.8);
}
}
<div class="first-color pulsating-circle">
<div class="inner">
<h4>long text here for title content</h4>
<p>text text text text text and more text</p>
</div>
</div>
Are you expecting like this:
body {
position: relative;
margin: 0;
height: 100vh;
background: linear-gradient(180deg, white 50%, #f2f2f2 50%) no-repeat;
display: flex;
align-items: center;
justify-content: center;
}
.pulsating-circle {
position: relative;
width: 232px;
height: 232px;
}
.pulsating-circle div {
display: flex;
flex-direction: column;
align-items: center;
height: inherit;
color: white;
justify-content: center;
position: relative;
z-index: 2;
}
.pulsating-circle:before {
content: '';
position: absolute;
display: block;
width: 200%;
height: 200%;
box-sizing: border-box;
margin-left: -50%;
margin-top: -50%;
border-radius: 150%;
background-color: #00BCDA;
animation: pulse-ring 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}
.pulsating-circle:after {
content: '';
position: absolute;
left: -25%;
top: -25%;
display: block;
width: 150%;
height: 150%;
border-radius: 232px;
background-color: #00BCDA;
animation: pulse-dot 1.25s cubic-bezier(0.455, 0.03, 0.515, 0.955) -0.4s infinite;
}
#keyframes pulse-ring {
0% {
transform: scale(0.33);
}
80%,
100% {
opacity: 0;
}
}
#keyframes pulse-dot {
0% {
transform: scale(0.8);
}
50% {
transform: scale(1);
}
100% {
transform: scale(0.8);
}
}
<div class="pulsating-circle">
<div>
<h4>Two lines title</h4>
<p>Two lines of text</p>
</div>
</div>
you can use this example:
.pulsating-circle {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
width: 232px;
height: 232px;
text-align: center;
z-index: 1;
}
.pulsating-circle:before {
content: '';
position: absolute;
display: block;
width: 150%;
height: 150%;
box-sizing: border-box;
margin-left: -25%;
margin-top: -25%;
border-radius: 150%;
background-color: #ccc;
animation: pulse-ring 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}
.pulsating-circle:after {
content: '';
position: absolute;
left: 0;
top: 0;
display: block;
width: 100%;
height: 100%;
border-radius: 232px;
background-color: #ccc;
animation: pulse-dot 1.25s cubic-bezier(0.455, 0.03, 0.515, 0.955) -0.4s infinite;
}
.text {
position: relative;
z-index: 5;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 140px;
}
.text > h4 {
margin-top: 0;
}
.text > p {
margin-bottom: 0;
}
#keyframes pulse-ring {
0% {
transform: scale(0.33);
}
80%, 100% {
opacity: 0;
}
}
#keyframes pulse-dot {
0% {
transform: scale(0.8);
}
50% {
transform: scale(1);
}
100% {
transform: scale(0.8);
}
}
<div class="first-color pulsating-circle">
<div class="text">
<h4>test title</h4>
<p>text text</p>
</div>
</div>
Here's a simple example of what I mean.
HTML
<div class="main-container">
<div class="ht-tx1"></div>
<div class="headtest"></div>
<div class="ht-tx2"></div>
</div>
CSS
.main-container {
width: 100%;
height: 200px;
margin: 250px 0 0 0;
position: relative;
background-color: yellow;
}
.headtest {
font-family: 'quicksand', helvetica;
background-color: #a2aba2;
width: 100%;
height: 200px;
position: absolute;
top: 0;
right: 0;
}
.ht-tx1 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani1 2s forwards;
position: absolute;
top: 0;
right: 0;
}
.ht-tx2 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani2 2s forwards;
position: absolute;
bottom: 0;
right: 0;
}
#keyframes test-ani1 {
100% {
transform: translateY(-20px);
}
}
#keyframes test-ani2 {
100% {
transform: translateY(20px);
}
}
-
If you view in Chrome, both black bars slide out perfectly. The one transitioning from behind, and the one in front.
If you view it in Firefox, the bar transitioning from behind is broken. It sometimes works, but mostly it ignores the slide animation and just appears at the end of the animation duration.
I've re-created this a number of times and it seems that items that transition from behind another element are broken in firefox.
I've tried using -moz- which doesn't work. IS there anything else you can think of?
I've tried it without the absolute positioning, with z-indexs. and nothing seems to work.
EDIT ----
I appreciate work-around ideas, but I'd really like to know the route cause of this if anyone knows?
Thanks very much.
It seems Firefox is inconsistent when animate the transform property, and I can't say why (yet), most likely a bug though.
Here is 2 workarounds to achieve the same effect
.main-container {
width: 100%;
height: 200px;
margin: 50px 0 0 0;
position: relative;
background-color: yellow;
}
.headtest {
font-family: 'quicksand', helvetica;
background-color: #a2aba2;
width: 100%;
height: 200px;
position: absolute;
top: 0;
right: 0;
}
.ht-tx1 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani1 2s forwards;
position: absolute;
top: 0;
right: 0;
}
.ht-tx2 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani2 2s forwards;
position: absolute;
bottom: 0;
right: 0;
}
#keyframes test-ani1 {
0% {
transform: translateY(-1px);
}
0.1% {
transform: translateY(0px);
}
100% {
transform: translateY(-20px);
}
}
#keyframes test-ani2 {
100% {
transform: translateY(20px);
}
}
<div class="main-container">
<div class="ht-tx1"></div>
<div class="headtest"></div>
<div class="ht-tx2"></div>
</div>
.main-container {
width: 100%;
height: 200px;
margin: 50px 0 0 0;
position: relative;
background-color: yellow;
}
.headtest {
font-family: 'quicksand', helvetica;
background-color: #a2aba2;
width: 100%;
height: 200px;
position: absolute;
top: 0;
right: 0;
}
.ht-tx1 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani1 2s forwards;
position: absolute;
top: 0;
right: 0;
}
.ht-tx2 {
width: 100%;
height: 0px;
text-align: center;
background-color: #000;
animation: test-ani2 2s forwards;
position: absolute;
bottom: 0;
right: 0;
}
#keyframes test-ani1 {
100% {
top: -20px;
}
}
#keyframes test-ani2 {
100% {
height: 20px;
bottom: -20px;
}
}
<div class="main-container">
<div class="ht-tx1"></div>
<div class="headtest"></div>
<div class="ht-tx2"></div>
</div>
The solution relies on the z-index property of your elements: if you don't specify it the elements lay out one on top of the others, following the flow of the HTML document, when their "position" is set to "absolute". So "ht-txt1" is underneath "headtest" and "ht-tx2" is on top of "headtest".
To correct this "ht-tx1" and "ht-tx2" should take a "z-index" value of -1, so they are hidden underneath "headtest".
As for FF compatibility you need to prefix your "transform" effect with -moz-, check http://caniuse.com/#feat=transforms2d for more details.
Here's the CSS style code:
.main-container {
width: 100%;
height: 200px;
margin: 250px 0 0 0;
position: relative;
background-color: yellow;
}
.headtest {
font-family: 'quicksand', helvetica;
background-color: #a2aba2;
width: 100%;
height: 200px;
position: absolute;
top: 0;
right: 0;
}
.ht-tx1 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani1 2s forwards;
position: absolute;
top: 0;
right: 0;
z-index: -1;
}
.ht-tx2 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani2 2s forwards;
position: absolute;
bottom: 0;
right: 0;
z-index: -1;
}
#keyframes test-ani1 {
100% {
-ms-transform: translateY(-20px);
-webkit-transform: translateY(-20px);
-moz-transform: translateY(-20px);
transform: translateY(-20px);
}
}
#keyframes test-ani2 {
100% {
-ms-transform: translateY(20px);
-webkit-transform: translateY(20px);
-moz-transform: translateY(20px);
transform: translateY(20px);
}
}