I have almost always used $(window).width() to check the viewport width. It normally works for both browsers and devices. But for a website on which I need to show a particular splash screen if viewport width is less than 768px, this is not working. It gives correct width upto a point but below that it keeps giving 980px howsoever narrow I make the browser. There are a few particular conditions for this site:
This site was responsive in beginning (using bootstrap) but then made non-responsive. For this we removed viewport meta tag and set following rule in css that overrides its responsive widths:
.container{ width: 1170px; }
If I resize the whole browser i.e. the window that contains all browser tabs, then it does give correct width (less than 980px also, which is the desired behaviour), but if I use development tools and use the mobile layouts from there then width is never reported to be below 980px.
It would not have mattered that it worked on resizing only the main browser window, but the issue is that it is not working in devices as well. I added an alert and on mobile devices, again width is never alerted to be less than 980px.
Can someone please suggest some solution for this or explain why it is not working as expected?
I can't seem to find any authoritative source, but there are many pages that mention smartphones assume a website is 980px wide unless told otherwise.
Apple's developer site for instance says
The majority of webpages fit nicely in the visible area with the viewport width set to 980 pixels in portrait orientation, as shown in Figure 3-4. If Safari on iOS did not set the viewport width to 980 pixels, then only the upper-left corner of the webpage, shown in gray, would be displayed. However, this default doesn’t work for all webpages, so you’ll want to use the viewport meta tag if your webpage is different. See Supported Meta Tags for more on viewport.
Figure 3-4 Comparison of 320 and 980 viewport widths
(Incidentally, it was the iPhone which first did this, but other phones soon followed.)
So the solution is either to put
<meta name="viewport" content="width=device-width">
into the head (in your case, back into the head), or, acknowledge that the site is now not-responsive, and will not perform optimally on a phone!
Related
As you could imagine, I'm trying to make my webpage responsive and mobile friendly.
I have an outer container on which I set the width dynamically using this hook (window.innerWidth). So to test if the page is responsive I open up Chrome-devtools and start making the devtools wider:
Sure it's a little jumpy but it scales correctly, as expected. The problem starts when I open up to do the same in the responsive tools:
Suddenly the whole page scales down? Also, it's hard to see but I'm logging window.innerWidth and it's not changing as I'm changing the width.
So I try it out on my cell-phone and the the behaviour is really unexpected:
On load it looks ok
Flip the phone, still as expected, but when I flip it back???
This crazy effect happens, I mean now it looks like window.innerHeight is having some trouble as well? Because the container with the gray background color has it's min-height set to window.innerHeight. And if i try going to some other page of the app and then back I get this:
It's a zoomed in version of the last image. I can pinche-zoom out from it.
So I google around and it looks like I find someone with the same problem there's a detailed answer suggesting I should use window.visualViewport.width instead. So I try it out:
Main differences, the resizing seem's a little jumpier. I'm also logging window.visualViewport.width and it is changing, but only slightly and it's not corresponding to the responsive-width that's shown above the screen.
But most importantly, it's unfortunately not fixing the problem of weirdly resizing the entire screen, and the unexpected behaviour on mobile remains. (should be mentioned that this one too, works as expected if I'm not in "responsive mode" and just resize the window.
So I spot another answer further down suggesting to use window.screen.width instead, so I try it out:
Which introduced a whole new type of wonkyness? It seems to scale correctly, but down at around a few pixels above 300 it starts to just cut-off a piece of the header while making the container (which should be the width of the screen) smaller at a faster rate than the screen?
This seem to be related to the fact that the header has the css:
grid-template-columns: 130px auto 130px;. If I lower the 130px-value, the point at which the header gets cut off lowers as well. I suppose making the screen go below the headers min-width causes some (in my opinion) really unexpected behaviour.
Though the console log (now logging window.screen.width, now correctly prints the width reported by chromes responsive tool. The bug can be seen in my phone as well
I guess my phone must be a few pixels below 300 in width. Interesting fact is that using 100vw displays exactly the same behaviour as using screen.width.
It's also interesting to look at the difference between screen.width, innerWidth and visualViewport.width. If I set the size of the responsive window to 500px and reload the window. All of them evaluates to 500px. If I set the screen to any value below the threshold where screen.width starts to cut off a piece of the screen.
screen.width evaluates to the width of the responsive window.
innerWidth and visualViewport.width will both evaluate to 309px (which I assume is the minimum functional width of the header.
If we look at how innerWidth and visualViewport.width looks on my phone:
On both visualViewport.width and innerWidth we can see a much smaller but similar line to the one on screen.width (here it can be seen on a zoomed in screenshot).
First solution
So the first and most straight forward solution would be to use window.screen.width (or 100vw) and simply make sure that no element ever push themselves outside the width of the screen.
But wait, another solution has appeared!
By looking at a comment to an answer of the previous question I see that someone solved it by changing the the viewport meta-tag from
<meta name="viewport" content="width=device-width, initial-scale=1" />
to
<meta name="viewport" content="width=device-width, minimum-scale=1" />
All alternatives, screen.width, innerWidth and visualViewport.width all now behave identically to each other and as desired:
They all log the correct width of the responsive window, the page on my mobile also works. If you look closely you can see that the header does get cut off a little when the screen goes below the 309-threshold. But with this solution it seems like the page breaks a lot more gracefully than in first solution.
So if you've already solved the problem, why are you posting this question?
Well, as you might have understood by now, I love this problem more than I love the solution. That is, I would really like to know WHY this solution works? So even though my "practical" problem is solved I'm really curious as to a few remaining mysteries:
Why does resizing the window (first video) behave differently from resizing the "responsive box" in chrome dev tools?
Why does the bug appear on my mobile when I tilt my phone, and then tilt it back again? (third picture)
Why, when I (on the phone) go into some page and back again, is the screen super zoomed in? (fourth picture)
Why does innerWidth and visualViewport.width continue to print the same value when resizing the responsive window.
Why do they weirdly scale down the whole screen instead of changing the size of the screen in the expected way (are they for some reason zooming out when making the responsive window smaller? Is that why setting minimum-scale=1 solves the issue?)
Why does screen.width behave differently from innerWidth and visualViewport.width? And why does it cause such a weird white-space effect when going below the minimum width of the header?
Are there any reason one wouldn't want to set minimum-scale=1?
On my website, I have a mobile version for devices below 980px, however I would like devices blow 570px only to see this and if they rotate their mobile device, for them to then be able to see the full site with their device scaling if needed.
Change my pages width to see the mobile version. This is what I want devices to see on portrait mode but in landscape I would like them to see full version. I thought about implementing tilt detection, however nowadays you can get 27" all-in-one touch computers which can tilt!
If you don't have the viewport tag included, then the page will render using the device resolution. That means it will likely return 980px not the css pixels you're expecting. This is the default value of most mobile browsers (on Android and iOS devices at least). So, trying to add the viewport tag by checking if the width of the window is less than 570px without already having the viewport content tag set to "width=device-width" would be fruitless. This is why your first attempt did not work.
Also, if you try and remove the viewport tag AFTER the page is already rendered (for instance, inside a $(document).ready(function () {}); it would remove the tag, but the page would be unaffected.
However, you can set the viewport tag to have a different content value. So, in this case, you'd include the <meta name="viewport" content="width=device-width, initial-scale=1.0"> on the page, then in your document ready, use jQuery to set the content attribute to default width value of 980px instead. Because the DOM is ready when you are checking the width of the window, changing the value of the content attribute will cause devices that honor this property to render the page at the default 980px. (This is horribly small on my iPhone5 and impossible to use, but you stated that you find it acceptable.)
//add this to your document ready function and make sure
//that the viewport is initially set to content="width=device-width"
var pageWidth = $(window).width();
if (pageWidth < 570) {
$('meta[name="viewport"]').prop('content', 'width=980px');
}
Why you don't have to worry about resize events:
For most current devices that you are targeting, the window width is not resizable and the resize event will not be triggered on orientation change because it's not a change in the width of the browser, rather it's a change in zoom level. On your desktop, however, the browser won't even care about the viewport meta tag at all, so, no matter what value you have there, it doesn't affect the behavior.
RE-EDIT:
I am in the process of making a 1 page site. This is for a school and will only be accessed internally (like a page for different links that staff can quickly use to navigate to).
However sometimes staff have different sized windows open, when they open IE (it will auto re-direct them to my HTML page) is it possible to make sure they open it as 100% width and height?
Thanks,
Nick
Ya you can have width and height to take up 100% space but it is not easy to design a page like that for all resolutions. As you have to exapnd and shrink content both in height and width it becomes complex.better have a fixed width and have height according to the resolution(Again a problem with retina display). Here are some browser statistics- Link.
you are concerned about your page on different resolutions of desktops and laptops. But the bigger problem would be mobiles and tablets as they do count for quite a lot of web-traffic.
Better way of handling the problem is to go with responsive design and target 2560×1600 and above 1366x768 for desktops and few mobile and tablet resolutions.
Here is a link for responsive design resourses- resourses
Liquid design isn't too difficult.
If you mean you want your page to open in a new tab or in the same already maximised tab, search for that; SO has that covered already.
Don't worry about height. Just make it fill the width and let the user scroll.
I have a web app that needs to be within a container of a fixed size. I want that container to always be completely visible on the screen of mobile devices. (Particularly I care about iPads.) In my case, the container is 1000px wide by 650px tall. Essentially, I need something that would be the functional equivalent of <meta name="viewport" content="min-width=1000, min-height=650">. But min-width and min-height aren't valid in a viewport meta tag.
I already have the page laid out such that if the window or viewport has extra room the content is displayed centered on the page. I've tried using the orientationchange event to change the content attribute of my meta tag, but no luck. With some configurations that I've tried it loads correctly initially (sometimes, refreshing or reopening the page often yields different results) but upon changing orientation it becomes incorrect.
This is the closest I've come to getting it to work (in the window.onOrientationChange event):
var mvp = document.getElementById('myViewport');
if(window.innerWidth / window.innerHeight > 1000 / 650) {
mvp.setAttribute('content',"user-scalable=yes, height=650");
} else {
mvp.setAttribute('content',"user-scalable=yes, width=1000");
}
Where of course #myViewport is my viewport meta tag. This works correctly in portrait (although when switching back and forth I have to manually zoom back out,) but doesn't add the extra width needed to zoom out to see the full app height in landscape. Also, I'd prefer not to allow users to zoom in and out because of the nature of the app, and certainly don't want to require them to zoom out every time they change orientation.
If there is a way to force the zoom to always fit to screen, something akin to minimum-scale=auto, maximum-scale=auto, it seems like that would work (if I could get the width correct in landscape,) but I don't know of such a mechanism. I also tried using javascript to determine the scale, based on window.outerHeight or window.outerWidth depending on which one is the determining factor, but that wasn't successful either.
And please don't tell me that this is bad design, because the specs come from the client for their internal-use app and there's nothing I can do about them.
I need to have my site fit exactly to the user's browser, this means any browser and any size of monitor. i need to have no scroll bars both vertical and horizontal
I want to do this in javascript/jquery
I have this code:
screen.width
screen.height
i also tried jquery :
$(window).height()
$(window).width()
also had scroll bars.
Is this the only way?? cuz when i used it on my site, i had scroll bars both vertical and horizontal. it was to big.
Can any one please help?
It's impossible.
No way you'd be able to fit your content to all display resolutions (think ipads, smartphones [each with different resolutions], 30" monitors, etc).
by the way:
// both of these on their own do nothing.
$(window).height() // just returns to you the viewport height
$(window).width() // just returns to you the viewport width
body {height: 100%; width: 100%;}
div#page_container {height: 100%; width: 100%;}
No need for JS/jQuery, just wrap all your content inside <div id="page_container"></div>
It also resizes with people resizing browser windows.
I have to agree with Phil. There is going to be no way to determain the resolution of the users screen. That is going to be a user problem. I have always built my web sites at 1024 x 768 resolution for that reason. Sometime even lower depending on the content, and the target audience(sites that target older people who probably have a low resolution setting so they can read their screen).This way, I know that my stuff will fit. Most people now a days, with monitors the size that they are, do not go much below that.
I found this code here at http://support.microsoft.com/kb/287171 that might help you though. This will adjust the screens height and width based on the users screen resolution.
Also remember that some JavaScript will not work in certain browsers. I have run into this problem with pop-ups when it came to changing screen size, scrollbars ect...