Recently i am working on a mobile webapp with a big textarea that needs to constantly display two little buttons on the bottom corners of the viewport. So i started with the basics:
position: fixed;
bottom: 10px;
This works smoothly and looks beautiful on my target devices (iOS >=5, Android >= 2.3). However, the problem starts when i give my big textarea a focus() and a system keyboard appears.
In iOS browsers, the keyboard is just an overlay on the viewport - so the viewport keeps it's dimensions after keyboard is on and half of it is just hidden under it.
In most android devices the keyboard appearance makes the viewport's height smaller and fitted to the remaining area so my position fixed workes here. However, some android devices work just like iOS and the keyboard appears as an overlay.
I'm trying to think of the best way to cover this, not using user agent string. I want this to be a universal solution. I figured out sth like
//check the viewport height
on(focus) -> see if viewport size changed and change position: fixed
But to do this i still need to wait couple seconds after focus to let the window get resized or not + i don't really know where to put my buttons if the viewport stays the same, as i might be on any of the iOS systems (the have different sizes fo keyboard) or on android device with bad behaviour.
What do You think?
Related
I'm making a webapp and want to use all the screen and avoid scrolling if possible. There will be buttons that need to be clicked in many areas of the page.
The area at the bottom of mobile safari is not clickable when the tab bar is open and I rotate to portrait and back to landscape.
I have set the body height to the same as window.innerHeight instead of 100% so that I don't have to scroll to get to buttons at the bottom.
bodyEl.style.height = window.innerHeight + 'px';
It may be the case that this area is not usable for interactive content.
Here is a demo with code:
http://plnkr.co/edit/327sUQ?p=preview
You should be able to open a preview of it on iPhone 6 Plus by clicking on the fullscreen button 'Launch the preview in a separate window'.
Update:
It definitely looks like it was a bug in iOS8, it's working as expected in iOS8.4, 9.0 & 10.2 from my simulator.
I may have found an answer to your issue, but would love to hear if you can confirm. Setting the content of your page to have the following styles:
overflow-y: scroll (allows you to scroll below the viewport, but only if necessary per the length of the content; the default value is visible)
-webkit-overflow-scrolling: touch (to smooth any scroll behavior)
in addition to your height: 100% (which forces the content to fill the viewport)
appears to force the iOS menu (tabs and address bar on top as well as nav bar on the bottom) in Safari to always appear. That way, button clicks to the top and bottom of the page are no longer "dead zones" and will actually work instead of opening up the Safari menu.
I'm searching for a solution for a similar problem - this is not an answer, but an attempt of explanation.
First of all - currently, I cannot confirm this behavior - seems like it's fixed in iOS 8.4 (12H143). Didn't know exaclty in which version I saw it the last time.
Nethertheless, I try to explain what I've found out (until we decided to not bother anymore).
The not clickable area is not always a dead zone. If you scroll up before you click, chances are high you get it working. Thus I think the (empty) standard navigation bar is there (height and behavior of the elements are similar/the same), even if it's empty (all element moved to the address bar) in landscape mode.
Btw.:
There's another (similar) problem with the iPhone 6 plus (not fixed yet).
If you have a position: fixed element on the top of a webpage, in landscape mode and only if there are two or more tabs open (and the tab bar is visible), you can click through this element (even through buttons) - as if the whole thing isn't there.
I know this question is a bit old, but since the issue still exists I thought I should share my experience...
As of now there is NO fix for the issue, but there is a workaround. The solution jennz0r provided may work for some, but I didn't like the idea of the menu bar always showing. I saw a website that had the issue solved... well it seemed to work at least. I didn't find anything in their css or js.
So what was the fix? Since the "dead zone" is 44px in height they simply made their floating bar 88px height :D Users would instinctively tap on the top/center of the button and it will almost always work at first try!
Another workaround would be to simply make the button/bar float 44px from the bottom.
"If it's stupid, but it works... it ain't stupid..." ;)
In iOS web browsers (Safari, Chrome, etc.), when you click into an input field and the keyboard displays, it keeps the viewport the same size but slides it up partially out of view. This makes creating app-like websites very difficult, as I'm coding a chatting app and when the keyboard shows I want to keep the conversation completely in view, but simply resize the conversation area to fit in the new "resized" viewable area.
I've tried everything, such as having the conversation area be absolutely positioned with left: 0; right: 0; top: 0; bottom: 0, but still iOS keeps the viewport the same size and pushes it up and partially out of view.
Is this possible? Or is it system-level functionality that is beyond control of CSS or JavaScript?
The simple answer is... The soft keyboard is separate from the browser and cannot be controlled by anything inside the browser itself.
Android & iOS both treat the soft keyboard differently so writing something to work across devices is going to be difficult.
iOS Safari doesn't change the size of the browser window. It actually pushes the entire application window up hiding the top portion off the device screen. So, in theory a position: fixed; footer should function the way you expect while headers are pushed up out of sight. (Position fixed is preferable over absolute as its reference point is always the WINDOW.)
In practice it seems to depend on the version of iOS for how fixed positioning actually works. However, as of iOS version 12 you can use javascript to watch changes to window.innerHeight and add a new class when things change.
Chrome on Android seems to physically change the height of the browser window so screen size media-queries might be enough to position things in this case.
As always, there are so many device/OS/screen combos that you should test as much as possible and be aware that you're probably never going to solve for all of them.
I have an element with position fixed (pinned to any corner) on a page (which I do not necessarily have control over the meta viewport tag - it is an embedded widget for third party sites). On Mobile Safari when the user pinch zooms the page at a certain point the viewport becomes larger than the visible area. At that point the fixed position element stays attached to the viewport and is not necessarily in the visible area.
I would like to compare two widths: the width of the visible area and the width of the viewport. I believe the size of the visible area is window.innerWidth. I am not sure how to measure the viewport.
I have been trying to see the relationships between:
document.documentElement.clientWidth
screen.width
window.innerWidth
window.outerWidth
...But have not been able to see anything obvious.
This is butt ugly but it does show some code that almost works (view on iOS to see it working. Use a desktop and click edit at top right of page to see or edit code):
https://jsbin.com/jopamu (iOS only)
The trick with the "overzoom" calculation is nasty but it does compensate somewhat for the multiple viewport zooms. It is a complex problem to solve because there are competing issues:
pinch-zoom
zoom due to input focus
the "position:fixed" zoom
potentially the OS (accessibility) zoom
The possible solutions I have found are:
Position the menu using the calculations above and position:absolute - updating the left/top in onscroll event. Has ugly juddering (can improve a little by hiding and only showing when zooming/scrolling finishes).
Position the menu using position:fixed but change the left/top to correct the menu position as zooming/scrolling occurs. Much less judder but I couldn't quite get it 100% reliable (some race condition).
Not suitable for your case (and highly unrecommended due to risk of breaking things): you can prevent pinch zooming and iOS10 double-click zooming by cancelling default on touchstart. Difficult because it needs many other workarounds so normal touch works, and needs synthetic scrolling and zooming (but has ugly side effects such as preventing scrolling working sometimes and also interferes with accessability e.g. if voice accessability turned on etc etc).
If you just want to see the widths then use the older version:https://output.jsbin.com/jopamu/6
On iPad I cannot scroll a web page. It works fine in Safari, Chrome and Firefox on OS X.
The page has an area in which content can be scrolled only horizontally. It consists of a container div which has width = 100% and height = (100% - 40px). I am setting the height by a JavaScipt function which is triggered by window resize events. Inside this container is another div with the width of the content (very wide, to avoid line breaks). Inside that is the content.
CSS properties of the container are:
overflow-x:scroll;
overflow-y:hidden;
white-space:nowrap;
See the page and full source code here: dcfoto.de
On iPad, scrolling is not possible. What am I doing wrong?
By the way: resizing also does not work properly on orientation change. Maybe that's connected.
Unfortunately a two-finger swipe needs to be performed, and even then it is not responsive (when compared to the default one finger swipe scroll).
There are quite many javascript solutions out there, (sencha touch and iscroll being the most promising and advanced)
I would recommend http://cubiq.org/iscroll-4 which is hands down the coolest touch-scroll script out there. It also works for android, but quite more sluggishly since the default android browser albeit webkit based doesnot support css3 3d accelerated properties as good as the mobile safari one.
If I were you I would check for the user agent of the user, and deploy that script for android and ipad/iphone users.
I am designing website for mobile access and I want to set page width, height and button sizes, so they display filling up the screen. For example if user is using HTC HD , the whole screen would be 480x800 with button sized 240x200.
However IE mobile as well as Opera load the page with some zoom level, so the buttons display either too large or too small. How can I either read current zoom level in javascript or set it from javascript?
Take a look into <meta name="viewport">. It's supported across a wide variety of mobile platforms, including (AFAIK) iPhone, Android, Blackberry, Opera Mobile and even IE6 Mobile. Basically, it lets you preset the device width, zoom level, and max/min zoom. Have a look at the Apple developer site and for more info.
Also, you can use CSS media queries to detect the shape and size of the browser, and serve up different layouts (etc) accordingly. Again, these are fairly widely supported and the Apple developer site has more information.
You shouldn't rely on using JavaScript on mobile devices because it is still not widely supported across all phones. Instead you should set the width of the page to be the same as the browser width so your pages appear at 100%, e.g. body {width: 100%; margin: 0; padding: 0;}
As for buttons you should use relative values or use different image sizes if you are able to detect the browser width before the page is loaded.