I'm trying to switch images in a div every few seconds
the current code works, but there are 2 things that I want to change and I need your help for that:
The div resizes to the current image displaying in it, I want it to always use the size of the bigger image
I want to fade between the images instead of just switching
Thanks for reading, I hope you can help me.
This is what I got so far:
var imgIndex = 0;
setInterval(function() {
images[imgIndex].style.display = "none";
imgIndex++;
if (imgIndex >= images.length) {
imgIndex = 0;
}
images[imgIndex].style.display = "block";
}, 5000);
.imageDisplay {
display: inline-block;
width: 100%;
background-Color: white;
color: black;
border-radius: 5%;
margin: 2px;
padding: 1px;
opacity: 0.5;
transition-duration: 0.5s;
}
.imageDisplay:hover {
opacity: 1;
}
.Image {
width: 99%;
height: auto;
margin: 1px;
padding: 1px;
border-radius: 5%;
cursor: pointer;
display: none;
}
<div class="imageDisplay">
<p>Description</p>
<img class="Image"></img>
<img class="Image"></img>
</div>
Firstly you could set the div to be equal to the size of the large image and then use:
object-fit: cover;
object-position:center;
As for switching you could use:
transition: opacity .3s linear;
Read here on how to exactly implement the transitions. My suggestion would be stacking them all up and fading them in one by one every few seconds.
https://www.w3schools.com/css/css3_transitions.asp
http://css3.bradshawenterprises.com/cfimg/
Related
I have a hover effect where when the icon image is hovered over, an larger image appears (for clarity). I want this larger image effect to end after three seconds AND still have the hover ability. If the image is moved off of, then came back to; I want the larger image to load for another three seconds. Every time the image is hovered over, the effect would last three seconds.
I have tried CSS animations, transitions, setTimeout and none of them are working like I need. Any help is appreciated. I have a LOT of code on this project, so I will try to only include the relevant parts. Thanks in advance.
I will have the code added to the question, once i figure out what I am doing wrong.
Code for building levels for hover image
#PlayerMarker1 {
position: absolute;
left:2%;
top: 2%;
z-index: 9;
}
#Player1Final{
position: absolute;
left:2%;
top: 2%;
z-index: 9;
}
/* Elements for Image load on hover*/
.playerMarker img{
margin: 0 5px 5px 0;
}
.playerMarker:hover{
background-color: transparent;
}
.playerMarker:hover img{
border: 1px;
}
.playerMarker span{ /*CSS for enlarged image*/
position: absolute;
padding: 0px;
left: -1000px;
/*background-color: black ;*/
visibility: hidden;
color: black;
text-decoration: none;
}
.playerMarker span img{ /*CSS for enlarged image*/
border-width: 0;
padding: 2px;
}
.playerMarker:hover span{ /*CSS for enlarged image*/
visibility: visible;
top: 0;
left: 100px; /*position where enlarged image should offset horizontally */
z-index: 50;
}
Code for defining the images.
<div id="Player1Test">
<a id="PlayerMarker1" href="#thumb1"><img src="Player Markers/Morty_Icon.png" width="auto" height="auto"/><span><img src="Player Images/Morty_Token.png" /><br /></span></a>
</div>
This script adds the playerMarker classes to the element I need.
/* Script to add class to player marker ID items */
function Player1Function() {
var Player1FinalTest = document.getElementById("PlayerMarker1");
Player1FinalTest.classList.add("playerMarker");
Player1FinalTest.id='Player1Final';
}
Seems like css animations to pulse the image would work fine. Run the code snippet to try.
img {
margin: 25px;
width: 100px;
height: auto;
}
img:hover {
animation: pulse 2s 1;
}
#keyframes pulse {
0% {
transform: scale(1);
box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.7);
}
50% {
transform: scale(1.4);
box-shadow: 0 0 0 10px rgba(0, 0, 0, 0);
}
100% {
transform: scale(1);
box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
}
<h4>Hover the mouse over image<h4>
<img src="https://stackoverflow.design/assets/img/favicons/apple-touch-icon.png">
Yogi has a good answer using an animation that could be adapted to clearly move your element. I wanted to add an answer manipulating the left and top values using delay.
You are essentially moving a hidden image from off screen onto the screen. Though this feels a bit strange to do, as there may be more clear ways of accomplishing this task, you can immediately move the left into view, and delay moving the top out of view.
A different delay is needed for the hover and for the base element, so it returns to the original position immediately and is available for reuse, but delays moving away on hover.
This might keep in spirit of your current project.
If you have any questions, please ask 🚀
.playerMarker {
background-color: lightblue;
--size: 4rem;
height: var(--size);
width: var(--size);
}
.playerMarker span {
position: absolute;
padding: 0px;
top: 0;
left: -1000px;
visibility: hidden;
color: black;
text-decoration: none;
transition: top 0s;
}
.playerMarker span img {
border-width: 0;
padding: 2px;
}
.playerMarker:hover span {
transition: top 0s 2s;
visibility: visible;
top: -1000px;
left: 100px;
z-index: 50;
}
<div class="playerMarker">
<span>
<img src="https://stackoverflow.design/assets/img/favicons/apple-touch-icon.png" />
</span>
</div>
We open popup window. We want to slide this off the screen. The "Right" and "Top" parts can be made as much as possible. How can we slide out of the screen?
var wind = window.open("https://www.google.com","","width=50,height=50,left=1500%,top=1000%");
While I'm not exactly sure about your particular use case, but by toggling opacity and right/left, you can achieve the "effect" of the div going out of the screen.
function move() {
let element = document.getElementById("box");
element.style.transform = "translate(-400px)";
element.style.right = 0;
element.style.opacity = 0;
}
#box {
width: 300px;
height: 200px;
background: blue;
margin-bottom: 20px;
color: white;
transition: all 0.3s ease;
opacity: 1;
position: absolute;
}
#btn {
margin-top: 300px;
}
<div id="box">Hello</div>
<button id="btn" onclick="move()">Click</button>
I have an overlay which contains a div and a couple of other elements.
I'm trying to get the div to scale up with a transition upon opening the overlay.
HTML
<div id="item-overlay" class="overlay">
<div id="item-panel" class="overlay-panel">
<div class="overlay-panel-top">
<h1 id="item-panel-title" class="main-panel-txt">Item</h1>
<img class="close" src="images/close.png" alt="" onclick="closeOverlay()">
</div>
</div>
</div>
CSS
.overlay{
display: none;
align-items: center;
justify-content: center;
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 2;
}
#item-panel{
width: 0%;
height: 75%;
background: white;
border-radius: 15px;
padding: 25px;
-webkit-transition: width 0.25s ease-in-out;
}
JS
var itmOverlay = document.getElementById("item-overlay");
var itemPanel = document.getElementById("item-panel")
function itemOverlay(){
itmOverlay.style.display = "flex";
itemPanel.style.width = "50%";
}
function closeOverlay(){
itmOverlay.style.display = "none";
itemPanel.style.width = "0%";
}
This doesn't work, the of div just appears at full-size when opening the overlay. However, I can past the code above into the console and the transition will work.
I'm really not sure what's going on here.
I'm unsure why the code above doesn't work, but I managed to get the desired effect by changing the width in a separate function that's called after the overlay is enabled.
function itemOverlay(){
itmOverlay.style.display = "flex";
setTimeout(openOverlayTimer, 10);
}
function openOverlayTimer(){
itemPanel.style.width = "50%";
}
CODE
I have 3 divs with text (1, 2, 3).
When the user hovers over each div, it should change the image.
I have a 1s ease transition to make it smooth.
BUG
If you hover over different divs too quickly, the transition is choppy or doesn't load. I'm looking for a solution where the user can quickly move through the divs and the image will transition slowly to whichever is the newest div. Thank you in advance.
CODEPEN DEMO
Codepen
LIVE DEMO:
img1 = 'url(https://images.unsplash.com/photo-1533273859801-d731381dfe2d)';
img2 = 'url(https://images.unsplash.com/photo-1534939444268-6a9ff2733c32)';
img3 = 'url(https://images.unsplash.com/photo-1534841515798-3d43f5434123)';
$('.p1').hover(function(){
$('.bg').css({'background-image': img1});
});
$('.p2').hover(function(){
$('.bg').css({'background-image': img2});
});
$('.p3').hover(function(){
$('.bg').css({'background-image': img3});
});
body {
margin: 0;
font-family: sans-serif;
}
.bg {
position: absolute;
width: 100%;
height: 100%;
background: url(https://images.unsplash.com/photo-1533273859801-d731381dfe2d) no-repeat center;
background-size: cover;
z-index: -1;
background-color: #989898;
background-blend-mode: multiply;
transition: background-image 1s ease
}
.projects {
position: absolute;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100vw;
height: 16em;
}
.p {
font-size: 1.2em;
position: relative;
padding: 2rem 0;
color: #fff;
opacity: 0.5;
letter-spacing: 4px;
text-indent: 4px;
font-weight: 400;
transition: opacity 0.5s ease;
text-align: center;
}
.p:hover {
opacity: 1;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="bg"></div>
<div class="projects">
<div class="p p1">1</div>
<div class="p p2">2</div>
<div class="p p3">3</div>
</div>
I suggest you to use the mousemove event and the .on() method instead of the .hover() method.
That, to be able to "buffer" events... Without missing one.
.hover() method is the same as defining a mouseenter and mouseout event handler (the second being optionnal).
With the mousemove event, the chances for the event to fire correctly (from a user point of view) are higher since it fires like a machinegun.
Why... Because you will have to "buffer" those events to wait for the current transition to end.
Now, you will attach the event handler to the common class .p and set a timeout of 600ms of "mouse inactivity". After that delay, the background wil be updated with the image corresponding with the last .p mousemoved.
While the user just move the mouse like someone with parkinson's desease, nothing happens about the background. It is updated and animated only on mousemove stop.
img1 = 'url(http://ejournalz.com/wp-content/uploads/2017/06/Dog-Care.jpg)';
img2 = 'url(https://www.focusdogtraining.com/wp-content/uploads/2017/10/puppies.jpg)';
img3 = 'url(https://www-tc.pbs.org/wgbh/nova/assets/img/full-size/clever-dog-lab-merl.jpg)';
var movement;
$(".p").on("mousemove",function(e){
var target = $(e.target);
clearTimeout(movement);
movement = setTimeout(function(){
console.log("User stopped moving... Updating the image.")
if(target.hasClass("p1")){
console.log("image #1");
$('.bg').css({'background-image': img1});
}
if(target.hasClass("p2")){
console.log("image #2");
$('.bg').css({'background-image': img2});
}
if(target.hasClass("p3")){
console.log("image #3");
$('.bg').css({'background-image': img3});
}
},600);
});
A working demo is best viewed on CodePen than in a SO snippet (sadly).
Ok. This is impossible using CSS, so here is a how to do it using jQuery.
To acheive the transition, we'll have to use two divs, one in the background and one in the front that will fade in giving us the illusion of transition. The .bg div should contain those two divs:
<div class="bg">
<div class="back"></div>
<div class="front"></div>
</div>
The css should change to:
.bg {
position: absolute;
width: 100%;
height: 100%;
z-index: -1;
background-color: #989898;
background-blend-mode: multiply;
transition: background-image 1s ease
}
.bg > * {
background: url(http://ejournalz.com/wp-content/uploads/2017/06/Dog-Care.jpg) no-repeat center;
background-size: cover;
position: absolute;
width: 100%;
height: 100%;
}
Which just removes any css transitions and make the inner divs overlap and as big as their parent .bg.
Now for the js part - where the actual transition takes place. When the mouse enters a .p area, we just call the function changeTo with the corresponding image. The function takes the current image from the front to the back, sets the new image as the front image. Doing that will be choppier than the css transition because the opacity doesn't match. Making the front image the back one should be accompaigned with an invertion of the opacity of the front. That is achieved by just getting the opacity and substracting it from 1. After we do that, we just animate the front image opacity from whatever value it is now to 1. The speed of this animation should be relative to what the opacity is:
var $back = $(".bg .back"),
$front = $(".bg .front");
function changeTo(img) {
$front.stop(); // stop any animation that may be in progress
var op = $front.css("opacity"); // get the opacity value (stoping the animation will let the opacity hanging between 0 and 1 inclusive, so we get that value to transition from it)
$back.css("background-image", $front.css("background-image")); // make the front image the back one
$front.css({
opacity: 1 - op, // because we made the front image the back one we need to invert the front image's opacity to give the illusion that the back image (which is now the front one) is shown at the original opacity. That's how math works!
"background-image": img // and of course make the front image our desired one
});
$front.animate({ // animate the front image's
opacity: 1 // ... opacity from whatever value it is to 1
}, 500 * op, "linear"); // in a period of 0.5s accouunting for the opacity delta, in other words animating from opacity 0.5 to 1 will take only half the time as animating from 0 to 1. That also how math works! :P
}
$('.p1').on("mouseenter", function() { // when mouse enters .p1
changeTo(img1); // change to img1
});
$('.p2').o...
Working example:
var img1 = 'url(http://ejournalz.com/wp-content/uploads/2017/06/Dog-Care.jpg)';
var img2 = 'url(https://www.focusdogtraining.com/wp-content/uploads/2017/10/puppies.jpg)';
var img3 = 'url(https://www-tc.pbs.org/wgbh/nova/assets/img/full-size/clever-dog-lab-merl.jpg)';
var $back = $(".bg .back"),
$front = $(".bg .front");
function changeTo(img) {
$front.stop();
var op = $front.css("opacity");
$back.css("background-image", $front.css("background-image"));
$front.css({
opacity: 1 - op,
"background-image": img
});
$front.animate({
opacity: 1
}, 500, "linear");
}
$('.p1').on("mouseenter", function() {
changeTo(img1);
});
$('.p2').on("mouseenter", function() {
changeTo(img2);
});
$('.p3').on("mouseenter", function() {
changeTo(img3);
});
.bg {
position: absolute;
width: 100%;
height: 100%;
z-index: -1;
background-color: #989898;
background-blend-mode: multiply;
transition: background-image 1s ease
}
.bg > * {
background: url(http://ejournalz.com/wp-content/uploads/2017/06/Dog-Care.jpg) no-repeat center;
background-size: cover;
position: absolute;
width: 100%;
height: 100%;
}
.projects {
position: absolute;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100vw;
height: 16em;
}
.p {
font-size: 1.2em;
position: relative;
padding: 2rem 0;
color: #fff;
opacity: 0.5;
letter-spacing: 4px;
text-indent: 4px;
font-weight: 400;
transition: opacity 0.5s ease;
text-align: center;
}
.p:hover {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="bg">
<div class="back"></div>
<div class="front"></div>
</div>
<div class="projects">
<div class="p p1">1</div>
<div class="p p2">2</div>
<div class="p p3">3</div>
</div>
If you see the code sample I have shared, you can see the overlay going outside the box. I traced the issue down to the transition attribute.
I want to remove the content outside of the div. Overflow isn't working as it is supposed to. (removing transition works, but I would like to keep it if possible)
Any help is appreciated
Codepen Link
CODE
var timer = setInterval(function() {
document.querySelector(".qs-timer-overlay").style.opacity = (document.querySelector(".qs-timer-overlay").style.opacity * 1) + 0.1;
if (document.querySelector(".qs-timer-overlay").style.opacity * 1 == 1) {
clearInterval(timer);
}
}, 1000);
.qs-main-header .qs-timer {
padding: 13px 10px;
min-width: 130px;
text-align: center;
display: inline-block;
background-color: #dd8b3a;
color: #FFF;
font-size: 20px;
border-radius: 50px;
text-transform: uppercase;
float: right;
cursor: pointer;
position: relative;
overflow: hidden;
}
.qs-main-header .qs-timer-overlay {
z-index: 1;
width: 10%;
max-width: 100%;
position: absolute;
height: 100%;
top: 0;
left: 0;
background-color: #c7543e;
opacity: 0.0;
/* border-radius: 50px 50px 0px 50px; */
}
.qs-main-header .qs-timer-content {
z-index: 2;
position: relative;
}
.scale-transition {
-webkit-transition: all 1s;
transition: all 1s;
}
<div class="qs-main-header">
<div class="qs-timer scale-transition ng-hide" ng-show="visibility.timer">
<div class="scale-transition qs-timer-overlay"></div>
<div class="qs-timer-content ng-binding">0 <span class="ng-binding">Sec(s)</span>
</div>
</div>
</div>
Actually it is the border-radius that is not getting respected when the transition is happening. This is because of creation of compositing layers for accelerated rendering and can be explained by having a look at the following articles:
HTML5 Rocks - Accelerated Rendering in Chrome
GPU Accelerated Compositing in Chrome.
Why does the issue not happen when transition is disabled?
When styles change but none of the criteria that necessitates the creation of a compositing layer is satisfied (that is, no animation or transition or 3D transform etc):
There is no compositing layer and so the whole area seems to get repainted at every change. Since a full repaint happens there is no issue.
View the below snippet (in full screen mode) after enabling "Show paint rects" and "Show composited layer borders" from Dev tools and observe the following:
No areas with an orange border (compositing layer) are created.
Every time the styles are modified by setting the focus on one of the a tags, the whole area gets repainted (a red or green blinking area).
.outer {
position: relative;
height: 100px;
width: 100px;
margin-top: 50px;
border: 1px solid red;
overflow: hidden;
}
.border-radius {
border-radius: 50px;
}
.inner {
width: 50px;
height: 50px;
background-color: gray;
opacity: 0.75;
}
a:focus + .outer.border-radius > .inner {
transform: translateX(50px);
height: 51px;
opacity: 0.5;
}
<a href='#'>Test</a>
<div class='outer border-radius'>
<div class='inner'>I am a strange root.
</div>
</div>
Why does adding a transition create a problem?
Initial rendering has no compositing layer because there is no transition yet on the element. View the below snippet and note how when the snippet is run a paint (red or green blinking area) happens but no compositing layer (area with orange border) is created.
When transition starts, Chrome splits them into different compositing layers when some properties like opacity, transform etc are being transitioned. Notice how two areas with orange borders are displayed as soon as the focus is set on one of the anchor tags. These are the compositing layers that got created.
The layer splitting is happening for accelerated rendering. As mentioned in the HTML5 Rocks article, the opacity and transform changes are applied by changing the attributes of the compositing layer and no repainting occurs.
At the end of the transition, a repaint happens to merge all the layers back into a single layer because compositing layers are no longer applicable (based on criteria for creation of layers).
.outer {
position: relative;
height: 100px;
width: 100px;
margin-top: 50px;
border: 1px solid red;
overflow: hidden;
}
.border-radius {
border-radius: 50px;
}
.inner {
width: 50px;
height: 50px;
background-color: gray;
transition: all 1s 5s;
/*transition: height 1s 5s; /* uncomment this to see how other properties don't create a compositing layer */
opacity: 0.75;
}
a:focus + .outer.border-radius > .inner {
transform: translateX(50px);
opacity: 0.5;
/*height: 60px; */
}
<a href='#'>Test</a>
<div class='outer border-radius'>
<div class='inner'>I am a strange root.
</div>
</div>
This illustrates that when the layers are merged back and full repaint happens, the border-radius on the parent also gets applied and respected. However, during transition only the compositing layer's properties are changed, so the layer seems to become unaware of the properties of other layers and thus doesn't respect the border-radius of the parent.
I would assume this to be because of the way rendering of layers work. Each layer is a software bitmap and so it kind of becomes equivalent to having a circular image and then placing a div on top of it. That would obviously not result in any clipping of content.
The comment in this bug thread also seems to confirm that a repaint happens when a separate layer is no longer required.
We want to repaint if "gets own layer" is going to change
Note: Though they are Chrome specific, I think the behavior should be similar in others also.
What is the solution?
The solution seems to be to create a separate stacking context for the parent (.qs-timer) element. Creating a separate stacking context seems to result in a separate compositing layer being created for the parent and this solves the issue.
As mentioned by BoltClock in this answer, any one of the following options would create a separate stacking context for the parent and doing one of them seems to resolve the issue.
Setting a z-index on the parent .qs-timer to anything other than auto.
var timer = setInterval(function() {
document.querySelector(".qs-timer-overlay").style.opacity = (document.querySelector(".qs-timer-overlay").style.opacity * 1) + 0.1;
if (document.querySelector(".qs-timer-overlay").style.opacity * 1 == 1) {
clearInterval(timer);
}
}, 1000);
.qs-main-header .qs-timer {
padding: 13px 10px;
min-width: 130px;
text-align: center;
display: inline-block;
background-color: #dd8b3a;
color: #FFF;
font-size: 20px;
border-radius: 50px;
text-transform: uppercase;
float: right;
cursor: pointer;
position: relative;
overflow: hidden;
z-index: 1; /* creates a separate stacking context */
}
.qs-main-header .qs-timer-overlay {
z-index: 1;
width: 10%;
max-width: 100%;
position: absolute;
height: 100%;
top: 0;
left: 0;
background-color: #c7543e;
opacity: 0.0;
/* border-radius: 50px 50px 0px 50px; */
}
.qs-main-header .qs-timer-content {
z-index: 2;
position: relative;
}
.scale-transition {
-webkit-transition: all 1s;
transition: all 1s;
}
<div class="qs-main-header">
<div class="qs-timer scale-transition ng-hide" ng-show="visibility.timer">
<div class="scale-transition qs-timer-overlay"></div>
<div class="qs-timer-content ng-binding">0 <span class="ng-binding">Sec(s)</span>
</div>
</div>
</div>
Setting opacity to anything less than 1. I have used 0.99 in the below snippet as it doesn't cause any visual difference.
var timer = setInterval(function() {
document.querySelector(".qs-timer-overlay").style.opacity = (document.querySelector(".qs-timer-overlay").style.opacity * 1) + 0.1;
if (document.querySelector(".qs-timer-overlay").style.opacity * 1 == 1) {
clearInterval(timer);
}
}, 1000);
.qs-main-header .qs-timer {
padding: 13px 10px;
min-width: 130px;
text-align: center;
display: inline-block;
background-color: #dd8b3a;
color: #FFF;
font-size: 20px;
border-radius: 50px;
text-transform: uppercase;
float: right;
cursor: pointer;
position: relative;
overflow: hidden;
opacity: 0.99; /* creates a separate stacking context */
}
.qs-main-header .qs-timer-overlay {
z-index: 1;
width: 10%;
max-width: 100%;
position: absolute;
height: 100%;
top: 0;
left: 0;
background-color: #c7543e;
opacity: 0.0;
/* border-radius: 50px 50px 0px 50px; */
}
.qs-main-header .qs-timer-content {
z-index: 2;
position: relative;
}
.scale-transition {
-webkit-transition: all 1s;
transition: all 1s;
}
<div class="qs-main-header">
<div class="qs-timer scale-transition ng-hide" ng-show="visibility.timer">
<div class="scale-transition qs-timer-overlay"></div>
<div class="qs-timer-content ng-binding">0 <span class="ng-binding">Sec(s)</span>
</div>
</div>
</div>
Adding a transform to the element. I have used translateZ(0px) in the below snippet as this also doesn't create any visual difference.
var timer = setInterval(function() {
document.querySelector(".qs-timer-overlay").style.opacity = (document.querySelector(".qs-timer-overlay").style.opacity * 1) + 0.1;
if (document.querySelector(".qs-timer-overlay").style.opacity * 1 == 1) {
clearInterval(timer);
}
}, 1000);
.qs-main-header .qs-timer {
padding: 13px 10px;
min-width: 130px;
text-align: center;
display: inline-block;
background-color: #dd8b3a;
color: #FFF;
font-size: 20px;
border-radius: 50px;
text-transform: uppercase;
float: right;
cursor: pointer;
position: relative;
overflow: hidden;
transform: translateZ(0px) /* creates a separate stacking context */
}
.qs-main-header .qs-timer-overlay {
z-index: 1;
width: 10%;
max-width: 100%;
position: absolute;
height: 100%;
top: 0;
left: 0;
background-color: #c7543e;
opacity: 0.0;
/* border-radius: 50px 50px 0px 50px; */
}
.qs-main-header .qs-timer-content {
z-index: 2;
position: relative;
}
.scale-transition {
-webkit-transition: all 1s;
transition: all 1s;
}
<div class="qs-main-header">
<div class="qs-timer scale-transition ng-hide" ng-show="visibility.timer">
<div class="scale-transition qs-timer-overlay"></div>
<div class="qs-timer-content ng-binding">0 <span class="ng-binding">Sec(s)</span>
</div>
</div>
</div>
The first two approaches are more preferable than the third because the third one works only on a browser that supports CSS transforms.
Yes, adding opacity: 0.99; to .qs-timer issue will fixed.
When opacity: 1 OR NOT define:
In this special case, there is no transparency involved so that gfx could avoid doing the expensive things.
In case Opacity: 0.99:
nsIFrame::HasOpacity() decides that there is an opacity, so gfx include valuable things. ( likes opacity with border-radius)
For more help Special case opacity:0.99 to treat it as opacity:1 for graphics , This ticket is not providing the opinion of our actual goal, but giving the idea about what is happening inside of CSS.