Safari falsely triggering css3 animation - css

I've tried to make some minor animations on an image, while it's loading, and when a user is hovering it, but there seems to be an issue when it comes to Safari.
When I hover the "a" tag, which should just trigger a "transition animation" it seems trigger the "loadImg" animation, even though it doesn't seem to be very related to each other. It's tested in Chrome, IE, Edge, Firefox and Opera, and it works fine there.
This the the code I find the most relevant to the issue.
<div class="playerInfo">
<div class="avatarName">
<a href="http://steamcommunity.com/profiles/76561198064550827" target="_blank" title="Click to see Magn0053's profile">
<img src="https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/5d/5d8a752dfea20299845bcd57d64ce04125d02d67_full.jpg" alt="Player avatar">
</a>
<figcaption class="playerName">Magn0053</figcaption>
</div>
</div>
and the css
.playerInfo img {
-webkit-animation: 1s loadImg;
position: relative;
transition: 0.3s linear;
width: 184px;
height: 184px;
top: 0px;
left: 0px;
}
.playerInfo a:hover img{
height:175px;
width:175px;
left:4.5px;
top:4.5px;
position: absolute;
}
I also have an example at https://jsfiddle.net/xhjppg93/.

As a rule of thumb, always use transform scale instead of changing width and height when dealing with transitions. This is because it will be gpu accelerated and it'll work a lot better for mobiles. :) Here's a quick fix for you.
.playerInfo {
width: 184px;
height: 227px;
margin: 0 5px;
}
.avatarName {
height: 206px;
position: relative;
}
.playerInfo a {
height: 184px;
width: 184px;
position: absolute;
left: 0;
top: 0;
border-radius: 10px;
margin: 0;
padding: 0;
}
.playerInfo img,
.playerInfo .imgReplacer {
border-radius: 10px;
margin: 0;
padding: 0;
}
.playerInfo img {
animation: 1s loadImg;
-webkit-animation: 1s loadImg;
-moz-animation: 1s loadImg;
-o-animation: 1s loadImg;
position: relative;
transition: 0.3s linear;
width: 184px;
height: 184px;
top: 0px;
left: 0px;
}
.playerInfo a:hover img {
transform: scale(0.95);
}
.playerName {
animation: 1s nameFix;
-moz-animation: 1s nameFix;
-webkit-animation: 1s nameFix;
-o-animation: 1s nameFix;
position: absolute;
bottom: 0;
}
#keyframes nameFix {
0% {
position: absolute;
bottom: 0;
}
100% {
bottom: 0;
position: absolute;
}
}
#keyframes loadImg {
0% {
height: 0px;
width: 0px;
left: 50%;
top: 50%;
position: absolute;
}
100% {
height: 184px;
width: 184px;
left: 0;
position: absolute;
top: 0;
}
}
<div class="playerInfo">
<div class="avatarName">
<a href="http://steamcommunity.com/profiles/76561198064550827" target="_blank" title="Click to see Magn0053's profile">
<img src="https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/5d/5d8a752dfea20299845bcd57d64ce04125d02d67_full.jpg" alt="Player avatar">
</a>
<figcaption class="playerName">Magn0053</figcaption>
</div>
</div>

Try these:
-webkit-transition: 0.3s linear;
-webkit-transition: -webkit-transform 0.3s linear;

Related

Nested pseudo elements ::before & ::after not working with #keyframes animation

