For iOS, Safari, VoiceOver, how do I get VoiceOver to read something other than the text content? - ios

I am trying to get VoiceOver to say something other than the specified text content in an HTML span element:
<span tabindex="0" class="myClassName" id="DateLabel" role="heading">1:02a</span>
Consider the case where I might like VoiceOver to say the full time text.
When I add the aria-label attribute, VoiceOver is still reading the text, despite desktop browsers like IE and Chrome correctly reading the aria-label instead.
When I add the aria-labelledby attribute plus a hidden aria label element, I am able to get VoiceOver to read the alternate narration, and NOT the text content. However, I find this only works if the aria-role is a widget role like button or link. This is bad because I don't want to imply to users that this is an interactive element they can activate. VoiceOver annoyingly appends "button" to the end of the narrated sequence. I would prefer to use a structural role like "heading" but then VoiceOver just reverts reading the text content instead of reading my hidden narration.
Please help! I've been bashing my head against this but I simply cannot stand iOS's non-standard implementation of ARIA. I don't understand why they must be different from desktop browsers for something so simple but they are in so many places and I cannot find a good document outlining the exact behavior anywhere.

You can use aria-label like this:
<span tabindex="0" class="myClassName" id="DateLabel" role="heading" aria-label="1 0 2 am">1:02a</span>
However, why are you setting tabindex to 0? For a heading this is not a good practice because screen reader users can navigate between headings using the keyboard commands. Also, you will want to set aria-level on your heading to indicate what level it is.
The best markup to use for this is:
<span class="myClassName" id="DateLabel" role="heading"
aria-level="2" aria-label="1 0 2 am">1:02a</span>
Update: This appears to no longer work for at least some versions of VoiceOver, it will read the visible content and ignore the aria-label. See this bug - https://bugs.webkit.org/show_bug.cgi?id=160009

In my case I used for iOS VoiceOver:
<span role="text" aria-label="audible text">visible text</span>
it is important to add the attribute role="text" so that VoiceOver reads the attribute aria-label=""

In this case you could use a pattern that hides the visual text from screen-readers and hide the screen-reader text from showing visually. Like this:
<span aria-hidden="true">1:02a Dec</span>
<span class="visually-hidden">1:02 AM December</span>
and use CSS to hide .visually-hidden for example like this:
.visually-hidden {
position: absolute;
left: -999em;
}
Don't use display:none since it removes the element from being sent to the accessibility API.
As a side note: use role="heading" carefully if ever, and if so use an appropriate aria-leve="#" number/level.

You could use the abbr html element.
For example :
<abbr title="HyperText Markup Language">HTML</abbr>

Related

Custom keyboard in WKWebView

I want to control the keyboard displayed when using WKWebView.
I have the following swift code starting the webview:
let webView = WKWebView(frame: self.view.bounds, configuration: configuration)
webView.navigationDelegate = self
It will load html that looks like this:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div class="inputElement textFieldInput">
<input type="text" id="textField" value="" data-clear-btn="true"/>
</div>
</body>
</html>
Normally the keyboard is controlled by the type option on the input field. "num" for a numeric keyboard and "text" for a alphanumeric keyboard. But I want to have more control.
I have done enough research to know that this can not be accomplished by using the option on the text box. I am fully expecting to write modify the code that opens the webview.
How can I modify the swift code to allow me to do this?
Ideally, I could define multiple keyboards and allow the html code to control them something like this: <input type='customkb1'> and <input type='customkb2'>
My immediate need is to disable the emojis button on the keyboard but I would like a generic solution as I will be able to really improve the usability of my application if I can define a keyboard specific to what the user is inputting.
Here is what we have found so far:
That is trick I know and use for native part of the application:
https://stackoverflow.com/a/25861718/1885345
But it doesn't work for webViews
That is the way to specify keyboard from WKWebView:
https://stackoverflow.com/a/28533488/1885345
But it doesn't have the option to set keyboard without emojis
That is what I use to disable third-party keyboards:
https://stackoverflow.com/a/34863426/1885345
Nice challenge! So far I have tested it on an iPad and got it half-working (with a caveat) by declaring the input field's pattern as such:
<input type="text" pattern="[0-9]*" value="" data-clear-btn="true"/>
The thing is that the keyboard actually pops up first with the numeric view but it allows to toggle the alphanumeric (without emojis) view via the lower ABC side-buttons.
With Javascript I copied the entered value to another field and the Regex does not actually filter out the entered alphanumeric characters. So far so good.
As soon as you put A-Za-z (as prefix or postfix) into the pattern, the emoji button comes back though.
I have tried catching the UIResponder.keyboardWillShowNotification but does not return the keyboard object, as I wanted to set its UIKeyboardType programmatically then, but this attribute only reflects UITextViews apparently.
Alternatively you could declare the input field of password type, clearing the dots with Javascript and displaying the actual value to another non-editable field...
If I find a more elegant way, I will update my answer as it is getting quite late. Cheers.
EDIT: Apparently only using a TextInput element with ReactNative you can directly prop the keyboardType to the ascii-capable iOS keyboard which shall set us free from Emojis.
If you’re looking for a way to only allow certain characters to be entered in an input field, disabling keyboard modes (the emoji keyboard, for example) isn’t the best option. There are many ways to type in unwanted characters: they can be pasted from the clipboard, or even entered in the result of text replacement (for example, you can make :) turn into 😁).
Input validation should be done on the webpage side, not with WKWebView.

