I have two div elements that the width can be controlled with click event on javascript. Whether on click event (toggling a className) or hover event, the background images of the its pseudo element seems to be shaking (confirmed on chrome, ie, edge, and safari).
I have looked up on SO and google but it seems to be a problem with changing the size of the background itself, which is what I did not do here.
section {
width: 100%;
max-width: 1920px;
position: relative;
min-height: 700px;
overflow: hidden;
}
.container {
width: 99%;
height: 700px;
position: absolute;
transition: 1s linear width;
overflow: hidden;
}
.left {
top: 0;
left: 0;
background: transparent;
transform: skew(20deg) translateX(-50%);
border-radius: 0 20px 20px 0;
}
.left::after {
content: "";
position: absolute;
top: 0;
left: 50%;
height: 100%;
width: 100vw;
transform: skew(-20deg);
background-image: url(https://cdn.pixabay.com/photo/2018/12/04/22/38/road-3856796__340.jpg);
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
.right {
top: 0;
right: 0;
border-radius: 20px 0 0 20px;
transform: skew(20deg) translateX(50%);
}
.right::after {
content: "";
position: absolute;
top: 0;
right: 50%;
height: 100%;
width: 100vw;
transform: skew(-20deg);
background-image: url(https://media.istockphoto.com/photos/taking-a-walk-in-the-woods-picture-id1130258547?s=2048x2048);
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
.right:hover {
width: 250%;
}
<section>
<div class="container left"></div>
<div class="container right"></div>
</section>
I have optimized the code and considered the use of left/right to define the size of the element then changed the width transition with a translation.
section {
max-width: 1920px;
position: relative;
overflow: hidden;
height: 500px;
}
.container {
position: absolute;
top: 0;
bottom:0;
transition:transform 1s linear;
overflow: hidden;
transform: skew(20deg);
}
.left {
left: -60vw; /*to create the overflow*/
right: calc(55% + 10px); /*10px distance between both element*/
border-radius: 0 20px 20px 0;
}
.right {
right: -80vw;
left: 45%; /*100% - 55% (the right value of .left)*/
border-radius: 20px 0 0 20px;
}
.left::after,
.right::after {
content: "";
position: absolute;
top: 0;
left: -40%;
bottom: 0;
right: -40%;
transform: skew(-20deg);
background-position: center;
background-repeat: no-repeat;
background-size: 100% 100%;
transition:transform 1s linear;
}
.left::after {
background-image: url(https://cdn.pixabay.com/photo/2018/12/04/22/38/road-3856796__340.jpg);
transform-origin: bottom;
}
.right::after {
transform-origin: top;
background-image: url(https://media.istockphoto.com/photos/taking-a-walk-in-the-woods-picture-id1130258547?s=2048x2048);
}
.right:hover {
transform: skew(20deg) translateX(-60vw);
}
.right:hover::after {
transform: skew(-20deg) translateX(60vw);
}
<section>
<div class="container left"></div>
<div class="container right"></div>
</section>
The shaking stems from the centered background-position
of the background-image
.
Let's do this by hand:
Image a 200px
wide div
and a background-image
with 200px
width.
The image is set to center
ed background-position
and no other background-settings.
The image will then be positioned from 0px
through 200px
of the div
Now imaging the same div
with the same background-image
and background-position
.
The only difference is: the div is 201px
wide, that is just 1 more then before.
The image will now be positioned from 0.5px
through 200.5px
of the div
which will be rounded to 1px
through 201px
Now one step further: imagine the width
of the div
to be 202px
without changing any other properties.
The image will be positioned from 1px
through 201px
. That's exactly the same as before.
Now because your div is centered. The background starts to shake
(This is not always visible. It depends on the context width);
let buttons = document.querySelectorAll('button');
let bg = document.querySelector('#bg')
buttons.forEach((btn) => {
btn.addEventListener('click', (e) => {
bg.style.width = btn.getAttribute('w')
})
})
#bg {
display: block;
width: 200px;
height: 200px;
background-color: gold;
margin: 10px auto;
background-image: url('https://picsum.photos/200/200?image=990');
background-position: center;
background-repeat: no-repeat;
}
body {
text-align: center;
width: 400px;
}
<button w="200px">200</button>
<button w="201px">201</button>
<button w="202px">202</button>
<div id="bg"></div>
The solution would be:
The left image should be positioned from the left by background-position: 0% 50%;
and the right image should be positioned from the right by background-position: 100% 50%;
This snippet should be seen in full page view
div {
height: 800px;
width: 100vw;
overflow: hidden;
margin: 0 auto;
position: relative;
}
div span {
position: absolute;
top: 0;
bottom: 0;
z-index: 0;
-webkit-transform: skew(20deg);
transform: skew(20deg);
overflow: hidden;
border-radius: 20px;
transition-duration: .3s;
transition-timing-function: ease-in-out;
-webkit-animation: at-zb 1s both;
animation: at-zb 1s both;
}
div span:hover {
z-index: 200;
transition-duration: 1s;
-webkit-animation: at-z 1s both;
animation: at-z 1s both;
}
div span a {
position: absolute;
-webkit-transform: skew(-20deg);
transform: skew(-20deg);
background-size: cover;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
div span:nth-child(1) {
left: -160px;
right: calc(100% / 2 + 10px);
transition-property: right;
}
div span:nth-child(1) a {
-webkit-transform-origin: 0% 100%;
transform-origin: 0% 100%;
background-image: url("https://picsum.photos/1920/800?image=992");
background-position: 0% 50%;
background-repeat: no-repeat;
}
div span:nth-child(1):hover {
right: -160px;
}
div span:nth-child(2) {
left: calc(100% / 2 + 10px);
right: -160px;
transition-property: left;
}
div span:nth-child(2) a {
-webkit-transform-origin: 0% 0%;
transform-origin: 0% 0%;
background-image: url("https://picsum.photos/1920/800?image=990");
background-position: 100% 50%;
background-repeat: no-repeat;
}
div span:nth-child(2):hover {
left: -160px;
}
@-webkit-keyframes at-z {
0% {
z-index: 1;
}
1%,99% {
z-index: 9;
}
100% {
z-index: 10;
}
}
@keyframes at-z {
0% {
z-index: 1;
}
1%,99% {
z-index: 9;
}
100% {
z-index: 10;
}
}
@-webkit-keyframes at-zb {
0% {
z-index: 10;
}
1%,99% {
z-index: 2;
}
100% {
z-index: 1;
}
}
@keyframes at-zb {
0% {
z-index: 10;
}
1%,99% {
z-index: 2;
}
100% {
z-index: 1;
}
}
body {
margin: 0;
padding: 0;
}
<div><span><a></a></span><span><a></a></span></div>
See this codepen: https://codepen.io/HerrSerker/pen/zbWpjB for a SCSS version
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With