I am trying to apply a cool "Glitch Effect" I saw in this video here:
However, I cannot seem to get this animation to work. Here is the heading element I am trying to apply the effect to:
<h1 class="header-block-heading-primary">Web Developer</h1>
Here is the SCSS:
.header-block-heading-primary {
// animation: glitch-effect 3s infinite;
position: relative;
&::before,
&::after {
position: absolute;
left: 0;
top: 0;
content: "";
display: block;
height: 100%;
width: 100%;
z-index: -1;
}
&::before {
color: red;
animation: glitch-effect 3s infinite;
}
&::after {
color: blue;
animation: glitch-effect 2s infinite;
}
}
Here is the animation:
#keyframes glitch-effect {
0% {
left: -3px;
top: -3px;
}
25% {
left: 3px;
top: 0px;
}
50% {
left: -2px;
top: 3px;
}
75% {
left: 2px;
top: -2px;
}
100% {
left: 0px;
top: -3px;
}
}
And here is the outputted CSS:
.header-block-heading-primary {
position: relative;
}
.header-block-heading-primary::before,
.header-block-heading-primary::after {
position: absolute;
left: 0;
top: 0;
content: "";
display: block;
height: 100%;
width: 100%;
z-index: -1;
}
.header-block-heading-primary::before {
color: red;
-webkit-animation: glitch-effect 3s infinite;
animation: glitch-effect 3s infinite;
}
.header-block-heading-primary::after {
color: blue;
-webkit-animation: glitch-effect 2s infinite;
animation: glitch-effect 2s infinite;
}
I have followed the same setup as the tutorial, and even referenced some old projects of mine looking at the use of ::before and ::after and they work just fine with the practically the same code (for the pseudo elements).
I have tried just single semi-colon, so :before & :after, and that did not work. I added the animation directly to the element itself (as seen by the commented out // animation: glitch-effect 3s infinite; underneath the .header-block-heading-primary selector), and it works fine so I'm being led to believe the ::before and ::after elements are not working. Also manually adding -webkit- in the nested SCSS did not work either.
I have looked at multiple other posts here on the site and could not find a answer that helped me solve this problem. So any help with this would be greatly appreciated!
your animations is working but you need to set ::after and ::before content:"Web Developer". you can show the effect in snippet.
.header-block-heading-primary {
position: relative;
}
.header-block-heading-primary::before,
.header-block-heading-primary::after {
position: absolute;
left: 0;
top: 0;
content: "Web Developer";
display: block;
height: 100%;
width: 100%;
z-index: -1;
}
.header-block-heading-primary::before {
color: red;
animation: glitch-effect 3s infinite;
}
.header-block-heading-primary::after {
color: blue;
animation: glitch-effect 2s infinite;
}
#keyframes glitch-effect {
0% {
left: -3px;
top: -3px;
}
25% {
left: 3px;
top: 0px;
}
50% {
left: -2px;
top: 3px;
}
75% {
left: 2px;
top: -2px;
}
100% {
left: 0px;
top: -3px;
}
}
<h1 class="header-block-heading-primary">Web Developer</h1>
this is the sass code this is working in my page please try this code.
.header-block-heading-primary {
position: relative;
&::before,
&::after {
position: absolute;
left: 0;
top: 0;
content: "Web Developer";
display: block;
height: 100%;
width: 100%;
z-index: -1;
}
&::before {
color: red;
animation: glitch-effect 3s infinite;
}
&::after {
color: blue;
animation: glitch-effect 2s infinite;
}
}
#keyframes glitch-effect {
0% {
left: -3px;
top: -3px;
}
25% {
left: 3px;
top: 0px;
}
50% {
left: -2px;
top: 3px;
}
75% {
left: 2px;
top: -2px;
}
100% {
left: 0px;
top: -3px;
}
}
Thank you.
I got it! The background image for the header section was conflicting with the ::before and ::after, so I just need to add a higher z-index to the heading and it works!
.header-block-heading-primary {
position: relative;
z-index: 20;
&::before {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
content: "Web Developer";
z-index: -1;
}
&::after {
content: "Web Developer";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
}
&::before {
color: #ff00c1;
animation: glitch-effect 3s infinite;
}
&::after {
color: #3498db;
animation: glitch-effect 2s infinite;
}
&:hover::before {
animation: glitch-effect 1s infinite;
}
&:hover::after {
animation: glitch-effect 2s infinite;
}
}

Stopping a margin transition at its initial point

