Skip to main content
Accessibility AccessLint 0.16

Page orientation must not be restricted using CSS transforms.

About this AccessLint rule

When a web page uses CSS transforms inside an @media (orientation: ...) query to rotate content by 90 degrees, it counteracts the device's built-in orientation handling. The page appears locked to a single orientation, even when the user physically rotates their device. This creates a barrier for people who cannot easily reposition their device.

Users with motor disabilities often mount phones or tablets on wheelchair trays, stands, or other fixed holders. They may only be able to use their device in one orientation. If a page forces a rotation that cancels out the device's natural reorientation, the content becomes sideways and unusable for these users. People with low vision who prefer a specific orientation for readability are also affected.

Why this matters

WCAG 2.1 Success Criterion 1.3.4 (Orientation), at Level AA, requires that content not restrict its view and operation to a single display orientation (portrait or landscape) unless a specific orientation is essential to the activity. An essential use case might be a piano keyboard app or a bank check deposit interface where the layout is meaningless in the other orientation. Outside of those narrow cases, users must be free to view content in whichever orientation their device is in.

The way this restriction typically happens in CSS: a developer adds a @media (orientation: portrait) or @media (orientation: landscape) query that applies a 90-degree rotation to the <html> or <body> element. When the user holds the device in portrait mode, for example, the CSS rotates the entire page 90 degrees to simulate landscape. The device itself has already adjusted its rendering for portrait, so this CSS transform cancels that adjustment, making the content appear locked in landscape.

How to fix it

The fix depends on the situation:

  1. Remove the orientation-dependent transform. If the rotation exists solely to force a preferred orientation, delete the @media block containing the transform. Let the browser and operating system handle orientation changes naturally.

  2. Use responsive design instead. If the layout needs to adapt between orientations, use CSS techniques like flexbox, grid, or adjusted widths and font sizes inside orientation media queries. These approaches adapt the layout without locking the user into one orientation.

  3. Check for essential use cases. If the content genuinely requires a specific orientation to function (such as a musical instrument interface), the restriction is allowed under WCAG 1.3.4. Document this decision.

The CSS properties and functions that can cause this issue include:

  • The transform property with rotate(), rotateZ(), rotate3d(), matrix(), or matrix3d() functions
  • The rotate CSS property

Any of these applied conditionally within an @media (orientation: portrait) or @media (orientation: landscape) query, where the resulting rotation is 90 degrees (or 270 degrees, which is equivalent), will trigger this rule.

A rotation of 0 degrees or 360 degrees (a full turn) does not lock the orientation and is acceptable.

Examples

Incorrect: CSS transform locks the page to landscape

This page rotates the entire document 90 degrees when the device is in portrait mode, forcing landscape orientation:

<html lang="en">
<head>
<title>Locked orientation example</title>
<style>
@media (orientation: portrait) {
html {
transform: rotateZ(90deg);
}
}
</style>
</head>
<body>
<main>
<h1>Welcome</h1>
<p>This content is locked to landscape orientation.</p>
</main>
</body>
</html>

A user who has their device mounted in portrait mode will see this content rotated sideways.

Incorrect: using matrix to lock orientation

The matrix function can also produce a 90-degree rotation. This example has the same effect as the one above:

<html lang="en">
<head>
<title>Matrix orientation lock</title>
<style>
@media (orientation: portrait) {
html {
transform: matrix(0, 1, -1, 0, 0, 0);
}
}
</style>
</head>
<body>
<main>
<p>Page content appears locked.</p>
</main>
</body>
</html>

Correct: no orientation-dependent transform

Remove the orientation media query and transform entirely. The content renders in whatever orientation the device is in:

<html lang="en">
<head>
<title>No orientation lock</title>
</head>
<body>
<main>
<h1>Welcome</h1>
<p>This content adapts to any orientation.</p>
</main>
</body>
</html>

Correct: responsive layout without rotation

Use orientation media queries to adjust layout, not to rotate the page:

<html lang="en">
<head>
<title>Responsive layout example</title>
<style>
.container {
display: flex;
flex-direction: column;
}
@media (orientation: landscape) {
.container {
flex-direction: row;
}
}
</style>
</head>
<body>
<div class="container">
<nav>Navigation</nav>
<main>Main content</main>
</div>
</body>
</html>

Correct: rotation that does not lock orientation

A full turn (360 degrees) results in the same position as no rotation, so it does not restrict orientation:

<html lang="en">
<head>
<title>Full rotation example</title>
<style>
@media (orientation: portrait) {
html {
transform: rotateZ(1turn);
}
}
</style>
</head>
<body>
<main>
<p>This page is not orientation-locked.</p>
</main>
</body>
</html>

Detect accessibility issues automatically

Rocket Validator scans your site with complementary accessibility engines, helping teams find issues across every page.

Help us improve our guides

Was this guide helpful?
๐ŸŒ Trusted by teams worldwide

Validate at scale.
Ship accessible websites, faster.

Automated HTML & accessibility validation for large sites. Check thousands of pages against WCAG guidelines and W3C standards in minutes, not days.

Scheduled Reports
API Access
Open Source Standards
$7 / 7 days

Pro Trial

Full Pro access. Cancel anytime.

Start Pro Trial โ†’

Join teams across 40+ countries