blob: b5d6864dbe86e263e2a5cec5189939d8ea3d7609 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<title>Demo: prefers-reduced-motion media query</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">
html {
font: 100% sans-serif;
font: -apple-system-body;
}
body {
font-size: 0.8em;
line-height: 1.1;
}
button {
cursor: pointer;
font-size: 1em;
-webkit-appearance: none;
border: solid 1px black;
color: black;
background-color: white;
padding: 0;
position: relative;
}
button::before {
display: block;
position: absolute;
content: " ";
top: 50%;
left: 50%;
width: 1px;
height: 1px;
opacity: 0;
background-color: rgba(255,100,100,0.3);
transition-duration: 0.4s;
transition-timing-function: ease-in-out;
/* Example 1: This value will be modified when 'reduce motion' is enabled. */
transition-property: top left width height opacity;
}
@media (prefers-reduced-motion) {
button::before {
/* Example 1: Now only animating the opacity... not size or position, which control the scale effect. */
transition-property: opacity;
}
}
button:hover::before, button:focus::before {
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity:1;
}
button > div {
margin: 1.5em 2em;
}
#twirl {
position: relative;
border: solid 1px black;
overflow: hidden;
}
#twirl > div {
margin: 1.5em 2em;
}
@keyframes animation-twirl {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#twirl::after {
width: 2000px;
height: 2000px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -1000px;
margin-top: -1000px;
background: repeating-linear-gradient(140deg, rgba(0,0,0,0), rgba(0,0,0,0) 10px, rgba(200,200,200,0.3) 10px, rgba(200,200,200,0.3) 20px);
background-size: cover;
content: '';
animation: animation-twirl 100s infinite;
}
/* Example 2: Disabling a ongoing, decorative background animation. */
@media (prefers-reduced-motion) {
#twirl::after {
animation: none;
}
}
#indicator #prmValue {
display: inline-block;
padding: 0.2em 0.4em;
text-transform: uppercase;
border: solid 1px #666;
background-color: #eee;
}
#indicator a {
text-decoration: none;
}
</style>
</head>
<body>
<h1>Reduced Motion Demos for WebKit blog post: <a href="https://webkit.org/blog/7551/responsive-design-for-motion/">Responsive Design for Motion</a></h1>
<p>To test these, enable the "Reduce Motion" setting.</p>
<ul>
<li><strong>iOS:</strong> Settings > General > Accessibility > Reduce Motion</li>
<li><strong>macOS:</strong> System Preferences > Accessibility > Display > Reduce Motion</li>
<li><strong>Xcode Accessibility Inspector:</strong> Settings > Reduce Motion (<a href="./axi.htm">see video demo</a>)</li>
</ul>
<h2>Example 1: Using CSS to modify an interaction transition-property</h2>
<!-- Check the 'button::before' blocks in the CSS. -->
<button>
<div>
On hover/focus (or tap on mobile), a zoom/scale trigger appears by default,
but it uses a simple dissolve when 'reduce motion' is enabled.
</div>
</button>
<h2>Example 2: Using CSS to disable an ongoing, purely decorative animation</h2>
<!-- Check the '#twirl::after' blocks in the CSS. -->
<div id="twirl">
<div>
The spinning background animation is stopped entirely if 'reduce motion' is enabled.
</div>
</div>
<h2>Example 3: Using JavaScript to access the current value</h2>
<div id="indicator">Prefers reduced motion: <span id="prmValue">unsupported</span> <a href="https://webkit.org/b/168491" title="Outstanding bug: 168491" aria-label="Outstanding bug: 168491"><sup>1</sup></a></div>
<script type="text/javascript">
var motionQuery = matchMedia('(prefers-reduced-motion)');
function handleReduceMotionChanged() {
document.getElementById('prmValue').innerText = motionQuery.matches ? 'on' : 'no-preference or unsupported';
}
handleReduceMotionChanged(); // trigger this once on load to set up the initial value
motionQuery.addListener(handleReduceMotionChanged); // Note: https://webkit.org/b/168491
</script>
<h2>Example 4: Only display animated version if prefers-reduced-motion is both supported *and* off.</h2>
<p>This example uses a more explicit match for <code>(prefers-reduced-motion: no-preference)</code> which excludes all browsers that don't yet support the new feature.</p>
<img id="jaws" src="jaws.jpg" alt="Brody realizing the shark is in the water" width="480" height="214">
<script type="text/javascript">
var motionQuery2 = matchMedia('(prefers-reduced-motion: no-preference)');
function handleReduceMotionChanged2() {
document.images['jaws'].src = motionQuery2.matches ? 'jaws.gif' : 'jaws.jpg';
}
handleReduceMotionChanged2(); // trigger this once on load to set up the initial value
motionQuery.addListener(handleReduceMotionChanged2); // Note: https://webkit.org/b/168491
</script>
<p>Return to WebKit blog post: <a href="https://webkit.org/blog/7551/responsive-design-for-motion/">Responsive Design for Motion</a></p>
</body>
</html>