CSS animations transitioning from behind other elements broken in Firefox - html

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);
}
}

Related

Carousel Slide: İnsert Text and Link Adding for CSS and HTML

I'm new to HTML and CSS. I just made a carousel slide using HTML and CSS. And I want to insert text in the corners of this slide. I couldn't do that because whatever I tried didn't work. I'm also trying to redirect to a different page when clicking on this slide.
I'am sorry my English btw. I hope I could explain what I mean.
CSS and HTML of my slide:
.tech-slideshow {
height: 190px;
max-width: 2600px;
margin: 0;
position: relative;
overflow: hidden;
transform: translate3d(0, 0, 0);
}
.tech-slideshow > div {
height: 200px;
width: 2526px;
background: url(https://resmim.net/cdn/2022/10/22/OybOx.jpg);
position: absolute;
top: 0;
left: 0;
height: 100%;
transform: translate3d(0, 0, 0);
}
.tech-slideshow .mover-1 {
animation: moveSlideshow 40s linear infinite;
}
#keyframes moveSlideshow {
50% {
transform: translateX(-40%);
}
}
<div class="tech-slideshow">
<div class="mover-1"></div>
</div>
Here's a possible solution with absolute positioning:
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.tech-slideshow {
height: 190px;
max-width: 2600px;
position: relative;
overflow: hidden;
}
.tech-slideshow__link {
display: block;
width: 100%;
height: 100%;
}
.mover-1 {
width: 2526px;
background: url(https://resmim.net/cdn/2022/10/22/OybOx.jpg);
height: 100%;
animation: moveSlideshow 40s linear infinite;
}
.mover-1-text {
position: absolute;
padding: 0.5em 2em;
color: #fff;
background-color: #000;
font-size: 1.5rem;
}
.mover-1-text1 {
left: 10px;
top: 10px;
}
.mover-1-text2 {
left: 10px;
bottom: 10px;
}
.mover-1-text3 {
right: 10px;
bottom: 10px;
}
#keyframes moveSlideshow {
50% {
transform: translateX(-40%);
}
}
<div class="tech-slideshow">
<a href="#" class="tech-slideshow__link" target="_blank">
<div class="mover-1"></div>
<p class="mover-1-text mover-1-text1">Text</p>
<p class="mover-1-text mover-1-text2">Text</p>
<p class="mover-1-text mover-1-text3">Text</p>
</a>
</div>

IE11 Pseudo-element animation is not working properly

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:

Masking an object to make it appear as if it goes behind the item it's rotating around

