Mobile Zone is brought to you in partnership with:

Mobile and web 2.0 developer, consultant and speaker. Author of "Programming the Mobile Web" book, published by O'Reilly in 2010. Forum Nokia Champion. Maximiliano is a DZone MVB and is not an employee of DZone and has posted 36 posts at DZone. You can read more from them at their website. View Full User Profile

Safari on iOS 7 and HTML5: Problems, Changes and New APIs

  • submit to reddit

The New Devices

The iPhone 5S and the iPhone 5C are on the market, and the good news is that, from a web development perspective, they are exactly the same as the iPhone 5. Same screen size, same pixel density, same abilities. They may be faster, but it's nothing to worry about from a coding perspective.

The new Touch ID feature (fingerprint scanner) is not available to web sites yet, and the 64-bit CPU will not change anything from a JavaScript developer’s perspective. Having said that, on the iOS Simulator now you have the ability to emulate a 64-bit CPU.

HTML5 markup support

Video Tracks

The video HTML5 element now supports the track child for subtitles and/or closed captions. We can support multiple languages and they will appear in a picker inside the video player. The user can change the language and disable the captions from the track picker.


For all the possible track types (kind attribute), it supports only captions and subtitles, and we have to define the language in the srclang attribute in ISO format (such as en for English). Subtitles are useful when the user can hear the audio but she/he doesn’t understand the language, and captions are for when the user can’t hear the audio, so it includes additional information about what is happening (such as ‘background musing playing’).


Defining the label attribute for track is worthless, because on iOS it will be ignored and the language name will be used instead for the menu with an optional CC suffix if we are using captions instead of subtitles as the kind value.

<source src="myvideo.mp4">
<track kind="captions" src="my-captions-en.vtt" srclang="en">
<track kind="subtitles" src="my-captions-fr.vtt" srclang="fr">

Tracks can be accessed through a JavaScript API, and we can use it to loop through all the cues on the track file. That might be useful only on iPad, where we can truly embed the video in the web canvas instead of an always-full screen mode on iPhone.

Track elements should follow cross-domain policies, because by default, the video and track origins must be the same. Using JavaScript, we can detect if tracks are available using webkitHasClosedCaptions, as in:

var hasCC = document.querySelector("video").webkitHasClosedCaptions;

We can also change caption visibility using the webkitClosedCaptionsVisible boolean property of every video element.

Styling Captions

From a CSS perspective, iOS 7 supports the new ::cue pseudo-element, but we can only change text-shadow, opacity and outline. All other properties, such as color and font styles, are ignored.

::cue { opacity: 0.8 }

Read more about the Track element and API (keep in mind that some of the API might not work on Safari).

Progress and Output Elements

The <progress> element is now supported, creating a progress bar on the screen based on max and value. There is no indeterminate progress support as in other browsers, so it’s only suitable when we know the determinate value of the activity’s progression.

<progress max="100" value="40">

The <output> element is now supported, but I don’t think you will be so excited about it. :)

The <meter> element seems to be supported, but all the content is ignored and nothing is rendered on the screen, so I think it’s a bug.

REMOVED: Datetime Input Type

Following Google Chrome, now Safari on iOS doesn’t support the datetime input type, and it will fall back to text. This type was deprecated in favor of using two inputs, date and time, for the same purpose. The problem is that datetime was compatible with iOS from version 5.0 to 6.1; if you are using it, be careful!

The week input type is still not available, but now instead of falling back to a text input type, it’s rendered a non-interactive control


 If you are using a input type=”datetime”, you should act immediately as it is now rendered as a text input type.

Seamless iframe

The new boolean seamless attribute for iframes is now available on iOS 7. It will create a borderless iframe in your website. The iframe will not have scrollbars and, by default, it will get the height of the inner content appearing in the website as using the space of any other block element in the DOM.

<iframe seamless src="mypage.html"></iframe>

HTML5 JavaScript APIs

Let’s start with the bad news: there is no WebGL, FullScreen, WebRTC, getUserMedia or IndexedDB support yet.

In terms of new APIs available we have:

  • Page Visibility API
  • XHR 2.0 full implementation
  • Video tracks API (already covered)
  • AirPlay API
  • CSS Regions API
  • Canvas enhancements
  • Removed support for Shared Workers
  • WebSpeech Synthesis API

Page Visibility is the API webkit-prefixed on iOS 7 to detect when our tab goes foreground and background. You can try a live demo here. XMLHttpRequest 2.0 spec fully compatible means that now we can request ‘blob’ as a response. The Video tracks API was already covered quickly, and it allow us to query and navigate through all the tracks and contents on any media element.

