Superimposed images flicker when changing widthHow to change an element's class with JavaScript?Vertically align text next to an image?When to use IMG vs. CSS background-image?How do I give text or an image a transparent background using CSS?When to use margin vs padding in CSSChange an HTML5 input's placeholder color with CSSHow do I auto-resize an image to fit a 'div' container?Make the cursor a hand when a user hovers over a list itemHow to decide when to use Node.js?Cannot display HTML string
How to compare two different formulations of a problem?
Hai la patente? - omission of possessive adjective
Is Eldritch Blast affected by antimagic field
Changing a TGV booking
How to put the parent node higher than the children nodes in a drawing for a graph?
Is "stainless" a bulk or a surface property of stainless steel?
Is there a known non-euclidean geometry where two concentric circles of different radii can intersect? (as in the novel "The Universe Between")
My two team members in a remote location don't get along with each other; how can I improve working relations?
Does C++20 mandate source code being stored in files?
Don't teach Dhamma to those who can't appreciate it or aren't interested
How does turbine efficiency compare with internal combustion engines if all the turbine power is converted to mechanical energy?
Rogue/Artificer multiclass skill proficiency
Can my boss not paying for hours I put in to clean bar after we close?
What is the evidence on the danger of feeding whole blueberries and grapes to infants and toddlers?
90s(?) book series about two people transported to a parallel medieval world, she joins city watch, he becomes wizard
Default camera device to show screen instead of physical camera
Mixing colours for a symbol
Is refusing to concede in the face of an unstoppable Nexus combo punishable?
How does the government purchase things?
Are required indicators necessary for radio buttons?
Chord with lyrics - What does it mean if there is an empty space instead of a Chord?
How to decide whether an eshop is safe or compromised
Are there reliable, formulaic ways to form chords on the guitar?
Do predators tend to have vertical slit pupils versus horizontal for prey animals?
Superimposed images flicker when changing width
How to change an element's class with JavaScript?Vertically align text next to an image?When to use IMG vs. CSS background-image?How do I give text or an image a transparent background using CSS?When to use margin vs padding in CSSChange an HTML5 input's placeholder color with CSSHow do I auto-resize an image to fit a 'div' container?Make the cursor a hand when a user hovers over a list itemHow to decide when to use Node.js?Cannot display HTML string
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I'm making an image comparison feature. It's working fairly well, except that the images flicker when the front (blue) image is changing width. It appears to be some sort of issue with z-index
?
Behavior differs slightly depending on browser used:
Safari: flickers a bit
Chrome: flickers a lot
Firefox: shows the green image at all times
const $imageSlider = document.querySelector(".image-slider");
const $sliderHandle = $imageSlider.querySelector(".image-slider__handle");
const $container = $imageSlider.querySelector(".image-slider__container--left");
const handleMouseMove = event =>
const sliderPosition = `$(event.offsetX / $imageSlider.offsetWidth) * 100%`;
$container.style.width = sliderPosition;
$sliderHandle.style.left = sliderPosition;
;
$imageSlider.addEventListener("mousemove", event =>
requestAnimationFrame(() => handleMouseMove(event))
);
.image-slider
position: relative;
display: inline-block;
.image-slider__handle
content: " ";
position: absolute;
left: 50%;
top: 0;
bottom: 0;
display: block;
width: 0.25rem;
background-color: white;
transform: translateX(-50%);
.image-slider__container
height: 100%;
.image-slider__container--left
position: absolute;
width: 50%;
overflow: hidden;
.image-slider__image
display: block;
height: 100%;
<p>Move the mouse across the surface below to compare images:</p>
<div class="image-slider">
<div class="image-slider__container image-slider__container--left">
<img src="https://via.placeholder.com/200/0000FF/808080?text=Lorem" class="image-slider__image" alt="" />
</div>
<div class="image-slider__container image-slider__container--right">
<img src="https://via.placeholder.com/400/00FF00/808080?text=Ipsum" class="image-slider__image" alt="" />
</div>
<div class="image-slider__handle"></div>
</div>
javascript html css
add a comment |
I'm making an image comparison feature. It's working fairly well, except that the images flicker when the front (blue) image is changing width. It appears to be some sort of issue with z-index
?
Behavior differs slightly depending on browser used:
Safari: flickers a bit
Chrome: flickers a lot
Firefox: shows the green image at all times
const $imageSlider = document.querySelector(".image-slider");
const $sliderHandle = $imageSlider.querySelector(".image-slider__handle");
const $container = $imageSlider.querySelector(".image-slider__container--left");
const handleMouseMove = event =>
const sliderPosition = `$(event.offsetX / $imageSlider.offsetWidth) * 100%`;
$container.style.width = sliderPosition;
$sliderHandle.style.left = sliderPosition;
;
$imageSlider.addEventListener("mousemove", event =>
requestAnimationFrame(() => handleMouseMove(event))
);
.image-slider
position: relative;
display: inline-block;
.image-slider__handle
content: " ";
position: absolute;
left: 50%;
top: 0;
bottom: 0;
display: block;
width: 0.25rem;
background-color: white;
transform: translateX(-50%);
.image-slider__container
height: 100%;
.image-slider__container--left
position: absolute;
width: 50%;
overflow: hidden;
.image-slider__image
display: block;
height: 100%;
<p>Move the mouse across the surface below to compare images:</p>
<div class="image-slider">
<div class="image-slider__container image-slider__container--left">
<img src="https://via.placeholder.com/200/0000FF/808080?text=Lorem" class="image-slider__image" alt="" />
</div>
<div class="image-slider__container image-slider__container--right">
<img src="https://via.placeholder.com/400/00FF00/808080?text=Ipsum" class="image-slider__image" alt="" />
</div>
<div class="image-slider__handle"></div>
</div>
javascript html css
When moving the mouse very gently just a bit to the right/left the blue image disappears completely..
– iLuvLogix
Mar 27 at 14:47
@iLuvLogix Yes, that happens too.
– jlowgren
Mar 27 at 14:47
1
it works better if you don't format your string then checkif (sliderPosition > 1)
, if that passes then format and set your style values. Like this demo
– zgood
Mar 27 at 15:01
add a comment |
I'm making an image comparison feature. It's working fairly well, except that the images flicker when the front (blue) image is changing width. It appears to be some sort of issue with z-index
?
Behavior differs slightly depending on browser used:
Safari: flickers a bit
Chrome: flickers a lot
Firefox: shows the green image at all times
const $imageSlider = document.querySelector(".image-slider");
const $sliderHandle = $imageSlider.querySelector(".image-slider__handle");
const $container = $imageSlider.querySelector(".image-slider__container--left");
const handleMouseMove = event =>
const sliderPosition = `$(event.offsetX / $imageSlider.offsetWidth) * 100%`;
$container.style.width = sliderPosition;
$sliderHandle.style.left = sliderPosition;
;
$imageSlider.addEventListener("mousemove", event =>
requestAnimationFrame(() => handleMouseMove(event))
);
.image-slider
position: relative;
display: inline-block;
.image-slider__handle
content: " ";
position: absolute;
left: 50%;
top: 0;
bottom: 0;
display: block;
width: 0.25rem;
background-color: white;
transform: translateX(-50%);
.image-slider__container
height: 100%;
.image-slider__container--left
position: absolute;
width: 50%;
overflow: hidden;
.image-slider__image
display: block;
height: 100%;
<p>Move the mouse across the surface below to compare images:</p>
<div class="image-slider">
<div class="image-slider__container image-slider__container--left">
<img src="https://via.placeholder.com/200/0000FF/808080?text=Lorem" class="image-slider__image" alt="" />
</div>
<div class="image-slider__container image-slider__container--right">
<img src="https://via.placeholder.com/400/00FF00/808080?text=Ipsum" class="image-slider__image" alt="" />
</div>
<div class="image-slider__handle"></div>
</div>
javascript html css
I'm making an image comparison feature. It's working fairly well, except that the images flicker when the front (blue) image is changing width. It appears to be some sort of issue with z-index
?
Behavior differs slightly depending on browser used:
Safari: flickers a bit
Chrome: flickers a lot
Firefox: shows the green image at all times
const $imageSlider = document.querySelector(".image-slider");
const $sliderHandle = $imageSlider.querySelector(".image-slider__handle");
const $container = $imageSlider.querySelector(".image-slider__container--left");
const handleMouseMove = event =>
const sliderPosition = `$(event.offsetX / $imageSlider.offsetWidth) * 100%`;
$container.style.width = sliderPosition;
$sliderHandle.style.left = sliderPosition;
;
$imageSlider.addEventListener("mousemove", event =>
requestAnimationFrame(() => handleMouseMove(event))
);
.image-slider
position: relative;
display: inline-block;
.image-slider__handle
content: " ";
position: absolute;
left: 50%;
top: 0;
bottom: 0;
display: block;
width: 0.25rem;
background-color: white;
transform: translateX(-50%);
.image-slider__container
height: 100%;
.image-slider__container--left
position: absolute;
width: 50%;
overflow: hidden;
.image-slider__image
display: block;
height: 100%;
<p>Move the mouse across the surface below to compare images:</p>
<div class="image-slider">
<div class="image-slider__container image-slider__container--left">
<img src="https://via.placeholder.com/200/0000FF/808080?text=Lorem" class="image-slider__image" alt="" />
</div>
<div class="image-slider__container image-slider__container--right">
<img src="https://via.placeholder.com/400/00FF00/808080?text=Ipsum" class="image-slider__image" alt="" />
</div>
<div class="image-slider__handle"></div>
</div>
const $imageSlider = document.querySelector(".image-slider");
const $sliderHandle = $imageSlider.querySelector(".image-slider__handle");
const $container = $imageSlider.querySelector(".image-slider__container--left");
const handleMouseMove = event =>
const sliderPosition = `$(event.offsetX / $imageSlider.offsetWidth) * 100%`;
$container.style.width = sliderPosition;
$sliderHandle.style.left = sliderPosition;
;
$imageSlider.addEventListener("mousemove", event =>
requestAnimationFrame(() => handleMouseMove(event))
);
.image-slider
position: relative;
display: inline-block;
.image-slider__handle
content: " ";
position: absolute;
left: 50%;
top: 0;
bottom: 0;
display: block;
width: 0.25rem;
background-color: white;
transform: translateX(-50%);
.image-slider__container
height: 100%;
.image-slider__container--left
position: absolute;
width: 50%;
overflow: hidden;
.image-slider__image
display: block;
height: 100%;
<p>Move the mouse across the surface below to compare images:</p>
<div class="image-slider">
<div class="image-slider__container image-slider__container--left">
<img src="https://via.placeholder.com/200/0000FF/808080?text=Lorem" class="image-slider__image" alt="" />
</div>
<div class="image-slider__container image-slider__container--right">
<img src="https://via.placeholder.com/400/00FF00/808080?text=Ipsum" class="image-slider__image" alt="" />
</div>
<div class="image-slider__handle"></div>
</div>
const $imageSlider = document.querySelector(".image-slider");
const $sliderHandle = $imageSlider.querySelector(".image-slider__handle");
const $container = $imageSlider.querySelector(".image-slider__container--left");
const handleMouseMove = event =>
const sliderPosition = `$(event.offsetX / $imageSlider.offsetWidth) * 100%`;
$container.style.width = sliderPosition;
$sliderHandle.style.left = sliderPosition;
;
$imageSlider.addEventListener("mousemove", event =>
requestAnimationFrame(() => handleMouseMove(event))
);
.image-slider
position: relative;
display: inline-block;
.image-slider__handle
content: " ";
position: absolute;
left: 50%;
top: 0;
bottom: 0;
display: block;
width: 0.25rem;
background-color: white;
transform: translateX(-50%);
.image-slider__container
height: 100%;
.image-slider__container--left
position: absolute;
width: 50%;
overflow: hidden;
.image-slider__image
display: block;
height: 100%;
<p>Move the mouse across the surface below to compare images:</p>
<div class="image-slider">
<div class="image-slider__container image-slider__container--left">
<img src="https://via.placeholder.com/200/0000FF/808080?text=Lorem" class="image-slider__image" alt="" />
</div>
<div class="image-slider__container image-slider__container--right">
<img src="https://via.placeholder.com/400/00FF00/808080?text=Ipsum" class="image-slider__image" alt="" />
</div>
<div class="image-slider__handle"></div>
</div>
javascript html css
javascript html css
edited Mar 27 at 17:54
JGallardo
6,9904 gold badges57 silver badges70 bronze badges
6,9904 gold badges57 silver badges70 bronze badges
asked Mar 27 at 14:45
jlowgrenjlowgren
3,1413 gold badges21 silver badges39 bronze badges
3,1413 gold badges21 silver badges39 bronze badges
When moving the mouse very gently just a bit to the right/left the blue image disappears completely..
– iLuvLogix
Mar 27 at 14:47
@iLuvLogix Yes, that happens too.
– jlowgren
Mar 27 at 14:47
1
it works better if you don't format your string then checkif (sliderPosition > 1)
, if that passes then format and set your style values. Like this demo
– zgood
Mar 27 at 15:01
add a comment |
When moving the mouse very gently just a bit to the right/left the blue image disappears completely..
– iLuvLogix
Mar 27 at 14:47
@iLuvLogix Yes, that happens too.
– jlowgren
Mar 27 at 14:47
1
it works better if you don't format your string then checkif (sliderPosition > 1)
, if that passes then format and set your style values. Like this demo
– zgood
Mar 27 at 15:01
When moving the mouse very gently just a bit to the right/left the blue image disappears completely..
– iLuvLogix
Mar 27 at 14:47
When moving the mouse very gently just a bit to the right/left the blue image disappears completely..
– iLuvLogix
Mar 27 at 14:47
@iLuvLogix Yes, that happens too.
– jlowgren
Mar 27 at 14:47
@iLuvLogix Yes, that happens too.
– jlowgren
Mar 27 at 14:47
1
1
it works better if you don't format your string then check
if (sliderPosition > 1)
, if that passes then format and set your style values. Like this demo– zgood
Mar 27 at 15:01
it works better if you don't format your string then check
if (sliderPosition > 1)
, if that passes then format and set your style values. Like this demo– zgood
Mar 27 at 15:01
add a comment |
2 Answers
2
active
oldest
votes
The flickering is caused by affecting the "hoveredness" of the image slider in logic that runs upon hover. Hovering the slider moves the handle under the mouse, and the handle now intercepts the hover event, causing further hovers to have their offset values calculated relative to the handle, not the slider. And as soon as the mouse moves off the handle, it again correctly causes a mousemove
event on the slider.
This is easily fixed by applying pointer-events: none
to all elements which may block (and intercept) the pointer event.
Pardon the change in convention - I renamed some of the classes for myself.
const imageSlider = document.querySelector('.slider');
const sliderHandle = imageSlider.querySelector('.handle');
const container = imageSlider.querySelector('.pane.left');
imageSlider.addEventListener('mousemove', event =>
const sliderPosition = `$(event.offsetX / imageSlider.offsetWidth) * 100%`;
container.style.width = sliderPosition;
sliderHandle.style.left = sliderPosition;
);
.slider
position: relative;
display: inline-block;
.slider > .handle
content: " ";
position: absolute;
left: 50%;
top: 0;
bottom: 0;
display: block;
width: 0.25rem;
background-color: white;
transform: translateX(-50%);
pointer-events: none; /* Don't block mouse events to .slider! */
.slider > .pane
height: 100%;
pointer-events: none; /* Don't block mouse events to .slider! */
.slider > .pane.left
position: absolute;
width: 50%;
overflow: hidden;
.slider > .pane > img
display: block;
height: 100%;
<p>Move the mouse across the surface below to compare images:</p>
<div class="slider">
<div class="pane left">
<img src="https://via.placeholder.com/200/0000FF/808080?text=Lorem" alt="" />
</div>
<div class="pane right">
<img src="https://via.placeholder.com/400/00FF00/808080?text=Ipsum" alt="" />
</div>
<div class="handle"></div>
</div>
While conventions can be argued back and forth, the fix itself is the most suitable, even if the other answers and comments also have been very helpful. Thanks!
– jlowgren
Mar 27 at 17:46
Aha thanks for the link to BEM! Now I see there is method to the madness.
– Gershom Maes
Mar 27 at 17:50
add a comment |
I would consider an easier way using multiple background and less of code. By using background-clip
and content-box
I can adjust the visible part by increasing decreasing the padding:
const $imageSlider = document.querySelector(".image-slider");
const handleMouseMove = event =>
$imageSlider.style.paddingLeft = event.offsetX+"px";
;
$imageSlider.addEventListener("mousemove", event =>
requestAnimationFrame(() => handleMouseMove(event))
);
.image-slider
width:400px;
height:200px;
background:
/*a white line(width:4px height:100%) positionned on the left of the content-box*/
linear-gradient(#fff,#fff) left/4px 100% content-box,
/*the top image a the center clipped to the content-box but positionned relatively to the padding-box*/
url(https://via.placeholder.com/200/0000FF/808080?text=Lorem) center/cover padding-box content-box,
url(https://via.placeholder.com/200/00FF00/808080?text=Ipsum) center/cover;
background-repeat:no-repeat;
box-sizing:border-box;
<p>Move the mouse across the surface below to compare images:</p>
<div class="image-slider">
</div>
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55380043%2fsuperimposed-images-flicker-when-changing-width%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
The flickering is caused by affecting the "hoveredness" of the image slider in logic that runs upon hover. Hovering the slider moves the handle under the mouse, and the handle now intercepts the hover event, causing further hovers to have their offset values calculated relative to the handle, not the slider. And as soon as the mouse moves off the handle, it again correctly causes a mousemove
event on the slider.
This is easily fixed by applying pointer-events: none
to all elements which may block (and intercept) the pointer event.
Pardon the change in convention - I renamed some of the classes for myself.
const imageSlider = document.querySelector('.slider');
const sliderHandle = imageSlider.querySelector('.handle');
const container = imageSlider.querySelector('.pane.left');
imageSlider.addEventListener('mousemove', event =>
const sliderPosition = `$(event.offsetX / imageSlider.offsetWidth) * 100%`;
container.style.width = sliderPosition;
sliderHandle.style.left = sliderPosition;
);
.slider
position: relative;
display: inline-block;
.slider > .handle
content: " ";
position: absolute;
left: 50%;
top: 0;
bottom: 0;
display: block;
width: 0.25rem;
background-color: white;
transform: translateX(-50%);
pointer-events: none; /* Don't block mouse events to .slider! */
.slider > .pane
height: 100%;
pointer-events: none; /* Don't block mouse events to .slider! */
.slider > .pane.left
position: absolute;
width: 50%;
overflow: hidden;
.slider > .pane > img
display: block;
height: 100%;
<p>Move the mouse across the surface below to compare images:</p>
<div class="slider">
<div class="pane left">
<img src="https://via.placeholder.com/200/0000FF/808080?text=Lorem" alt="" />
</div>
<div class="pane right">
<img src="https://via.placeholder.com/400/00FF00/808080?text=Ipsum" alt="" />
</div>
<div class="handle"></div>
</div>
While conventions can be argued back and forth, the fix itself is the most suitable, even if the other answers and comments also have been very helpful. Thanks!
– jlowgren
Mar 27 at 17:46
Aha thanks for the link to BEM! Now I see there is method to the madness.
– Gershom Maes
Mar 27 at 17:50
add a comment |
The flickering is caused by affecting the "hoveredness" of the image slider in logic that runs upon hover. Hovering the slider moves the handle under the mouse, and the handle now intercepts the hover event, causing further hovers to have their offset values calculated relative to the handle, not the slider. And as soon as the mouse moves off the handle, it again correctly causes a mousemove
event on the slider.
This is easily fixed by applying pointer-events: none
to all elements which may block (and intercept) the pointer event.
Pardon the change in convention - I renamed some of the classes for myself.
const imageSlider = document.querySelector('.slider');
const sliderHandle = imageSlider.querySelector('.handle');
const container = imageSlider.querySelector('.pane.left');
imageSlider.addEventListener('mousemove', event =>
const sliderPosition = `$(event.offsetX / imageSlider.offsetWidth) * 100%`;
container.style.width = sliderPosition;
sliderHandle.style.left = sliderPosition;
);
.slider
position: relative;
display: inline-block;
.slider > .handle
content: " ";
position: absolute;
left: 50%;
top: 0;
bottom: 0;
display: block;
width: 0.25rem;
background-color: white;
transform: translateX(-50%);
pointer-events: none; /* Don't block mouse events to .slider! */
.slider > .pane
height: 100%;
pointer-events: none; /* Don't block mouse events to .slider! */
.slider > .pane.left
position: absolute;
width: 50%;
overflow: hidden;
.slider > .pane > img
display: block;
height: 100%;
<p>Move the mouse across the surface below to compare images:</p>
<div class="slider">
<div class="pane left">
<img src="https://via.placeholder.com/200/0000FF/808080?text=Lorem" alt="" />
</div>
<div class="pane right">
<img src="https://via.placeholder.com/400/00FF00/808080?text=Ipsum" alt="" />
</div>
<div class="handle"></div>
</div>
While conventions can be argued back and forth, the fix itself is the most suitable, even if the other answers and comments also have been very helpful. Thanks!
– jlowgren
Mar 27 at 17:46
Aha thanks for the link to BEM! Now I see there is method to the madness.
– Gershom Maes
Mar 27 at 17:50
add a comment |
The flickering is caused by affecting the "hoveredness" of the image slider in logic that runs upon hover. Hovering the slider moves the handle under the mouse, and the handle now intercepts the hover event, causing further hovers to have their offset values calculated relative to the handle, not the slider. And as soon as the mouse moves off the handle, it again correctly causes a mousemove
event on the slider.
This is easily fixed by applying pointer-events: none
to all elements which may block (and intercept) the pointer event.
Pardon the change in convention - I renamed some of the classes for myself.
const imageSlider = document.querySelector('.slider');
const sliderHandle = imageSlider.querySelector('.handle');
const container = imageSlider.querySelector('.pane.left');
imageSlider.addEventListener('mousemove', event =>
const sliderPosition = `$(event.offsetX / imageSlider.offsetWidth) * 100%`;
container.style.width = sliderPosition;
sliderHandle.style.left = sliderPosition;
);
.slider
position: relative;
display: inline-block;
.slider > .handle
content: " ";
position: absolute;
left: 50%;
top: 0;
bottom: 0;
display: block;
width: 0.25rem;
background-color: white;
transform: translateX(-50%);
pointer-events: none; /* Don't block mouse events to .slider! */
.slider > .pane
height: 100%;
pointer-events: none; /* Don't block mouse events to .slider! */
.slider > .pane.left
position: absolute;
width: 50%;
overflow: hidden;
.slider > .pane > img
display: block;
height: 100%;
<p>Move the mouse across the surface below to compare images:</p>
<div class="slider">
<div class="pane left">
<img src="https://via.placeholder.com/200/0000FF/808080?text=Lorem" alt="" />
</div>
<div class="pane right">
<img src="https://via.placeholder.com/400/00FF00/808080?text=Ipsum" alt="" />
</div>
<div class="handle"></div>
</div>
The flickering is caused by affecting the "hoveredness" of the image slider in logic that runs upon hover. Hovering the slider moves the handle under the mouse, and the handle now intercepts the hover event, causing further hovers to have their offset values calculated relative to the handle, not the slider. And as soon as the mouse moves off the handle, it again correctly causes a mousemove
event on the slider.
This is easily fixed by applying pointer-events: none
to all elements which may block (and intercept) the pointer event.
Pardon the change in convention - I renamed some of the classes for myself.
const imageSlider = document.querySelector('.slider');
const sliderHandle = imageSlider.querySelector('.handle');
const container = imageSlider.querySelector('.pane.left');
imageSlider.addEventListener('mousemove', event =>
const sliderPosition = `$(event.offsetX / imageSlider.offsetWidth) * 100%`;
container.style.width = sliderPosition;
sliderHandle.style.left = sliderPosition;
);
.slider
position: relative;
display: inline-block;
.slider > .handle
content: " ";
position: absolute;
left: 50%;
top: 0;
bottom: 0;
display: block;
width: 0.25rem;
background-color: white;
transform: translateX(-50%);
pointer-events: none; /* Don't block mouse events to .slider! */
.slider > .pane
height: 100%;
pointer-events: none; /* Don't block mouse events to .slider! */
.slider > .pane.left
position: absolute;
width: 50%;
overflow: hidden;
.slider > .pane > img
display: block;
height: 100%;
<p>Move the mouse across the surface below to compare images:</p>
<div class="slider">
<div class="pane left">
<img src="https://via.placeholder.com/200/0000FF/808080?text=Lorem" alt="" />
</div>
<div class="pane right">
<img src="https://via.placeholder.com/400/00FF00/808080?text=Ipsum" alt="" />
</div>
<div class="handle"></div>
</div>
const imageSlider = document.querySelector('.slider');
const sliderHandle = imageSlider.querySelector('.handle');
const container = imageSlider.querySelector('.pane.left');
imageSlider.addEventListener('mousemove', event =>
const sliderPosition = `$(event.offsetX / imageSlider.offsetWidth) * 100%`;
container.style.width = sliderPosition;
sliderHandle.style.left = sliderPosition;
);
.slider
position: relative;
display: inline-block;
.slider > .handle
content: " ";
position: absolute;
left: 50%;
top: 0;
bottom: 0;
display: block;
width: 0.25rem;
background-color: white;
transform: translateX(-50%);
pointer-events: none; /* Don't block mouse events to .slider! */
.slider > .pane
height: 100%;
pointer-events: none; /* Don't block mouse events to .slider! */
.slider > .pane.left
position: absolute;
width: 50%;
overflow: hidden;
.slider > .pane > img
display: block;
height: 100%;
<p>Move the mouse across the surface below to compare images:</p>
<div class="slider">
<div class="pane left">
<img src="https://via.placeholder.com/200/0000FF/808080?text=Lorem" alt="" />
</div>
<div class="pane right">
<img src="https://via.placeholder.com/400/00FF00/808080?text=Ipsum" alt="" />
</div>
<div class="handle"></div>
</div>
const imageSlider = document.querySelector('.slider');
const sliderHandle = imageSlider.querySelector('.handle');
const container = imageSlider.querySelector('.pane.left');
imageSlider.addEventListener('mousemove', event =>
const sliderPosition = `$(event.offsetX / imageSlider.offsetWidth) * 100%`;
container.style.width = sliderPosition;
sliderHandle.style.left = sliderPosition;
);
.slider
position: relative;
display: inline-block;
.slider > .handle
content: " ";
position: absolute;
left: 50%;
top: 0;
bottom: 0;
display: block;
width: 0.25rem;
background-color: white;
transform: translateX(-50%);
pointer-events: none; /* Don't block mouse events to .slider! */
.slider > .pane
height: 100%;
pointer-events: none; /* Don't block mouse events to .slider! */
.slider > .pane.left
position: absolute;
width: 50%;
overflow: hidden;
.slider > .pane > img
display: block;
height: 100%;
<p>Move the mouse across the surface below to compare images:</p>
<div class="slider">
<div class="pane left">
<img src="https://via.placeholder.com/200/0000FF/808080?text=Lorem" alt="" />
</div>
<div class="pane right">
<img src="https://via.placeholder.com/400/00FF00/808080?text=Ipsum" alt="" />
</div>
<div class="handle"></div>
</div>
edited Mar 27 at 17:49
answered Mar 27 at 15:57
Gershom MaesGershom Maes
2,20914 silver badges32 bronze badges
2,20914 silver badges32 bronze badges
While conventions can be argued back and forth, the fix itself is the most suitable, even if the other answers and comments also have been very helpful. Thanks!
– jlowgren
Mar 27 at 17:46
Aha thanks for the link to BEM! Now I see there is method to the madness.
– Gershom Maes
Mar 27 at 17:50
add a comment |
While conventions can be argued back and forth, the fix itself is the most suitable, even if the other answers and comments also have been very helpful. Thanks!
– jlowgren
Mar 27 at 17:46
Aha thanks for the link to BEM! Now I see there is method to the madness.
– Gershom Maes
Mar 27 at 17:50
While conventions can be argued back and forth, the fix itself is the most suitable, even if the other answers and comments also have been very helpful. Thanks!
– jlowgren
Mar 27 at 17:46
While conventions can be argued back and forth, the fix itself is the most suitable, even if the other answers and comments also have been very helpful. Thanks!
– jlowgren
Mar 27 at 17:46
Aha thanks for the link to BEM! Now I see there is method to the madness.
– Gershom Maes
Mar 27 at 17:50
Aha thanks for the link to BEM! Now I see there is method to the madness.
– Gershom Maes
Mar 27 at 17:50
add a comment |
I would consider an easier way using multiple background and less of code. By using background-clip
and content-box
I can adjust the visible part by increasing decreasing the padding:
const $imageSlider = document.querySelector(".image-slider");
const handleMouseMove = event =>
$imageSlider.style.paddingLeft = event.offsetX+"px";
;
$imageSlider.addEventListener("mousemove", event =>
requestAnimationFrame(() => handleMouseMove(event))
);
.image-slider
width:400px;
height:200px;
background:
/*a white line(width:4px height:100%) positionned on the left of the content-box*/
linear-gradient(#fff,#fff) left/4px 100% content-box,
/*the top image a the center clipped to the content-box but positionned relatively to the padding-box*/
url(https://via.placeholder.com/200/0000FF/808080?text=Lorem) center/cover padding-box content-box,
url(https://via.placeholder.com/200/00FF00/808080?text=Ipsum) center/cover;
background-repeat:no-repeat;
box-sizing:border-box;
<p>Move the mouse across the surface below to compare images:</p>
<div class="image-slider">
</div>
add a comment |
I would consider an easier way using multiple background and less of code. By using background-clip
and content-box
I can adjust the visible part by increasing decreasing the padding:
const $imageSlider = document.querySelector(".image-slider");
const handleMouseMove = event =>
$imageSlider.style.paddingLeft = event.offsetX+"px";
;
$imageSlider.addEventListener("mousemove", event =>
requestAnimationFrame(() => handleMouseMove(event))
);
.image-slider
width:400px;
height:200px;
background:
/*a white line(width:4px height:100%) positionned on the left of the content-box*/
linear-gradient(#fff,#fff) left/4px 100% content-box,
/*the top image a the center clipped to the content-box but positionned relatively to the padding-box*/
url(https://via.placeholder.com/200/0000FF/808080?text=Lorem) center/cover padding-box content-box,
url(https://via.placeholder.com/200/00FF00/808080?text=Ipsum) center/cover;
background-repeat:no-repeat;
box-sizing:border-box;
<p>Move the mouse across the surface below to compare images:</p>
<div class="image-slider">
</div>
add a comment |
I would consider an easier way using multiple background and less of code. By using background-clip
and content-box
I can adjust the visible part by increasing decreasing the padding:
const $imageSlider = document.querySelector(".image-slider");
const handleMouseMove = event =>
$imageSlider.style.paddingLeft = event.offsetX+"px";
;
$imageSlider.addEventListener("mousemove", event =>
requestAnimationFrame(() => handleMouseMove(event))
);
.image-slider
width:400px;
height:200px;
background:
/*a white line(width:4px height:100%) positionned on the left of the content-box*/
linear-gradient(#fff,#fff) left/4px 100% content-box,
/*the top image a the center clipped to the content-box but positionned relatively to the padding-box*/
url(https://via.placeholder.com/200/0000FF/808080?text=Lorem) center/cover padding-box content-box,
url(https://via.placeholder.com/200/00FF00/808080?text=Ipsum) center/cover;
background-repeat:no-repeat;
box-sizing:border-box;
<p>Move the mouse across the surface below to compare images:</p>
<div class="image-slider">
</div>
I would consider an easier way using multiple background and less of code. By using background-clip
and content-box
I can adjust the visible part by increasing decreasing the padding:
const $imageSlider = document.querySelector(".image-slider");
const handleMouseMove = event =>
$imageSlider.style.paddingLeft = event.offsetX+"px";
;
$imageSlider.addEventListener("mousemove", event =>
requestAnimationFrame(() => handleMouseMove(event))
);
.image-slider
width:400px;
height:200px;
background:
/*a white line(width:4px height:100%) positionned on the left of the content-box*/
linear-gradient(#fff,#fff) left/4px 100% content-box,
/*the top image a the center clipped to the content-box but positionned relatively to the padding-box*/
url(https://via.placeholder.com/200/0000FF/808080?text=Lorem) center/cover padding-box content-box,
url(https://via.placeholder.com/200/00FF00/808080?text=Ipsum) center/cover;
background-repeat:no-repeat;
box-sizing:border-box;
<p>Move the mouse across the surface below to compare images:</p>
<div class="image-slider">
</div>
const $imageSlider = document.querySelector(".image-slider");
const handleMouseMove = event =>
$imageSlider.style.paddingLeft = event.offsetX+"px";
;
$imageSlider.addEventListener("mousemove", event =>
requestAnimationFrame(() => handleMouseMove(event))
);
.image-slider
width:400px;
height:200px;
background:
/*a white line(width:4px height:100%) positionned on the left of the content-box*/
linear-gradient(#fff,#fff) left/4px 100% content-box,
/*the top image a the center clipped to the content-box but positionned relatively to the padding-box*/
url(https://via.placeholder.com/200/0000FF/808080?text=Lorem) center/cover padding-box content-box,
url(https://via.placeholder.com/200/00FF00/808080?text=Ipsum) center/cover;
background-repeat:no-repeat;
box-sizing:border-box;
<p>Move the mouse across the surface below to compare images:</p>
<div class="image-slider">
</div>
const $imageSlider = document.querySelector(".image-slider");
const handleMouseMove = event =>
$imageSlider.style.paddingLeft = event.offsetX+"px";
;
$imageSlider.addEventListener("mousemove", event =>
requestAnimationFrame(() => handleMouseMove(event))
);
.image-slider
width:400px;
height:200px;
background:
/*a white line(width:4px height:100%) positionned on the left of the content-box*/
linear-gradient(#fff,#fff) left/4px 100% content-box,
/*the top image a the center clipped to the content-box but positionned relatively to the padding-box*/
url(https://via.placeholder.com/200/0000FF/808080?text=Lorem) center/cover padding-box content-box,
url(https://via.placeholder.com/200/00FF00/808080?text=Ipsum) center/cover;
background-repeat:no-repeat;
box-sizing:border-box;
<p>Move the mouse across the surface below to compare images:</p>
<div class="image-slider">
</div>
edited Mar 27 at 15:14
answered Mar 27 at 15:06
Temani AfifTemani Afif
99.7k11 gold badges64 silver badges112 bronze badges
99.7k11 gold badges64 silver badges112 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55380043%2fsuperimposed-images-flicker-when-changing-width%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
When moving the mouse very gently just a bit to the right/left the blue image disappears completely..
– iLuvLogix
Mar 27 at 14:47
@iLuvLogix Yes, that happens too.
– jlowgren
Mar 27 at 14:47
1
it works better if you don't format your string then check
if (sliderPosition > 1)
, if that passes then format and set your style values. Like this demo– zgood
Mar 27 at 15:01