How to center and keep focus on Modal image using mobile

html5
css3

#1

I am using a modal to display large res versions of images when viewing on mobile. This way the user can choose whether to load the larger file as well as examine the image in more detail.

You can see the webpage that has the problem on mobile https://glewindesign.com/project_1.html

The 1st issue is that my image is larger than the modal container as well as the viewport. I want it that way with the scroll bars so the user can just use their finger to move around and examine the full size image, no need to pinch/zoom.

Because the image is larger though, I am having trouble centering it. No matter what CSS centering tricks I try, it always loads at the top left of the image.

The 2nd problem is focus not being properly trapped in the modal.

When I am scrolling through the high res image, sometimes there is a glitch where the user interacts with the area behind the modal? I notice it when I quickly scroll downwards. Sometimes the fixed footer menu will appear.

I used this tutorial

and I was utilizing the overlay which I thought would prevent interaction with elements behind the modal, but like I said I still encounter the issue of the fixed footer appearing sometimes.

Any advice regarding this would be greatly appreciated!


How to change position of scrollbar on modal window opening
#2

You can centre an image that is smaller than the containing block but you can't centre an image that is larger than its containing block because it will just sit the top left of the block as you found out.

At the point the image becomes larger than the containing block a scrollbar will appear horizontally or vertically in order for you to see the rest of the image which is sticking out the right and bottom of your div.

Although we could force the image to be centred there is no scroll mechanism to let you see images that are shifted out to the left or above the top. For example if you forced the image to be central by absolutely placing its centre in the centre (top:50%;left:50%;transform:translate:(-50%)). That would mean the image would be centred but you could not scroll to see the parts sticking out the left and top.

It seems to me that the only solution is to use some JS when the modal is called and automatically set the scrollbar position to the 50% mark both horizontally and vertically. In that way the image would appear centred when loaded and the user could scroll in any direction.

e.g. This screenshot explains the effect.

I'm not sure if that is feasible or not (or whether the touch scroll mechanism will be too hard to program).


#3

Paul,

Thank you for taking the time to explain that to me I really appreciate it!

It makes me feel better knowing its simply not possible with CSS, I have been trying so many different variations trying to make it work!

I will ask about positioning the scrollbars using javascript in the javascript part of the forums as well as do some research on the web to see if someone has figured that out.

Thanks a lot,


#4

I don't want to comment on your js thread as that may derail the topic but here is my attempt at doing the centring with js.

http://www.pmob.co.uk/temp2/mobile-center-scroll.html

Just view source as all the code is in the page. The yellow square on the image is the exact center of the image so if its working it should show in the centre when loaded. Of course if you resize the page you would need to call the script again but I doubt that will be an issue on mobile. You can test by resizing the window and then refreshing and calling the modal again.

I also added a class to the html element when the modal is active to hide the scrollbars on html and body so the rest of the page doesn't scroll accidentally.

It needs thorough testing with different sized images to make sure its working. You would also need to run the code when the modal is called and detect the image that was being used but as proof of concept it seems feasible.

Here's an example with different sized images integrated into a modal.

I'd still wait for more specific help in the js forum but it may get you started.:slight_smile:


#5

Paul, this is fantastic. Thank you for your time and effort. I only know some HTML and CSS so your expertise has really saved me!

I have updated my website with your code and script.

The centering script you made works great! :smiley: https://glewindesign.com/project_1.html

It seems like although you fixed the scrolling the content behind the open modal issue, a related bug appeared.

When I use google chrome and scroll around the image, it sometimes will still show the body content holding the fixed navbar that is behind the modal. It appears right where the google address bar is. When you scroll up and down, that address bar disappears to show more of the image and when that happens it will briefly show content from behind the modal?

This does not seem to happen in firefox, but the address bar does not disappear in firefox, it is in a fixed position.

So I am not exactly sure why this is happening or how to prevent it...But it seems like it has to do with google chrome having their disappearing address bar on scroll.

Also, do you think it would be possible to call the script again if I change the view from portrait to landscape on the mobile device? I ask because when I think about how users will interact, they will probably be holding their phone in portrait, click on an image, the modal opens and is centered still in portrait mode, then the user will probably position their phone to landscape mode for better viewing. When that happens it would be great if the script was activated again, because otherwise all that centering effort is not really appreciated when the image changes to landscape view.

I am wondering if this is what I should try out https://developer.mozilla.org/en-US/docs/Web/API/Detecting_device_orientation

Thanks again Paul!


#6

I think you are talking about the standard bounce effect that ios allows you to scroll further than the height of the element. It happens at both the top and bottom and is meant to show you you've reached the end of the scroll as it bounces back. The downside is that for a fixed element you get a glimpse of the content underneath.

There is an article here that talks about the issue. However I think the simplest thing to do is to wrap your page excluding the modal in a wrapper and when the modal is active set the opacity of the rest of the content to zero so that you can't see at all even if it does bounce.

.noOverflow, .noOverflow body {
	overflow:hidden;
}
.noOverflow .page-wrap{
	touch-action:none;
	opacity:0;
}

<div class="page-wrap">
<!-- all your page content here (excluding modal) -->
</div>

I have added that to my demo so you can test and see if id does what you wanted.