The CSS regions API appears as part of the CSS Regions spec (covered later) and is basically the prefixed webkitGetFlowByName function available on every DOM element.

Regarding the Canvas 2D Drawing API, we now have the globalCompositeOperation attribute on the canvas context that allows us to define the blending mode (such as multiply) when drawing different layers on top of each other. We also have a new Path constructor that we can then draw on the canvas’ context, allowing us to store these paths for later usage instead of drawing them directly on the canvas.

AirPlay API

The AirPlay API needs some explanation. AirPlay is the wireless streaming solution from Apple that allows some devices to stream content to other devices, usually an Apple TV. While Safari already supported x-webkit-airplay HTML attribute to define if we want AirPlay or not, we couldn’t customize the experience from HTML5 before.

The API allows us to customize the player and get information and events about streaming through AirPlay. Every video element has the eventswebkitplaybacktargetavailabilitychanged and webkitcurrentplaybacktargetiswirelesschanged. They remind us how terrible it is not to use underscores, camel case or other techniques for event names in JavaScript. :S The first event will fire when there is a new AirPlay target--such as an Apple TV--available, or when it’s not available anymore. The second will fire when the playback status on one target has changed.

I think webkitcurrentplaybacktargetiswirelesschanged has won the record: the longest JavaScript event name ever.

If there is a streaming target available, we can then offer the user a button to pick the target, calling the video webkitShowPlaybackTargetPicker function.

While there is no official documentation on this API yet, you can check the video ‘What’s New in Safari and WebKit for Web Developers’ from the WWDC session where they covered this topic.

Background Execution

Now we have several use cases for background execution:

  • If the user is changing tabs (Tab selection screen), your code is still executing but the image is frozen.
  • If the user is changing apps (multitasking mode), your code is still executing and the image is updated.
  • If Safari is in the foreground, but your website is in a background tab, your code is frozen and Safari has a snapshot of your last execution for UI purposes.
  • If Safari is in the background, your code is frozen.

WebSpeech Synthesis API

UPDATE 19/9: I could make this API work, so it is officially supported and working.

The WebSpeech API allow the website to record and transcribe audio, as well as synthesize text to voice using internal voices in the operating system.

Safari on iOS 7 includes just the Synthesis API (text to speech), but not the APIs for listening for audio from the microphone. You can query on all the available voices to speak in different languages, and on a real device it is returning 36 voices (sometimes you refresh the page and you get 0, a bug I think) using speechSynthesis.getVoices(). In terms of English, you have a female voice using en-US and a male voice using en-GB. I’m not an expert in voice recognition, but I feel that the voices in this API are not the same as Siri, which sounds more natural in iOS 7.

To make JavaScript speak from your website, you can use a shortcut version in the default language or you can define different properties as the following examples:

speechSynthesis.speak(new SpeechSynthesisUtterance("Hello, this is my voice on a webpage"));
var speech = new SpeechSynthesisUtterance();
speech.text = "Hello";
speech.volume = 1; // 0 to 1
speech.rate = 1; // 0.1 to 9
speech.pitch = 1; // 0 to 2, 1=normal
speech.lang = "en-US";

From the SpeechSynthesisUtterance object we can also bind to some events, such as start and end, but please don’t use alert inside those events, or your whole Safari will freeze (don’t ask me why).

The speakable string can be plain text. While the standard supports an XML document in SSML format (Speech Synthesis Markup Language) for input, Safari on iOS is just reading the XML. :)

It’s important to keep in mind that the Speech Synthesis API works only after a user’s explicit action, such as clicking on a button, so you can’t initiate a speech on the onload or on a time-base. Try this online demo browsing to on your iOS7 device

Other Changes

  • MutationObserver
  • Unprefixed Animation Timing API (also known as requestAnimationFrame)
  • Unprefixed transitionend event name
  • Unprefixed URL
  • Unprefixed WebAudio API and new advanced abilities
  • New DOM properties hidden and visibilityState
  • window.doNotTrack support

WebSQL Bug

  • Using WebSQL API will have big issues (DOMException) while trying to create a database bigger than 5Mb. On previous versions, the limit was 50Mb with the user’s permission. Because of a bug, when you try to store more than 5Mb, the user will get a permission dialog, but just for 5Mb only. Even if the user grants you permission, because it’s for 5Mb only, you will get an exception trying to get more. It’s a BIG BUG.

Update 19/9: According to tarobomb from New York Times, if you request less than 5Mb when you first create the database and then you try to store more data (up to 50Mb), the proper confirmation dialog will appear (first 10Mb, then 25Mb and finally 50Mb) and you will finally be able to store more than 5Mb.

Published at DZone with permission of Maximiliano Firtman, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)