Skip to content

Commit

Permalink
Fix the touch-action processing model for zoom scenarios
Browse files Browse the repository at this point in the history
It's incorrect to consider the touch-action values only up to the nearest
ancestor that supports ANY default touch behavior.  Eg. in Edge you can
disable double-tap to zoom across an entire page (including any iframes
or other scrolling elements) by applying 'touch-action: manipulation' to
the html element.  See http://jsbin.com/tipure/ and http://jsbin.com/jucuna.
This is issue w3c#19.

This change also moves the core processing model details up to
above the specific value definitions to make it easier to follow
without getting lost in all the value-specific notes.
  • Loading branch information
RByers committed Oct 22, 2015
1 parent 6c17eee commit 5f9e1ca
Showing 1 changed file with 10 additions and 8 deletions.
18 changes: 10 additions & 8 deletions index.html
Expand Up @@ -667,6 +667,16 @@ <h2>The <code>touch-action</code> CSS property</h2>
</table>
<div>
<p>The <code>touch-action</code> CSS property determines whether touch input MAY trigger default behavior supplied by user agent. This includes, but is not limited to, behaviors such as panning or zooming.</p>

<p>When a user touches an element, the effect of that touch is determined by the value of the <code>touch-action</code> property and the default touch behaviors on the element and its ancestors. A touch behavior is supported if allowed by the <code>touch-action</code> properties of all elements between the hit tested element and it's nearest ancestor with the default touch behavior (including both the hit tested element and the element with the default touch behavior).</p>

<section class="note">Some user agents support touch actions triggered by interactions of multiple concurrent pointers (e.g. multi-touch). Methods for processing or associating the <code>touch-action</code> values of multiple concurrent pointers is out of scope for this specification.</section>
<p>During the execution of a user agent touch behavior, the user agent MUST NOT fire subsequent pointer events for the pointer. The user agent MUST <a href="#firing-events-using-the-pointerevent-interface">fire a pointer event</a> named <code>pointercancel</code> (and subsequently a <code>pointerout</code> event and one or more <code>pointerleave</code> events) whenever all of the following are true, in order to end the stream of events for the pointer:</p>
<ul>
<li>The user agent has determined (via methods out of scope for this specification) that touch input is to be consumed for a touch behavior,</li>
<li>a <code>pointerdown</code> event has been sent for the pointer, and</li>
<li>a <code>pointerup</code> or <code>pointercancel</code> event (following the above mentioned <code>pointerdown</code>) has not yet been sent for the pointer.</li>
</ul>

<p>Values have the following meanings:</p>
<dl>
Expand All @@ -679,14 +689,6 @@ <h2>The <code>touch-action</code> CSS property</h2>
<section class="note">The <code>touch-action</code> property only applies to elements that support both the CSS <code>width</code> and <code>height</code> properties (see [[CSS21]]). This restriction is designed to facilitate user agent optimizations for <span>low-latency</span> touch actions. For elements not supported by default, such as <code>&lt;span&gt;</code> which is a <span>non-replaced inline element</span> (see [[HTML5]]), authors can set the <code>display</code> CSS property to a value, such as <code>block</code>, that supports <code>width</code> and <code>height</code>. Future specifications could extend this API to all elements.</section>
<section class="note">The direction-specific pan values are useful for customizing overscroll behavior. For example, to implement a simple pull-to-refresh effect the document's touch-action can be set to <code>pan-x pan-down</code> whenever the scroll position is 0 and <code>pan-x pan-y</code> otherwise. This allows pointer event handlers to define the behavior for upward scrolls that start from the top of the document. <p>The direction-specific pan values can also be used for composing a component that implements custom panning with pointer event handling within an element that scrolls natively (or vice-versa). For example, an image carousel may use <code>pan-y</code> to ensure it receives pointer events for any horizontal pan operations without interfering with vertical scrolling of the document. When the carousel reaches its right-most extent, it may change its touch-action to <code>pan-y pan-right</code> so that a subsequent pan operation beyond it's extent can scroll the document within the viewport if possible. It's not possible to change the behavior of a pan in the middle of an operation.</p></section>
<section class="note">Disabling some default touch behaviors may allow user agents to respond to other behaviors more quickly. For example, with <code>auto</code> user agents typically add 300ms of delay before <code>click</code> to allow for double-tap gestures to be handled. In these cases, explicitly setting <code>touch-action: none</code> or <code>touch-action: manipulation</code> will remove this delay. Note that the methods for determining a tap or double-tap gesture are out of scope for this specification.</section>
<p>When a user touches an element, the effect of that touch is determined by the value of the <code>touch-action</code> property and the default touch behaviors on the element and its ancestors. To determine the effect of a touch, find the nearest ancestor (starting from the element itself) that has a default touch behavior. Then examine the <code>touch-action</code> property of each element between the hit tested element and the element with the default touch behavior (including both the hit tested element and the element with the default touch behavior). If the <code>touch-action</code> property of any of those elements disallows the default touch behavior, do nothing. Otherwise allow the element to start considering the touch for the purposes of executing a default touch behavior.</p>
<section class="note">Some user agents support touch actions triggered by interactions of multiple concurrent pointers (e.g. multi-touch). Methods for processing or associating the <code>touch-action</code> values of multiple concurrent pointers is out of scope for this specification.</section>
<p>During the execution of a user agent touch behavior, the user agent MUST NOT fire subsequent pointer events for the pointer. The user agent MUST <a href="#firing-events-using-the-pointerevent-interface">fire a pointer event</a> named <code>pointercancel</code> (and subsequently a <code>pointerout</code> event and one or more <code>pointerleave</code> events) whenever all of the following are true, in order to end the stream of events for the pointer:</p>
<ul>
<li>The user agent has determined (via methods out of scope for this specification) that touch input is to be consumed for a touch behavior,</li>
<li>a <code>pointerdown</code> event has been sent for the pointer, and</li>
<li>a <code>pointerup</code> or <code>pointercancel</code> event (following the above mentioned <code>pointerdown</code>) has not yet been sent for the pointer.</li>
</ul>
<pre id="example_5" class="example" title="Disallowing all touch behaviors">
&lt;div style=&quot;touch-action: none;&quot;&gt;
This element receives pointer events for all touches.
Expand Down

0 comments on commit 5f9e1ca

Please sign in to comment.