Why is skrollr preventing scrolling on ipad?

I'm trying to create a simple parallax animation with skrollr: my site is working well on Chrome/Mac but I'm seeing unusual behaviour on the ipad..
On ipad (testing on the IOS simulator),
the main body of the page doesn't skroll at all (or may scroll in the background, underneath the animated div?)
the animated background position (origami pattern) scrolls in the opposite direction (down is up) within the bounds defined in data-start / data-top-bottom
On desktop, the effect I can simulate the effect if I hack the div#hero to be position: fixed; in chrome dev tools.
The skrollr examples work as expected in the IOS simulator.
I have <div id="skrollr-body"></div> just before the closing </body> tag
Any suggestions?
You just naively added an empty #skrollr-body element. The documentation says
Starting with skrollr 0.6.0 there's just one thing you need to do: Include an element on your page with the id skrollr-body. That's the element we move in order to fake scrolling.
If that's the element we move for fake scrolling, then all your elements need to be inside of it (unless they're fixed positioned).
The only case were you don't need a #skrollr-body is when using position:fixed exlusively. In fact the skrollr website doesn't include a #skrollr-body element. If you need both fixed and non-fixed (i.e. static) elements, put the static ones inside the #skrollr-body element.
https://github.com/Prinzhorn/skrollr#what-you-need-in-order-to-support-mobile-browsers
So in other words, simply add a <div id="skrollr-body"> tag right after the opening <body> tag, and close this division by adding a </div> right before the </body> tag.
adding a div wrapper with skrollr-body id did absolutely nothing for, scroll just doesn't work on mobile

jQuery UI & Content Editable in Modal dialogs

