I want an element to get applied some styles in a smooth way after 2 seconds. I tried setTimeout, to add the class after two seconds, but despite having declared transition: all 1s to absolutely everything, when the class (containing new styles )is added, I can't see any "transition", the new styles are just applied without smoothness.
How can I fix it?
var s2 = document.querySelector("#section2");
setTimeout(() => {
s2.classList.add("up");
}, 2000);
html * {
transition: 1s all;
}
body {
overflow: hidden;
}
#section1 {
background: steelblue;
}
#section2 {
background: indigo;
position: absolute;
}
section {
width: 100%;
height: 100vh;
}
.up {
top: 0px;
}
<section id="section1"></section>
<section id="section2"></section>
What I want to achieve is that the div that is below the first one start moving up until it reaches the top of the window, like a "slide-up" effect. Why are "transition" property being ignored after adding the class containing this new styles?
You need to apply an initial value for the top rule to allow the transition to take effect.
var s2 = document.querySelector("#section2");
setTimeout(() => {
s2.classList.add("up");
}, 2000);
html * {
transition: 1s all;
}
body {
overflow: hidden;
position: relative; /** ensure section#section2 is positioned relative to the body **/
}
#section1 {
background: steelblue;
}
#section2 {
background: indigo;
position: absolute;
top: 100vh; /** initial value **/
}
section {
width: 100%;
height: 100vh;
}
/** #section2.up is more specific **/
#section2.up {
top: 0;
}
<section id="section1"></section>
<section id="section2"></section>
You can also animate with an external library like jQuery:
$("#section2").animate({
top: 0,
duration: 2000
});
html * {
transition: 1s all;
}
body {
overflow: hidden;
}
#section1 {
background: steelblue;
}
#section2 {
background: indigo;
position: absolute;
}
section {
width: 100%;
height: 100vh;
}
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<section id="section1"></section>
<section id="section2"></section>
Related
this code changes the background of the div every time a button is pressed but the new background is supposed to fade in so I set an animation. If you press red, and then another color, it makes the transition the first time, but not from the second on. The background will just appear without animation.
function changit(color) {
document.getElementById('cont').classList = color;
}
#keyframes appear {
0% {opacity:0;}
100% {opacity:1;}
}
#cont {
position: relative;
width: 100px;
height: 100px;
display: block;
}
#cont::before {
width: 93%;
height: 100%;
position: sticky;
content: "";
display: block;
}
.red::before, .blue::before, .black::before { transition: opacity 2s ease;animation:appear 2s; }
.red::before {
background: url(https://cdn.sstatic.net/Img/teams/teams-illo-free-sidebar-promo.svg) no-repeat;
}
.blue::before {
background: url(https://www.gravatar.com/avatar/24780fb6df85a943c7aea0402c843737?s=64&d=identicon&r=PG) no-repeat;
}
.black::before {
background:url(https://cdn.sstatic.net/Sites/stackoverflow/Img/subcommunities/intel.svg?v=0371bf2f3b96) no-repeat;
}
<div id="cont">
</div>
<button onclick="changit('red');">make red</button>
<button onclick="changit('blue');">make blue</button>
<button onclick="changit('black');">make black</button>
isnt the animation supposed to play again if the element changes class? How can I reset the animation to start again every time the element changes class to achieve this effect?
The animation property value actually never changes, with all the classes it's always the same and there is no point in time where it's unset, so it won't fire again.
You need to force the CSS engine sees that it did change. For this you can remove the class altogether force what is called a "reflow", which is when the CSS engine recalculates all the element's boxes in the page, and then only, set the class back:
function changit(color) {
const elem = document.getElementById('cont');
elem.classList = "";
elem.offsetWidth; // force reflow
elem.classList = color;
}
function changit(color) {
const elem = document.getElementById('cont');
elem.classList = "";
elem.offsetWidth; // force reflow
elem.classList = color;
}
#keyframes appear {
0% {opacity:0;}
100% {opacity:1;}
}
#cont {
position: relative;
width: 100px;
height: 100px;
display: block;
}
#cont::before {
width: 93%;
height: 100%;
position: sticky;
content: "";
display: block;
}
.red::before, .blue::before, .black::before { transition: opacity 2s ease;animation:appear 2s; }
.red::before {
background: url(https://cdn.sstatic.net/Img/teams/teams-illo-free-sidebar-promo.svg) no-repeat;
}
.blue::before {
background: url(https://www.gravatar.com/avatar/24780fb6df85a943c7aea0402c843737?s=64&d=identicon&r=PG) no-repeat;
}
.black::before {
background:url(https://cdn.sstatic.net/Sites/stackoverflow/Img/subcommunities/intel.svg?v=0371bf2f3b96) no-repeat;
}
<div id="cont">
</div>
<button onclick="changit('red');">make red</button>
<button onclick="changit('blue');">make blue</button>
<button onclick="changit('black');">make black</button>
Or, since you're using JS anyway, use the WebAnimations API:
function changit(color) {
const elem = document.getElementById('cont');
elem.classList = color;
elem.animate(
[ { opacity: 0 }, { opacity: 1 } ],
{ duration: 2000, repeat: 1 }
);
}
function changit(color) {
const elem = document.getElementById('cont');
elem.classList = color;
elem.animate(
[ { opacity: 0 }, { opacity: 1 } ],
{ duration: 2000, repeat: 1 }
);
}
#cont {
position: relative;
width: 100px;
height: 100px;
display: block;
}
#cont::before {
width: 93%;
height: 100%;
position: sticky;
content: "";
display: block;
}
.red::before {
background: url(https://cdn.sstatic.net/Img/teams/teams-illo-free-sidebar-promo.svg) no-repeat;
}
.blue::before {
background: url(https://www.gravatar.com/avatar/24780fb6df85a943c7aea0402c843737?s=64&d=identicon&r=PG) no-repeat;
}
.black::before {
background:url(https://cdn.sstatic.net/Sites/stackoverflow/Img/subcommunities/intel.svg?v=0371bf2f3b96) no-repeat;
}
<div id="cont">
</div>
<button onclick="changit('red');">make red</button>
<button onclick="changit('blue');">make blue</button>
<button onclick="changit('black');">make black</button>
Edit: This bug has been fixed by Chromium some time ago
Simple Codepen: https://codepen.io/themanfromearth1/pen/WNRoyyW
With Slick Slider: https://codepen.io/maxbeat/pen/abNBrex
The error happens when you combine backdrop-filter blur with either transition-duration or transform in the parent.
Parent Div:
.slider {
transition-duration: 300ms; /** One of those two is enough **/
transition: transform 0.3s; /** But with either the bug occurs **/
transform: translate3d(-100px, 0, 0);
}
Child Div:
.slider__item {
background: rgba(206, 206, 206, 0.15);
backdrop-filter: blur(89px);
}
When you click the button, the CSS blur disappears for a second and then the slide is blurred again.
Chrome: Problem
Firefox: Works (you have to enable backdrop-filter first in about:config)
Webkit/Safari: Working
Edit: There is a confirmed bug-report on Chromium for this problem
https://bugs.chromium.org/p/chromium/issues/detail?id=1194050
Without using translate you can use positioning with left.
let translated = false
function translate3d() {
const div2 = document.getElementById("slider")
if (!translated) {
div2.style.left = '100px';
} else {
div2.style.left = '400px';
}
translated = !translated;
}
.slider {
display: flex;
align-items: center;
justify-content: center;
position: relative;
left: 400px;
/** Remove duration and blur works **/
transition-duration: 300ms;
/** Also disappears if you transform like this **/
/** transition: transform 0.3s **/
}
.slider__item {
height: 100px;
width: 100px;
background: rgba(206, 206, 206, 0.15);
backdrop-filter: blur(89px)!important;
margin: 6px;
margin-top: 200px;
}
.container {
height: 1900px;
width: 899px;
background-image:url(https://images.unsplash.com/photo-1616604745302-60a195c7061a?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1401&q=80);
}
.button {
position:absolute;
top: 350px;
left: 400px;
}
<div class="container">
<div class="slider" id="slider">
<div class="slider__item">1</div>
<div class="slider__item">2</div>
<div class="slider__item">3</div>
<div class="slider__item">4</div>
<div class="slider__item">5</div>
</div>
</div>
<div class="button">
<button type="button" onclick="translate3d()">Click to transform translate3d</button>
</div>
<div>
It's a bug !
I've encountered it myself while I was building my own portfolio.
The way I've solved it was by using an API for smooth scrolling that I wrote which is available here: https://github.com/CristianDavideConte/universalSmoothScroll
Basically the solution is: don't use translate and backdrop-filter:blur together, just make the parent container scrollable and smoothly scroll it whenever you need it.
I've rewrote your slider example so that it correctly works with the API:
const maxSlide = 5;
const minSlide = 1;
const visibleSlides = 3;
let numSlide = 0;
function init() {
let leftArrow = document.getElementById('left-arrow');
let rightArrow = document.getElementById('right-arrow');
let slider = document.getElementsByClassName('slider')[0];
let slides = slider.children;
leftArrow.onclick = (e) => {
e.preventDefault();
if(numSlide > minSlide - 1) {
numSlide--;
uss.scrollIntoView(slides[numSlide], true, null, null, true);
}
}
rightArrow.onclick = (e) => {
e.preventDefault();
if(numSlide < maxSlide - visibleSlides) {
numSlide++;
uss.scrollIntoView(slides[numSlide], true, null, null, true);
}
}
/* We apply an ease function to make it look pretty */
let whateverEaseFunctionYouLike = remaning => {return remaning / 15 + 1;};
uss.setXStepLengthCalculator(whateverEaseFunctionYouLike, slider);
}
* {
padding: 0;
margin: 0;
}
body {
height: 100vh;
overflow: hidden;
background: url(https://img.wallpapersafari.com/desktop/1366/768/66/57/D2uNEj.jpg) no-repeat; /* Moved from container */
background-size: cover; /* Moved from container */
}
.container {
width: 100vw; /* Added */
display: flex; /*Added */
height: 200px; /* Moved from slider__item */
/*height: 100%; Removed */
/*padding: 60px; Removed */
}
.slider {
width: 80%; /* Changed */
height: 100%; /* Added */
position: relative;
display:flex; /* Added */
overflow: hidden; /* Added */
/*margin-bottom: 60px; Removed*/
}
.slick-list {
overflow: hidden;
}
.slick-track {
display: flex;
}
.slider__item {
width: calc(74vw / 3); /* Added */
height: 80%; /* Added */
flex-shrink: 0; /* Added */
margin: auto 1vw; /* Changed */
display: flex;
align-items: center;
justify-content: center;
font: 24px arial;
background: rgba(255,255,255,0.5);
backdrop-filter: blur(10px);
}
.slick-dots {
display: flex;
justify-content: center;
position: absolute;
width: 100%;
}
.slick-dots li {
background: #fff;
width: 10px;
height: 10px;
margin: 5px;
border-radius: 50%;
cursor: pointer;
list-style:none
}
.slick-dots li.slick-active {
background: #000;
}
.slick-dots li button {
font-size: 0;
border: none;
opacity: 0;
}
.slick-arrow {
font-size: 0;
width: 30px;
height: 30px;
background: none;
border: none;
border-top: 4px solid #fff;
border-left: 4px solid #fff;
/*transform: rotate(-45deg); Moved */
/*position: absolute; Removed */
margin: auto; /* Added */
top: 100px;
cursor: pointer;
}
.slick-next {
transform: rotate(135deg);
right: -30px;
}
.slick-prev {
left: -30px;
}
#left-arrow {
transform: rotate(-45deg); /* Moved from slick-arrow*/
}
#right-arrow {
transform: rotate(135deg); /* Moved from slick-arrow and then changed */
}
<script src = "https://cdn.jsdelivr.net/npm/universalsmoothscroll#latest/universalsmoothscroll-min.js"></script> <!-- Added -->
<body onload="init()"> <!-- Added init -->
<div class="container">
<button id= "left-arrow" class ="slick-arrow"><</button> <!-- Added -->
<div class="slider">
<div class="slider__item">1</div>
<div class="slider__item">2</div>
<div class="slider__item">3</div>
<div class="slider__item">4</div>
<div class="slider__item">5</div>
</div>
<button id= "right-arrow" class ="slick-arrow">></button> <!-- Added -->
</div>
</body>
The advantage of this aproach is that you can customize the scrolling related part of your slider just as much as you did with "slick-slider".
If you need one more example of a carousel built with this API you can take a look at here: https://cristiandavideconte.github.io/myPersonalWebPage/#home
I've been searching for a couple of days to add a fade transition effect on the backgroundImage that I'm changing through a Vue app.
Here is the code snippet I've been testing on:
new Vue({
el: "#main",
data: {
images: [
"https://images.freeimages.com/images/large-previews/bfd/clouds-1371838.jpg",
"https://images.freeimages.com/images/large-previews/ffa/water-lilly-1368676.jpg",
"https://images.freeimages.com/images/large-previews/efb/lotus-flower-1382251.jpg"
],
current: 0,
show: false
},
methods: {
changeBG: function () {
if (this.current < this.images.length - 1) {
this.current = this.current + 1;
} else {
this.current = 0;
}
}
}
});
.main {
height: 800px;
width: 100%;
margin-left: auto;
margin-right: auto;
z-index: 0;
background-repeat: no-repeat;
background-size: cover;
background-position: center 0px;
}
button {
width: 200px;
height: 25px;
margin: 10px;
}
p.hello{
color: white;
margin: 10px;
font-size: 50px;
}
.fade-enter-active,
.fade-leave-active {
transition: all 2s linear;
}
.fade-enter-to,
.fade-leave {
opacity: 0;
}
.fade-enter,
.fade-leave-to {
opacity: 1;
}
/* hello example transition */
.slide-fade-enter-active {
transition: all 1s ease;
}
.slide-fade-leave-active {
transition: all 1s cubic-bezier(1, 0.5, 0.8, 1);
}
.slide-fade-enter,
.slide-fade-leave-to {
transform: translateX(10px);
opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<transition name="fade">
<div v-if="changeBG" class="main" id="main" :style="{ backgroundImage: 'url(\'' + images[current] + '\')' }">
<button v-on:click="changeBG">
changeBG
</button>
<div id="testFromGuide">
<button #click="show = !show">
toggleHello
</button>
<transition name="slide-fade">
<p class="hello" v-if="show">all your base are belong to us</p>
</transition>
</div>
</div>
</transition>
My first question if this is simply possible? The reason I'm using backgroundImage is because the website I'm using this on has a background that is most easy to handle responsively through this (always covering, no repeat and keeping it center). And my scond question would be, if not, is there a possibility to make it work with a background set as described here?
In the codepen I've added an example of the vue guide to make sure it works and nothing is else is wrong. And the example works perfectly. Can't seem to find the answer for my example but I've been beginning to suspect it is simply not possible or I can't seem to find why vue isn't detecting something is changing.
For Vue Transitions to work, you need to change the DOM elements. So this way would work if you were changing actual images out. In your example, you're only changing an attribute value. The DOM doesn't trigger a transition since its the same element.
However, you can use the :key attribute to convince VUE to replace the element thus giving you a transition between 2 elements.
You can also set the image with inline CSS like you're doing in the example. You'll still have to create the transition in your CSS.
Here's an example using Vue Transition
new Vue({
el: "#main",
data: {
currentID: 0,
images: [
'https://images.freeimages.com/images/large-previews/efb/lotus-flower-1382251.jpg',
'https://images.freeimages.com/images/large-previews/ffa/water-lilly-1368676.jpg',
'https://images.freeimages.com/images/large-previews/bfd/clouds-1371838.jpg'
]
},
methods: {
toggleImage: function(){
if(this.currentID < this.images.length-1){
this.currentID +=1
} else {
this.currentID = 0
}
}
}
});
body {
overflow: hidden;
}
.main {
position: relative;
}
img {
width: 100%;
height: auto;
display: block;
position: absolute;
-webkit-transition: all 3s ease;
transition: all 3s ease;
}
button {
z-index: 100;
position: relative;
width: 200px;
height: 25px;
margin: 20px;
}
/* prefix with transition name */
.slide-fade-enter-active {
opacity: 1;
z-index: 10;
}
.slide-fade-leave-active {
opacity: 1;
}
.slide-fade-enter,
.slide-fade-leave-to {
opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<div class="main" id="main">
<transition name="slide-fade">
<!-- SRC comes from the array of images the :key is important for vue to believe its a 'new' DOM element and do the transition -->
<img v-bind:src="images[currentID]" v-bind:key="currentID" />
</transition>
<button #click="toggleImage">
Toggle Image
</button>
</div>
However, you don't get a lot of control over that since it uses image tags. Instead, it might be better to use a background image like this:
new Vue({
el: "#main",
data: {
currentID: 0,
images: [
'https://images.freeimages.com/images/large-previews/efb/lotus-flower-1382251.jpg',
'https://images.freeimages.com/images/large-previews/ffa/water-lilly-1368676.jpg',
'https://images.freeimages.com/images/large-previews/bfd/clouds-1371838.jpg'
]
},
methods: {
toggleImage: function(){
if(this.currentID < this.images.length-1){
this.currentID +=1
} else {
this.currentID = 0
}
}
}
});
.main {
/* make this the size of the window */
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.theImage {
width: 100%;
height: 100%;
position: absolute;
background-color: #333;
background-size: contain;
background-repeat: no-repeat;
background-position: center center;
-webkit-transition: all 3s ease;
transition: all 3s ease;
}
button {
z-index: 100;
position: relative;
width: 200px;
height: 25px;
margin: 20px;
}
/* prefix with transition name */
.slide-fade-enter-active {
opacity: 1;
z-index: 10;
}
.slide-fade-leave-active {
opacity: 1;
}
.slide-fade-enter,
.slide-fade-leave-to {
opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<div class="main" id="main">
<transition name="slide-fade">
<!-- SRC comes from the array of images the :key is important for vue to believe its a 'new' DOM element and do the transition -->
<div class="theImage" v-bind:style="{'background-image': 'url(' + images[currentID] + ')'}" v-bind:key="currentID"></div>
</transition>
<button #click="toggleImage">
Toggle Image
</button>
</div>
The answer was indeed to forget about vue transitions and let css do the work. A working example can be found here:
new Vue({
el: "#main",
data: {
show: false,
BG1: true,
BG2: false,
BG3: false
},
methods: {
changeBG: function(){
if (this.BG1 == true){
this.BG1 = false;
this.BG2 = true;
this.BG3 = false;
} else if (this.BG2 == true) {
this.BG1 = false;
this.BG2 = false;
this.BG3 = true;
} else if (this.BG3 == true) {
this.BG1 = true;
this.BG2 = false;
this.BG3 = false;
}
},
showBG1: function(){
if (this.BG1 == true){
return "";
} else {
return "transparent";
}
},
showBG2: function(){
if (this.BG2 == true){
return "";
} else {
return "transparent";
}
},
showBG3: function(){
if (this.BG3 == true){
return "";
} else {
return "transparent";
}
}
}
});
.main {
}
#bgs img.transparent {
opacity:0;
transform: translateY(-0.0px);
}
#bgs img{
/* Set rules to fill background */
min-height: 100%;
min-width: 1024px;
/* Set up proportionate scaling */
width: 100%;
height: auto;
/* Set up positioning */
position: fixed;
top: 0;
left: 0;
z-index: -1;
-webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
}
#media screen and (max-width: 1024px) { /* Specific to this particular image */
#bgs img{
left: 50%;
margin-left: -512px; /* 50% */
}
}
button {
z-index: 100;
position: relative;
width: 200px;
height: 25px;
margin: 20px;
}
p.hello{
color: white;
margin: 40px;
font-size: 50px;
}
.fade-enter-active {
transition: all 1s ease;
}
.fade-leave-active {
transition: all 1s ease;
}
.fade-enter, .fade-leave-to{
transform: translateY(-5px);
opacity: 0;
}
/* hello example transition */
.slide-fade-enter-active {
transition: all 1s ease;
}
.slide-fade-leave-active {
transition: all 1s cubic-bezier(1, 0.5, 0.8, 1);
}
.slide-fade-enter,
.slide-fade-leave-to {
transform: translateY(-5px);
opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<div class="main" id="main">
<div id="bgs">
<img :class="showBG1()" src="https://images.freeimages.com/images/large-previews/efb/lotus-flower-1382251.jpg">
<img :class="showBG2()" src="https://images.freeimages.com/images/large-previews/ffa/water-lilly-1368676.jpg">
<img :class="showBG3()" src="https://images.freeimages.com/images/large-previews/bfd/clouds-1371838.jpg">
</div>
<button #click="changeBG">
changeBG
</button>
<div id="testFromGuide">
<button #click="show = !show">
toggleHello
</button>
<transition name="slide-fade">
<p class="hello" v-if="show">all your base are belong to us</p>
</transition>
</div>
</div>
It's not perfect yet as for every extra background I need to add a function and add an extra if else loop to the changeBG function. It would be more elegant if this could be done with a list variable but I've not found a way to make this work with the :class method. I hope to look into this at a later time.
Is there a way to dynamically add top in css/less? I have the following structure:
.a2a-desktop-right {
right: 0px;
.a2a_svg {
position: absolute;
right: 8px;
}
}
.a2a_svg has some animation effects on hover and needs to be absolutely positioned, however there can be n-types of this element. Each one needs a top of 40px more than the previous. Any way to accomplish this without js?
EDIT
I can't define the style inline - it's a 3rd party script that generates these elements. That's also why javascript is out of the question - I won't know when the elements are rendered, and if I did it would still take time for the new styles to be applied.
I managed to find a way to do it with less after seeing the below by edwinnwebb.
/* Define two variables as the loop limits */
#from : 0;
#to : 10;
/* Create a Parametric mixin and add a guard operation */
.loop(#index) when(#index =< #to) {
/* As the mixin is called CSS is outputted */
div:nth-child(#{index}) {
top: unit(#index * 100, px);
}
/* Interation call and operation */
.loop(#index + 1);
}
/* the mixin is called, css outputted and iterations called */
.loop(#from);
/*
## Output
div:nth-child(0) {
top: 0px;
}
div:nth-child(1) {
top: 100px;
}
div:nth-child(2) {
top: 200px;
}
div:nth-child(3) {
top: 300px;
}
div:nth-child(4) {
top: 400px;
}
div:nth-child(5) {
top: 500px;
}
div:nth-child(6) {
top: 600px;
}
div:nth-child(7) {
top: 700px;
}
div:nth-child(8) {
top: 800px;
}
div:nth-child(9) {
top: 900px;
}
div:nth-child(10) {
top: 1000px;
}
*/
Applied to my problem becomes...
#iterations: 0;
.svg-loop (#iterations) when (#iterations =< 5) {
.a2a-button.a2a-desktop-right:nth-of-type(#{iterations}) {
.a2a_svg{
top: unit((#iterations * 40) - 33, px);
}
}
.svg-loop(#iterations + 1);
}
Not sure whether it is chrome specific bug or what, but when I am transitioning child element on a parent that has overflow hidden with border radius, the overflow is visible, while the transition is in place.
var wrapper = document.getElementsByClassName('wrapper')[0],
img = document.getElementsByTagName('img')[0];
/*
Click anywhere in the bordered area to toggle img
*/
wrapper.addEventListener('click', function() {
if (!img.className) {
img.className = 'hidden';
} else {
img.className = '';
}
}, false);
.wrapper {
overflow: hidden;
border-radius: 60px;
border: 1px solid salmon;
}
img {
width: 100%;
height: auto;
opacity: 1;
transition: opacity 1s ease;
}
.hidden {
opacity: 0;
}
<div class="wrapper">
<img src="http://static.planetminecraft.com/files/resource_media/screenshot/1211/y-you-no-work_1687402.jpg">
</div>
Here's a fiddle demonstrating the issue https://jsfiddle.net/827vuyqb/2/
Any solutions, workarounds for this?
Just position the wrapper element, and give it a z-index:
var wrapper = document.getElementsByClassName('wrapper')[0],
img = document.getElementsByTagName('img')[0];
/*
Click anywhere in the bordered area to toggle img
*/
wrapper.addEventListener('click', function() {
if (!img.className) {
img.className = 'hidden';
} else {
img.className = '';
}
}, false);
.wrapper {
overflow: hidden;
border-radius: 60px;
border: 1px solid salmon;
/*Position and z-index*/
position: relative;
z-index: 1;
}
img {
width: 100%;
height: auto;
opacity: 1;
transition: opacity 1s ease;
}
.hidden {
opacity: 0;
}
<div class="wrapper">
<img src="http://static.planetminecraft.com/files/resource_media/screenshot/1211/y-you-no-work_1687402.jpg">
</div>