Alright, here's what I have a nifty little scroller (they've been done to death but I wanted to take my hand at making one) and I want it to scroll to the left for X amount of pixels, which is no problem. The problem is, if the user hovers over the left side and starts scrolling the text back, I want it to stop at its initial starting point.
body {
background-color: black;
}
.wrapper {
position: absolute;
left: 50%;
margin-left: -250px;
overflow: hidden;
width: 500px;
height: 300px;
z-index: 98;
border: 3px solid 2a3439;
background-color: #353839;
}
.scroller {
color: white;
width: 1980px;
background-color: transparent;
height: 100%;
position: relative;
padding: 5px;
margin-left: 0px;
transition: all 2s linear 10s;
-moz-transition: all 2s linear 10s;
-webkit-transition: all 2s linear 10s;
}
.go-left:hover~.scroller {
margin-left: -250px;
transition: all 2s linear;
-moz-transition: all 2s linear;
-webkit-transition: all 2s linear ;
}
.go-left {
opacity: 0;
height: 300px;
background-color: red;
width: 200px;
z-index: 99;
position: absolute;
top: 0;
}
.go-right {
opacity: 0;
height: 300px;
background-color: red;
width: 200px;
z-index: 99;
position: absolute;
top: 0;
left: 300px
}
.go-right:hover+.scroller {
margin-left: 250px;
transition: all 2s linear;
-moz-transition: all 2s linear;
-webkit-transition: all 2s linear;
}
.image {
display: block;
overflow: hidden;
Height: 490px;
}
In that example, if you hover to the left I don't want it to move past it's starting point, so clamping it. You can see the working model on jsfiddle https://jsfiddle.net/Kaanha/puy6t4og/51/
This wouldn't be hard using some java, but the main thing here is, I need it to be pure CSS only. No java.
Thanks in advance for all help!

Strike in and out animation on hover

I'm trying to make a strikethrough animation like the effect here:
The strike line appears from left to right and disappears from left to right.
#keyframes strike {
0% {
width: 0;
}
50% {
width: 100%;
}
100% {
width: 0;
}
}
.strike {
position: relative;
}
.strike:hover:after {
content: ' ';
position: absolute;
top: 50%;
left: 0;
width: 100%;
height: 1px;
background: black;
animation-name: strike;
animation-duration: 1s;
animation-timing-function: linear;
animation-iteration-count: 1;
animation-fill-mode: fill;
animation-direction: normal;
}
<div>
The text in the span <span class="strike">is what I want to strike out</span>.
</div>
Is there a way to achieve that only with CSS ?
You can use transforms and transform-origin in the keyframe animation to make strike-through apear from left to right and disapear from left to right.
The point is to scale the pseudo element on the X axis for 0 to 1 with a transform origin on the left then back to 0 with a transform origin on the right (similar to this hover effect see last example of the answer).
And here is an example with your markup :
#keyframes strike{
0% { transform-origin: 0% 50%;transform:scaleX(0); }
50% { transform-origin: 0% 50%;transform:scaleX(1); }
50.01% { transform-origin:100% 50%;transform:scaleX(1); }
100% { transform-origin:100% 50%;transform:scaleX(0); }
}
.strike {
position: relative;
}
.strike:hover:after {
content: ' ';
position: absolute;
top: 50%;
left: 0;
width: 100%;
height: 1px;
background: black;
animation: strike .75s ease-in-out forwards;
}
<div>
The text in the span <span class="strike">is what I want to strike out</span>.
</div>
Here is a sample using transition, where it on hover toggle left/right position.
.strike {
position: relative;
}
.strike::after {
content: ' ';
position: absolute;
top: 50%;
left: 0;
right: 100%;
height: 1px;
background: black;
}
.strike:hover::after {
right: 0;
left: 100%;
transition: right .5s .0s, left .5s .5s;
}
<div>
The text in the span <span class="strike">is what I want to strike out</span>.
</div>

CSS Transition Not Returning To Original Shape & Can't Click Multiple Times