Are there any issues surrounding the use of contenteditable div elements in jQuery UI that lead to the caret not appearing. Here is a bit of code to show what I mean
<div id='diaHTMLEd' style='display:none'>
<div id='divRTE'></div>
<!--iframe src='xrte.html' height='300' width='500'></iframe-->
</div>
function openHTMLEditor( {
$('#diaHTMLEd').dialog({
height:200,
width:450,
modal:true,
open:addRTE
});
}
function addRTE() {
$('#divRTE').html("<div contenteditable='true'>Testing</div>");
return;
}
Explanation - I am opening up a modal jqUI dialog and in its :open event am adding a contenteditable div element to an inner div in the dialog. The text shows up but it does not become editable when clicked. If I replace that code and use the commented out iframe instead which contains an contenteditable drive everything works just fine.
It looks like there is something that stops content from becoming editable inside the dialog.
This question may be lacking in some detail but given the complexity of my application I am not really in a position to provide more representative code. Any help would be much appreciated.
A note for anyone running into this thread. After much work I eventually discovered the issue. Using contenteditable with jQuery UI dialogs is not by itself a problem. The problem in my case came down to some sort of conflict with the excellent jstree plugin which I am using.
As a general rule - in complex applications that use multiple plugins you are probably better off sandboxing contenteditable content inside an iframe

Unable to drag using image within anchor link in Chrome or IE

This is going to be fairly hard to explain, so I've put together a JsFiddle to help demonstrate. http://jsfiddle.net/j5TKr/
I've tried to include everything that I require without complicating it too much. The overall aim is to have a list of li's which can be selected (single click, ctrl-click, shift-click) or double-clicked to be opened. The selected li's can be dragged around (so that they can be moved into other folders). The JsFiddle doesn't have the li's being grouped together correctly, but I'm not worried about that as it is actually working correctly.
The problem that I have is that in Google Chrome and IE (and possibly other browsers - not Firefox) you can't drag the li's around using the image within the anchor. Or more specifically, in Chrome it doesn't drag until you release the mouse button. If I remove the image (the "This one works" text link) it works. If you drag using the image information below the actual anchor, it works as well.
I gather it's a problem to do with me wanting to be able to click and select li's without actually opening the links.
Sorry if this is all a bit confusing. I'll answer any questions that come up.
Here’s an HTML workaround effective in IE and Google Chrome.
Instead of marking your draggable elements up like so:
<div class="icon">
<a title="assets" href="[link]">
<img src="[image]" />
</a>
</div>
Mark them up like so:
<div
class="icon"
style="width: 90px; height: 90px; background: url('[image]')">
</div>
(You could, of course, separate the added CSS from the HTML.)

List of known "Safari on iPad" differences over "Desktop Safari"

In recently testing a web application on Windows/Mac desktop browsers - and then on an iPad I noticed various differences in Safari that I wasn't expecting. Even though the version # is the same.
I'd like to compose a list of those differences (for myself and others) to have as a developer reference.
e.g. in Safari on the iPad
iPad Safari takes full control of Select list/option styling
iPad opens the onscreen keyboard when an input element receives focus, thus inline floating calendar widgets (and the like) may not work as expected (or need to be altered)
iPad Safari doesn't support position:fixed like desktop Safari < iOS 5
iPad Safari (similar to iPhone/iPodTouch Safari) automatically hyperlinks 10 digit numbers to offer phone #/contact options
iPad Safari prompt('long message...','default'); shows only 1 line of the message (though it does provide scrolling of the message
I've heard from others that certain JavaScript doesn't work, etc. etc. but I have yet to fully test it thus I'd be grateful for any discoveries that you may have encountered.
A few more for you:
No Flash
Lousy iFrame support (so facebook like etc. needs a custom implementation for iPad)
Weird caching limitations
HTML textAreas doesn't get a scroll bar (you have to double-finger swipe - which of course, is amazingly intuitive)
In general. Treat it like a scaled up iPhone, not a scaled down Desktop.
I thought this might be useful: Apple's guide to preparing web content for the iPad
Just been caught out by the position:fixed issue my self
Safari on iPad has the same issue with button width/padding as on the iPhone
iPhone <button> padding unchangeable? describes this problem and a solution for removing padding on a button with text, but this does not help you if you want a button to be narrower than the padding itself (e.g. for a button that only has a small icon on it). To do that, I had to surround the button with an outer element with a defined width and overflow: hidden like so:
<span style="border: solid 1px blue; display: block; width: 16px; overflow: hidden">
<button style="-webkit-appearance: none; border-width: 0"> </button>
</span>
(the blue border is to show where the button is, it's not critical to the hack)
jQuery's offset() doesn't work: http://bugs.jquery.com/ticket/6446
It also looks like iPad Safari has issues with elements with overflow:auto; that therefore should show scrollbars (test page with div's and iframe's).
iPad Safari seems to have trouble handling background images in rare cases, showing weird lines of lower lying content.
There's not a lot about this in Google (yet).
iPad browser doesnt support file uploading(even if it supports it will useless as iPad does not have a standard File Browser). The file field appears with a Choose File button grayed out.
Beside doesn't support scrollbar in TextAea, it seems that we can using javascript to make text in TextArea selected automatically too.
This code will only move cursor to the end of text in TextArea.
<div>
<textarea id="text-embed-code" autocapitalize="off" multiline="">
There is a fox running after chrome.
</textarea>
<button onclick="testSelectText(event);">select text</button>
</div>
<script>
function testSelectText(e) {
var box = document.getElementById("text-embed-code");
box.select();
e.preventDefault();
return false;
}
</script>
There appears to be a bug in iPad Safari where a CSS element with both a background image and a background color is rendered with a slight border in the color of the background color. It should fill with the background image all the way to the edge of the rendered element.
I just had the same bug on my site, when trying to view it on an Ipad. The HTML structure is like:
<div class="main"> <!-- background-color: white -->
<div class="left"></div> <!-- background-image: url(some_transparent_png) -->
<div class="content">...</div>
<div class="right"></div> <!-- background-image: url(some_transparent_png) -->
</div>
The left layer uses a background-image, whereas the main layer uses just a background-color. The Ipad view shows a slight border at the edge of the left and right layer.
When i add
-webkit-background-size: 100% 100%;
to the left and right layer, the border disappears.
You can now control the styling of select lists on iOS by resetting it with -webkit-appearance: none;
This rule fixes animation flickering in Safari on iOS devices:
body {-webkit-transform:translate3d(0,0,0);}
There appears to be a bug in iPad Safari where a CSS element with both a background image and a background color is rendered with a slight border in the color of the background color. It should fill with the background image all the way to the edge of the rendered element.
24 bit transparent PNGS ABOVE A CERTAIN FILE SIZE don't render on the iPad2.
I can however get 8 bit ones of the same dimensions to render.
I haven't found out what this maximum file size is in order to get them to render.
I'm currently working on a small responsive web-app which makes heavy use of the iframe youtube api. Apparently the ipad version of safari doesn't support a few html5 methods which I use heavily in this project.
One of them is window.postMessage, which is a way of interacting with scripts on other pages, for example the a script that is used "within" that iframe. Autoplaying videos also doesn't work.
Frame problems. iPad Safari will both hide scrollbars and expand frames to the size of their content.
Changing the frame tag to include scrolling="yes" and noresize="noresize" appears to do nothing.
Some sites look fine on everything, even a Dreamcast browser, but not on iPad. The issue can be fixed using tables and iframes instead of normal framesetting (cols and rows, etc).
I also discovered that contenteditable is not supported in mobile safari, thus using a plain textarea is a better bet. Apple Developer Docs
position: fixed;
Does not work in iOS 4 but does work on iOS 5.

Resources