What is the most reliable way to detect if a user has a physical keyboard?
An idea is that since there is no physical keyboard window.onkeydown could be undefined (instead of null). But because of the virtual keyboard I'd suppose it to not be the case. I didn't test though.
My goal is to have input[type='number'] of an Online Timer to be replaced with wheel pickers if the user doesn't have a keyboard.
This gets really tricky with devices like the Microsoft Surface, which come with a keyboard, mouse, and have a touch screen. And you may mix all 3 input modes at any given time, or add another input method like a stylus.
Microsoft is taking the approach of abstracting input events as "pointer events". This model has been submitted to the W3C. This should give you an idea of the trend in managing input.
Still, I find it's handy to see if touch is available and operate under the assumption that—if it is—the user will use touch input at least some of the time. This can lead to design decisions to eliminate things which are completely touch-unfriendly even though that may mean compromising on mouse/keyboard functionality.
In your specific case, I would take a hard look at whether or not you even need to replace input[type=number] with a custom control. Most touch devices are reasonably modern, and many have custom, touch-friendly versions of the standard HTML inputs.
Also keep in mind accessibility scenarios which native controls probably support well "out of the box".
If you decide to implement a custom control, then I would advise detecting touch features and showing your custom control whether or not other input mechanisms are present. This means ensuring that the custom control is (at minimum) touch/keyboard/mouse friendly.
Here's my current touch test (with the disclaimer that it could break tomorrow and certainly hasn't been tested on every device):
var supportsTouch = ("ontouchstart" in window) || window.navigator.msMaxTouchPoints > 0;
I see two approaches.
The first approach would be to listen to every mouse and keyboard events. A user having a mouse is likely to also have a keyboard. A user going to a website is likely to move the mouse.
The second approach is to check the User Agent to read what Operating System is running and assume that the Android and iOS devices don't posses any keyboard. For Windows 8 I don't see how the User Agent could help, since windows 8 runs on both tablets and desktops/notebooks.
I'd rather have a more elegant solution though.
it's more reliable to detect a touchscreen and show the special widget then; just make sure the keyboard is still usable with your fancy widget for accessibility's sake.
You might be able determine the keyboard type by checking the operating system or even the screen dimensions. Android, iOS, and all devices with small screens tend not to have physical keyboards.
Related
The problem: I'm working hard to implement a responsive UI in my app. But the keyboard IME on Android squishes my entire page layout into a frame that's about 96 pixels high when in landscape orientation. Typically this means that the input control being edited is not visible in the space above the IME. And one cannot edit a value that's not visible in Chromium. I'm assuming iOS has the same problem.
Setting a minimum height for the page helps. But the Chromium scroll-into-view implementation is not robust enough to keep up with some of the more complex page rewrites that are triggered by a change in window size in my app.
Ideally, I'd like to run the keyboard IME in "extract" mode, where the page is entirely hidden, and only the value being edited is displayed in the space above the IME. But as far as I can tell, there's no way to do that, even in Android native apps. Chromium never runs the keyboard IME in "extract" mode, even in landscape orientation.
The solution I'm current implementing: simulate "extract" IME mode by perform editing of values in a full-screen dialog that contains nothing but a single dedicated <input>.
The question is: how should I detect when to use this solution. it's easy enough to check the browser's navigator.userAgent. The Mozilla foundation recommends checking for /Mobi|Android/ (although I've seen solutions that have 40 or 50 patterns). But I'm wondering whether there's a feature-driven way to check for this instead -- something more along the lines of if ("geolocation" in navigator) ....
But as far as I can tell, there are no features related to whether and how a keyboard IME will change the layout of a page. If there are, I'd like to know. The "feature" I'm looking for is something along the lines of "Will this browser lay out my entire page in a frame that's 96 pixels high (in landscape) whenever an input control gets focus". But "does this browser uses a keyboard IME" would be satisfactory.
Any ideas appreciated.
I am doing a simple :hover slide-in cover as shown in picture, it's supposed to slide in a "favorite article" control, which user can then click to favorite this item.
While it work well on desktop with mouse hover and click, I am not sure if it can be used as an effective control on mobile or other device (ie. click to toggle, then click again to favorite item) .
If I understand correctly, at least on iOS (Safari) and Android (Chrome), the default browser behaviour is to emulate touch as both hover and click. But is it a standard? eg.
Will Windows Phone or maybe a Wii U does the same?
Will click be fired about 300ms after hover, so there can be ghost click issue?
I can certainly bind a click/touch event on this element, just wondering if css :hover is sufficient nowadays.
To clarify: I am not asking about :hover support, which only make senses in a pointer driven environment. I am asking if devices can and should handle hover-able element as users click/tap (as iOS/Android do)
Your question isn't totally clear and I cannot understand whether you're asking "Can I use :hover across all the devices?" or "Will :hover behave the same across all the devices?" or "Is :hover a standard element on the web?"
Also it greatly depends of your concept of "all devices", if you have in mind the currently most used devices or you are taking in account also the less-known and used devices.
I will quote you the following, but I am pretty sure you have already read that:
Interactive user agents sometimes change the rendering in response to
user actions. CSS provides three pseudo-classes for common cases:
The :hover pseudo-class applies while the user designates an element
(with some pointing device), but does not activate it. For example, a
visual user agent could apply this pseudo-class when the cursor (mouse
pointer) hovers over a box generated by the element. User agents not
supporting interactive media do not have to support this pseudo-class.
Some conforming user agents supporting interactive media may not be
able to support this pseudo-class (e.g., a pen device). The :active
pseudo-class applies while an element is being activated by the user.
For example, between the times the user presses the mouse button and
releases it.
CSS does not define which elements may be in the above states, or how
the states are entered and left. Scripting may change whether elements
react to user events or not, and different devices and UAs may have
different ways of pointing to, or activating elements.
5.11.3 The dynamic pseudo-classes: :hover, :active, and :focus
http://www.w3.org/TR/CSS2/selector.html#dynamic-pseudo-classes
As you can see on the W3C specification it claims that the :hover pseudo-class is not required to a non-interactive media user agents as well as some interactive media user agents.
Therefore is safe to assume :hover is not always supported.
To dig deep on the matter, take a read at the following specification for Safari Mobile:
Additionally, Safari on iOS users interact with your web content
directly with their fingers, rather than using a mouse. This creates
new opportunities for touch-enabled interfaces, but does not work well
with hover states. For example, a mouse pointer can hover over a
webpage element and trigger an event; a finger on a Multi-Touch screen
cannot. For this reason, mouse events are emulated in Safari on iOS.
As a result, elements that rely only on mousemove, mouseover, mouseout
or the CSS pseudo-class :hover may not always behave as expected on a
touch-screen device such as iPad or iPhone.
You can handle touches directly or even detect advanced gestures in
Safari on iOS, using the DOM Touch events touchstart, touchmove,
touchend, and touchcancel. Unlike mouse events which are emulated, DOM
Touch events are specifically designed to work with touch interfaces,
so their behavior is reliable and expected.
5. Prepare for a touch interface
https://developer.apple.com/library/content/technotes/tn2010/tn2262/_index.html
Apple clearly states here that they tend to emulate the pointer with the touch gestures, however they clearly suggest to avoid using the :hover pseudo-class as won't behave the same on their touch device.
We could dig deeper and fetch every documentation for each user-agent existing on earth but the previous two are enough to assume the following:
Non interactive devices do not have to support :hover
Interactive devices can support the pseudo-class (but it's not mandatory and they can ignore it, for example screen-readers or braille screens)
Apple touch devices in absence of a pointer emulates :hover
It is safe to assume current touch devices also emulates :hover
It is safe to assume any other browser/device don't necessarily have to support :hover depending on their interface.
Very likely the recent browsers will all support :hover because is a visual aid for the user.
So to answer to all the question(s) I have assumed above:
"Is :hover a standard element on the web?"
Hover is a standard W3C in fact it claims it must be triggered by a pointer event, but isn't required for some interfaces.
"Can I use :hover across all the devices?"
Yes you probably can. The devices which won't support :hover very likely are devices/users that probably aren't your main target. Better ask yourself "Who will be the end-user of my product?" if they are only mobile users or only blind people or only people who like to browse using the Nintendo DS then don't use :hover events, otherwise do.
"Will :hover behave the same across all the devices?"
No, as Apple stated on their devices will not behave the same as a desktop would, and that probably reflects the same behaviour on all devices without a pointer.
If you plan to have an user action via a hover state don't do it. This is generally bad practice and it should avoided in any case, including desktop devices. Hover is not an call to action, click is. Hover should not be treated as a "toggle" but more like a visual helper for the user making him/her understand that element, if clicked, triggers an action.
If I understood your application then hover isn't reliable and in your specific case you should rethink on how it should work.
Use a more reliable method (and expected from your user)
Hovering your cursor over a webpage element is a common action when browsing with a mouse and keyboard, but there is no equivalent when it comes to touch-based browsing. This topic demonstrates how to use the aria-haspopup Document Object Model (DOM) property to simulate hover on touch-enabled devices with Internet Explorer 10 on Windows 8.
This behavior is not applicable to Internet Explorer 10 on Windows 7 (which does not support hover simulation with aria-haspopup) or Internet Explorer 11 on Windows 8.1 (which has built-in touch hover support).
In touch scenarios, hover is applied to an element while it is being touched. However, tapping an element can also activate an element, such as navigating a link. Effectively, a tap is both hover and activation in one action. This makes interactive content hidden behind hover inaccessible for touch users. The interaction model is completely different, and there is no touch analog to hovering the cursor over a page element.
The best practice is to not use hover to hide content that a user can
interact with. Instead, consider using the onclick event to toggle the
visibility.
It seems to me that part of this question hasn't yet been answered, namely what is the actual behaviour of Windows phones in relation to 'hover'. To clarify:
Consider a web page written for desktop/mouse use in which there is css markup so that 'hover' changes a style applied to an object. If one views that page on iPhone or Android and taps on the object the style change occurs. (i.e. it is behaving as if the object had an onClick() event handler to change the style). Does the same thing happen on a Windows Phone?
I can answer that question, at least for the Nokia Lumia 630 running Win 8.1:
No. As you press down with your finger in the initial part of a tap the style change does occur, but when you release your finger at the end of the tap the style reverts to the original. (This is arguably a more valid interpretation of 'hover' for touch, although whether it is of any practical use is another matter.)
I would add that the iPhone/Safari interpretation of hover also has an 'off' state. This is triggered when you tap on another object.
To show this and allow testing on different devices/browsers I have set up a demo page at www.davidleader.net/mobiledemo.html. This implements onClick(), onMouseover() and :hover to change the opacity of an image, revealing a different one underneath. (It therefore depends on support for opacity, but this has been around for a while.) There is also a 'dumb graphic' to click on to demonstrate the end of hover on the iPhone.
To summarize, as well as there being no de jure standards for interpretation of hover on mobile devices there are no de facto ones either. Therefore if you are targetting mobiles, avoid 'hover'.
Theres none at the moment that has a good support for :hover state in mobile
See related question about this
I havent use Modernzr.js for mobile , but it says it can detect if the browser supports touch events , so basically it adds ".touch" class in the html tag if the user uses mobile device.
so you'll use it like this, for e.g
.touch a:active{ /*css code here */ }
hopefully this would help somehow
When it comes to mobile phones, I doubt there is any standard. Yes it is very common for a touch device to apply a hover state while is is being touched, but you can never tell if a user could be using any number of browsers that may interpret a hover state differently.
I would say your best bet would be to shoot for the lowest common denominator and just assume that every touch device can only respond to touch actions.
The answer to that, of course, is to write media queries and/or javascript to force the browsers to act the way you want it to.
That's just my personal philosophy, for what it is worth.
I need access to a web-based on screen keyboard which will be used on a touch interface.
This example looks nice and functional, however when I try it on an iPad, the responsiveness it very low IMHO. It's not comfortable to use and sometimes whole words are misspelled due to slow response.
Is there a way to improve the experience on this type of on screen keyboard? This implementation uses the $('#id').click(...); function to process the events. Is there a better way to achieve the goal of typing on the screen? Are there better plugins out there?
Note: The final application will run on different types of devices. For several reasons, native on screen keyboards are no option.
Mobile browsers (iOS specifically, but others too) have a slight delay before triggering the 'click' event so it can differentiate between a single tap and a double tap.
For that style of keyboard you could probably get away with changing the 'click' to a 'mouseup'/'touchend' listener to remove the delay.
However, be aware that you would need to put in extra work if you need to make sure that you only handle a touch/click event if the user presses and releases on the same element (instead of starting the touch on one element and the sliding to another one before releasing).
I have a full-screen game in HTML+JavaScript, which uses the arrow keys as primary controls. This cannot be used on keyboardless Android devices (I haven't tested on iOS), and even if the soft keyboard had arrow keys it would take up unnecessary space. Therefore, I have added onscreen control buttons. However, the buttons are unnecessary (and absurdly large) on desktop browsers, so I would like them to not pop up unless they are needed.
What heuristics can I use to decide whether they are needed — that is, whether it is impossible or awkward for the user to input arrow-key events — other than recognizing specific User-Agents (which is straightforward, but not future-proof)?
I will of course allow the user to hide/show the buttons; I am looking for useful heuristics for choosing the default setting.
No need for any user-agent sniffing, config options or any kind of guessing. Just do this:
Have a title screen which says "press to continue".
On click or key press, hide touch controls and start game.
On touch, show touch controls and start game.
You never even needed to mention the option to the user and you auto-detected their preferred control perfectly.
Use feature detection with Modernizr: http://www.modernizr.com/docs/#touch
While this is not a reliable way to check if the user has a keyboard it is definitely reliable to see if the browser is capable of touch.
Instead of trying to guess, make it a config option for the user to choose.
If you have only arrows (left/right/up/down) you might consider adding touch-events inside the game field? This would not take up space obviously as it is layered on top of the game, so it could be 'always on'.
A computer user would not even know it is there, though he/she could use them to play your game with a mouse I guess.
The touch-device user on the other hand can much more easily use the "areas" (mid top, mid left, mid bottom and mid right for instance) because of .. well.. touching instead of using a mouse.
This might need some explaining, as you probably would not want the points to be visible to the user, but it feels like a valid option.
Even if you have 4 buttons and a 'fire', you could do this, for instance by adding a 'middle' section.
look for touch specific events such as touchstart or gesturestart and show the onscreen controls if detected.
http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html
I am not sure if the system-info api has been implemented by any browsers:
http://www.w3.org/TR/system-info-api/
rather than displaying the on-screen keyboard by default, add a button to toggle the display of the on-screen keyboard.
It might also be prudent to give the on-screen keyboard the ability to be resized.
Edit to answer question:
Keyboard should be hidden by default if most of your users are going to be on a computer,
Visible by default if most of your users are going to be on a mobile device.
You can consider checking the display size. If the display size is smaller than a certain size, you can assume that it is a mobile device and can display the Arrow Buttons. Other wise use keyboard buttons.
You can also keep an option so that user can set this manually if needed.
You could use javascript to find out the height of the windows view port and then us an if statement saying:
if ($(window).height() <= "960")) {
//Your code to display keyboard controls
//P.S. 960 is height of iPhone 4+ screen
}
Edit: Left out ) at end of $(window).height() <= "960"
I'm developing a web application and I noticed how irritating mouse gestures can be on it, so, is there a way to disable them (Firefox and Opera particularly)?
Edit: It seems there is some confusion. I'm developing a web based software that has an interface with such complex actions and tasks such as mouse selections, file drag and dropping, a desktop and a Windows Explorer -style filesystem. Whenever I try to select multiple virtual files and move them around, mouse gestures will apply and take me away from the software and navigate to the previous page or do something else nasty. My project is not a website, it's a web application -- mouse gestures are poison to this project.
You don't say you're using a library, but this is a jQuery plugin to detect gestures: http://plugins.jquery.com/project/jGesture
Looking at the source code, looks like it depends on measuring the action b/t mousdown and mouseup ... lotsa math.
And Mozilla offers some event handlers.. https://developer.mozilla.org/En/DOM/Mouse_gesture_events but it has a big Non-standard stamped on it.
the polite thing to do would be to inform users that to take full advantage of your site, they should disable mouse gestures temporarily.