http://www.pmob.co.uk/temp2/mobile-center-scroll2.html

Yes you could tie the script into the orientation change but it may be better to tie it into the resize event so everyone gets the centred page and not just some devices.

I've added the script to my above demo although it does complicate things a little as there is also a throttle script to prevent triggering the resize too many times.


#7

Paul I have implemented your changes and they all work!

After looking at that article I agree the easiest fix seems to be the wrapper.

Thanks a lot for your time and patience.

I learned a lot but also realized how much more there is to learn, especially with javascript!

I will close the other question in the javascript forums as you have solved it here.


How to change position of scrollbar on modal window opening
#9

Hey Paul. I really like the way the mobile view functions but the friend I am making the website for would rather have the image not be initially zoomed in, instead relying on the browsers native pinch zoom capabilities.

So I tried keeping your script but reverting to the earlier version that does not have the resize event throttle script as that seemed unnecessary now.

I changed the .img properties to max-width:100% and that seemed to make things work as I wanted when I viewed it on google chrome on my mobile. The issue is when I viewed it on firefox on my mobile it was broken, it seems like the fixed elements of the modal are preventing the pinch zoom from working.

I made a page with all of the relevant code on it glewindesign.com/mobile-test1.html

Any ideas on the best way to fix this? Thanks a lot!


#10

That page seems to be blank or at least no way to trigger a modal to test.

You'd need to set the image height to auto and also remove all the resizing from the script as it seems you just want a standard modal now?

However if the image is taller than it is wider you will run into the issue you had before where the centre of the image will not be the center of the viewport. That means you would need to check if the image was taller than it is wider and then use height:100% and width:auto instead of width:100% and height:auto. (You may actually just be better off getting a modal script 'off-the-shelf' as there are loads of fully featured free ones around. :))

I don't have Firefox on a mobile but it may be something to do with the touch-action:none that was added so you could try removing that and see if it has an effect.

I am out most of today so won't have time to play around but I think you need to consider exactly what you want to happen as the example is set up for the way you originally wanted. Just changing one aspect for mobile is not that simple as you'd need to change the script based on viewport size which would mean using matchMedia I would think. It may be better just to have a standard modal image that scales to viewport for all devices.


#11

Paul,

Sorry that page had the code on it but was set to only appear on mobile.

You are right, the example you had made works perfectly for what I originally wanted.

It does sound like what I am wanting now is just a standard modal, I just want to make sure I still utilize the overflow and wrapper techniques you showed me.

I tried out your standard modal code and it seemed to be working great on mobile with chrome.

With firefox on mobile I did try to change the touch-action and it did allow me to pinch zoom but the issue where the fixed elements are all broken and oversized is still happening.

I actually spent a really long time troubleshooting this bug but the only way I got around that was by making the modal element positioning no longer fixed. That solved the zooming issue on firefox which is awesome but it seemed to cause another issue.

Now when I close the modal, the scroll bar jumps to the top of the page. This is problematic because of the stack of modal trigger links I am utilizing, it makes the user have to always scroll back down to the next image.

You can see it happening on this page where I changed the position from fixed to absolute for the modal, modal-content and close classes.

https://glewindesign.com/mobile-test4.html

Is there a solution perhaps with javascript I could apply to fix this scrolling issue and still keep the css property workaround I have for the firefox zoom issues?

I will look for other possible modal scripts as you suggest, but I feel like what you have created is accomplishing what I want.

Thanks a lot for your help!


#13

You could link back to the element that opened the modal but would mean adding unique ids to the triggers.,

e.g.

(function() {
  var imageWidth = 0;
  var imageHeight = 0;;
  var thisImg = "";
  var modalContent = $(".modal-content");
  var elHtml = $("html");
  var linkClicked ="";
  
  $(document).on("click", ".myBtn", function() {
    var myTargetModal = $(this).attr("href");
	linkClicked = '#' + $(this).attr("id");

    elHtml.addClass("noOverflow");
    $(myTargetModal).addClass("modalOn");
    $("#myModal").hide();
    modalContent.hide();
    $("#myModal").fadeIn();
    $(myTargetModal).fadeIn();
    findCenter();
    return false;
  });

  $("body").on("click", ".close", function() {
     window.location = linkClicked;    
    $("#myModal").hide();
    modalContent.hide().removeClass("modalOn");
    elHtml.removeClass("noOverflow");
  });

})()

<nav class="items"> <a id="link1" href="#a1" class="myBtn">Trigger Modal This one</a> <a id="link2" href="#a2" class="myBtn">Trigger Modal 2</a>  etc...

So start with id="link1" and then increase for every element that is a trigger for the modal. When the close button is clicked the window.location is set to that fragment identifier ( window.location = linkClicked;). That will direct the page back down to where it was.

I haven't had time to look at the zooming problem in Firefox but I know that mobiles always have a hard time with fixed positioned elements.


#14

Paul,

This works great! Definitely a good fix for the scrolling issue.

Yeah when I looked online there were definitely others struggling with fixed elements on zoom.

If you do ever discover the solution to the firefox zooming issue that would be awesome to know, but at least the modal is working now.

Thanks a lot for your help!


#15

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.