I'm trying to make a 'dot' orbit around another object (circle) but due to the z-index the dot always appears above the circle it is meant orbiting around.
CodePen link: https://codepen.io/moy/pen/ROVZXd?editors=1100
Ideally the 2nd half of the animation would take place behind the object so it's not seen until it comes out the other side - is that possible?
I thought about fading out the object that is moving around but I don't think that would give a smooth/masked effect?
A bit stuck as to how I'd mask this area as I can't see a way the CSS would know it's meant to be hidden. I thought maybe I could change the z-index 50% though the animation it and reset it at 0%/100% but that doesn't appear to do anything.
Any ideas? Thanks in advance!
.earth {
background: white;
border: 1px solid black;
border-radius: 50%;
display: block;
height: 100px;
margin: 30px auto;
position: relative;
width: 100px;
z-index: 20;
}
.orbit {
border: 2px #eee transparent;
border-radius: 50%;
height: 140px;
margin: auto;
position: absolute;
top: -20px;
left: -20px;
transform: rotateZ(60deg) rotateY(60deg);
transform-style: preserve-3d;
width: 140px;
z-index: 10;
}
.orbit .moon {
animation: move ease-in-out infinite;
animation-duration: 2s;
background: black;
border-radius: 50%;
height: 15px;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 15px;
z-index: 10;
}
#keyframes move {
0% {
transform: rotateZ(-90deg) translateX(70px) rotateZ(90deg) rotateY(-70deg); z-index: 20;
}
50% {
z-index: -20;
}
100% {
transform: rotateZ(270deg) translateX(70px) rotateZ(-270deg) rotateY(-70deg); z-index: 20;
}
}
<div class="earth">
<div class="orbit">
<div class="moon"></div>
</div>
</div>
I seem to have solved this by adding a negative z-index to an animation applied to the parent .orbit
Link: https://codepen.io/moy/pen/wZdpRw?editors=1100
I initially applied this at 50% through the animation as that should be the furthest away the dot is before it comes back behind the larger circle. However this didn't work, setting it on 100% did work. Not entirely sure why but it seems to work!
The initial issue was due to the fact that you are applying z-index to the parent element and doing so it will impossible to make the child to move behind it (Why elements with any z-index value can never cover its child?) thus changin z-index is useless
Even if you remove the z-index from the parent you still have the transform that is also creating a stacking context making impossible to the child element to move behind so you cannot make the .moon to move behind the .earth.
The only way to do it (like you already noticed) is to remove z-index from the .earth to avoid the earth creating a stacking context and animate z-index of orbit to make the orbit AND the moon moving behind the earth (not only the moon).
Add some coloration to better see this:
.earth {
background: white;
border: 1px solid black;
border-radius: 50%;
display: block;
height: 100px;
margin: 60px auto;
position: relative;
width: 100px;
}
.orbit {
animation: hide ease-in-out infinite;
animation-duration: 2s;
background:red;
border-radius: 50%;
height: 140px;
margin: auto;
position: absolute;
top: -20px;
left: -20px;
transform: rotateZ(60deg) rotateY(60deg);
transform-style: preserve-3d;
width: 140px;
}
.orbit .moon {
animation: move ease-in-out infinite;
animation-duration: 2s;
background: black;
border-radius: 50%;
height: 15px;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 15px;
}
#keyframes move {
0% {
transform: rotateZ(-90deg) translateX(70px) rotateZ(90deg) rotateY(-70deg);
}
100% {
transform: rotateZ(270deg) translateX(70px) rotateZ(-270deg) rotateY(-70deg);
}
}
#keyframes hide {
0% {
z-index: 20;
}
100% {
z-index: -20;
}
}
<div class="earth">
<div class="orbit">
<div class="moon"></div>
</div>
</div>
Now if you add back z-index to earth it will stop working because of the stacking context:
.earth {
background: white;
border: 1px solid black;
border-radius: 50%;
display: block;
height: 100px;
margin: 60px auto;
position: relative;
width: 100px;
z-index:2;
}
.orbit {
animation: hide ease-in-out infinite;
animation-duration: 2s;
background:red;
border-radius: 50%;
height: 140px;
margin: auto;
position: absolute;
top: -20px;
left: -20px;
transform: rotateZ(60deg) rotateY(60deg);
transform-style: preserve-3d;
width: 140px;
}
.orbit .moon {
animation: move ease-in-out infinite;
animation-duration: 2s;
background: black;
border-radius: 50%;
height: 15px;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 15px;
}
#keyframes move {
0% {
transform: rotateZ(-90deg) translateX(70px) rotateZ(90deg) rotateY(-70deg);
}
100% {
transform: rotateZ(270deg) translateX(70px) rotateZ(-270deg) rotateY(-70deg);
}
}
#keyframes hide {
0% {
z-index: 20;
}
100% {
z-index: -20;
}
}
<div class="earth">
<div class="orbit">
<div class="moon"></div>
</div>
</div>
You can try key-framing the opacity:
.earth {
background: white;
border: 1px solid black;
border-radius: 50%;
display: block;
height: 100px;
margin: 30px auto;
position: relative;
width: 100px;
z-index: 20;
}
.orbit {
border: 2px #eee transparent;
border-radius: 50%;
height: 140px;
margin: auto;
position: absolute;
top: -20px;
left: -20px;
transform: rotateZ(60deg) rotateY(60deg);
transform-style: preserve-3d;
width: 140px;
z-index: 10;
}
.orbit .moon {
animation: move ease-in-out infinite;
animation-duration: 2s;
background: black;
border-radius: 50%;
height: 15px;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 15px;
z-index: 10;
}
#keyframes move {
0% {
transform: rotateZ(-90deg) translateX(70px) rotateZ(90deg) rotateY(-70deg); opacity: 1;
}
56% {
opacity: 1;
}
58% {
opacity: 0;
}
77% {
opacity: 0;
}
78% {
opacity: 1;
}
100% {
transform: rotateZ(270deg) translateX(70px) rotateZ(-270deg) rotateY(-70deg); opacity: 1;
}
}
<div class="earth">
<div class="orbit">
<div class="moon"></div>
</div>
</div>