Here's the CodePen.
The square changes to a circle as expected when it slides to the right, but when it returns back to the left, it stays a circle instead of changing to a square.
Also, I can only click the <a> once. If I try to click multiple times, it doesn't work.
Trying to do this with only CSS (if possible).
body {
margin-top: 30px;
background: gainsboro;
}
.container {
margin: auto;
width: 100%;
}
.path {
position: relative;
overflow: hidden;
width: 100%;
height: 80px;
x-background: white;
}
#keyframes ani {
0% {
left: 0;
}
50% {
left: 95%;
}
100% {
left: 0;
}
}
.shape:target {
border-radius: 50%;
transition: all .7s ease-in-out;
animation-name: ani;
animation-duration: 2s;
animation-direction: alternate;
animation-fill-mode: none;
}
.shape {
position: absolute;
left: 0;
background-color: slateblue;
width: 80px;
height: 80px;
display: block;
border-radius: none;
transition: border-radius .4s ease-out;
}
<div class="container">
<div class="path">
<span id="elem" class="shape"></span>
</div>
</div>
The closest you can get with just CSS is this, as far as I know:
body {
margin-top: 30px;
background: gainsboro;
}
.container {
margin: auto;
width: 100%;
}
.path {
position: relative;
overflow: hidden;
width: 100%;
height: 80px;
x-background: white;
}
#keyframes ani {
0% {
left: 0;
}
50% {
left: 95%;
}
100% {
left: 0;
}
}
.path a:focus .shape {
border-radius: 50%;
transition: all .7s ease-in-out;
animation-name: ani;
animation-duration: 2s;
animation-direction: alternate;
animation-fill-mode: none;
}
.shape {
position: absolute;
left: 0;
background-color: slateblue;
width: 80px;
height: 80px;
display: block;
border-radius: none;
transition: border-radius .4s ease-out;
}
<div class="container">
<div class="path">
<span id="elem" class="shape"></span>
</div>
</div>
The problem before was triggering the state with :target:. This is tough to debug with sites like Codepen or other embedded editors, since you can't see the hash change. Basically, clicking the link would append #elem to the URL, apply the :target styles to .shape, and stay like that until the hash changes.
This solution uses :focus, which gets you closer to your goal, but not all the way. To repeat the animation, you need to defocus/blur the circle, then click it again.
I'm usually all for CSS-only effects, but I'm pretty sure you'll need Javascript for this. Something as simple as applying a class on click, waiting 2 seconds, then removing the class would accomplish the same effect more reliably.

CSS: How to scale an image from the center instead of top-left

So my problem is that I have an image and I set its CSS to have a
max-width: 100%
which scales it at lower resolutions ( as will be seen in the fiddle below ). What I want is for the transition to take effect from the center of the image.
Currently; and from what I have seen from most the transitions I have done involving scale they expand from the top-left corner.
here is my fiddle: http://jsfiddle.net/Eolis/3ya98xh8/3/
Just replace width: 400px; with transform: scale(2,2) on :hover.
img {
width: 100%; max-width: 100%;
}
div {
position: absolute; left: 20%; top: 20%;
width: 250px;
transition: all 2s ease-in-out;
}
div:hover {
transform: scale(2,2)
}
<div>
<a href="http://photobucket.com/images/cat" target="_blank">
<img src="http://i583.photobucket.com/albums/ss278/campipr/coolcat.gif" border="0" alt="cat photo: cat coolcat.gif"/>
</a>
</div>
Add this to the div:hover:
transform: translateX(-25%) translateY(-25%);
Here is the Fiddle: http://jsfiddle.net/3ya98xh8/4/
Don't forget to set transform-origin
.current{
top: 0px;
left: 0px;
z-index: 2;
opacity: 1;
transform: scale(0.9, 0.9);
transition: opacity 1.6s ease-out 0s, transform 7.2s linear 0s;
transform-origin: center center;
animation: normal;
}
https://css-tricks.com/almanac/properties/t/transform-origin/
may as well throw my solution up in case it is helpful to anyone:
::CSS::
img {
width: 100%; max-width: 100%;
}
div {
position: absolute; left: 50%; top: 50%;
margin-left: -125px; margin-top: -100px;
width: 250px;
transition: all 2s ease-in-out;
}
div:hover {
margin-left: -200px; margin-top: -150px;
width: 400px;
}
::HTML::
<div>
<a href="http://photobucket.com/images/cat" target="_blank">
<img src="http://i583.photobucket.com/albums/ss278/campipr/coolcat.gif" border="0" alt="cat photo: cat coolcat.gif"/>
</a>
</div>
::Fiddle::
http://jsfiddle.net/Eolis/3ya98xh8/5/

Resources