Button border on hover moves the text inside

I have created a border-like keyframe CSS style. When I hover the button the border-like animation should start from top-right to top-left then to bottom-left then after to bottom-right and finally to top-right again. When I hover the button the previous sequence should happen and is already created. However; when hovered, the text inside the button moves, which makes the button looks weird.
I looked at the answer to this question, but it's not applicable in my case as I am not using border styling on hover. Instead, I am changing the background color, width, and height of the three spans, not borders.
How can I prevent this shake with the method the animation is created?
CodePen: https://codepen.io/Tes3awy/pen/ZZRpBW
HTML
<div class="wrapper">
<a class="custom-btn" href="https://mince.34way.com/about/" title="About">
About Us
<span class="border-top"></span>
<span class="border-right"></span>
<span class="border-bottom"></span>
<span class="border-left"></span>
</a>
</div>
CSS
body {
position: relative;
height: 100vh;
}
.wrapper {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.custom-btn {
position: relative;
width: 183px;
height: 55px;
line-height: 55px;
display: inline-block;
text-align: center;
text-transform: uppercase;
margin: 0 auto;
border: 2px solid #77a942;
color: #77a942;
text-decoration: none;
}
span[class^="border-"] {
opacity: 0;
}
.border-top {
position: absolute;
top: -2px;
right: 0;
width: 100%;
height: 3px;
background-color: transparent;
}
.border-left {
position: absolute;
top: 0;
left: -2px;
width: 3px;
height: 100%;
background-color: transparent;
}
.border-bottom {
position: absolute;
left: 0;
bottom: -2px;
width: 100%;
height: 3px;
background-color: transparent;
}
.border-right {
position: absolute;
bottom: 0;
right: -2px;
width: 3px;
height: 100%;
background-color: transparent;
}
.custom-btn:hover .border-top {
animation: animateTop .2s 1 alternate ease forwards;
}
.custom-btn:hover .border-left {
animation: animateLeft .2s 1 alternate ease forwards;
animation-delay: .2s;
}
.custom-btn:hover .border-bottom {
animation: animateBottom .2s 1 alternate ease forwards;
animation-delay: .4s;
}
.custom-btn:hover .border-right {
animation: animateRight .2s 1 alternate ease forwards;
animation-delay: .6s;
}
#keyframes animateTop {
0% {
width: 0;
height: 0;
opacity: 0;
background-color: #77a942;
}
50% {
width: 50%;
height: 3px;
opacity: 1;
background-color: #77a942;
}
100% {
width: 100%;
height: 3px;
opacity: 1;
background-color: #77a942;
}
}
#keyframes animateLeft {
0% {
width: 0;
height: 0;
opacity: 0;
background-color: #77a942;
}
50% {
width: 3px;
height: 50%;
opacity: 1;
background-color: #77a942;
}
100% {
width: 3px;
height: 100%;
opacity: 1;
background-color: #77a942;
}
}
#keyframes animateBottom {
0% {
width: 0;
height: 0;
opacity: 0;
background-color:#77a942;
}
50% {
width: 50%;
height: 3px;
opacity: 1;
background-color:#77a942;
}
100% {
width: 100%;
height: 3px;
opacity: 1;
background-color:#77a942;
}
}
#keyframes animateRight {
0% {
width: 0;
height: 0;
opacity: 0;
background-color: #77a942;
}
50% {
width: 3px;
height: 50%;
opacity: 1;
background-color: #77a942;
}
100% {
width: 3px;
height: 100%;
opacity: 1;
background-color: #77a942;
}
}
When you translate things by 50%, they may end up in-between pixels. When you use a transition, CSS tends to change its mind on what pixel it rounds to. Try to make sure that the button you're centering text in has height/width that CSS has a definite position it can settle on when you divide it by half.

CSS3 animations not in sync on IE/Edge

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>