How to Rotate Text with CSS
Rotate a text element with CSS transforms, or use vertical writing modes when you want text to flow vertically. Includes examples, layout tips, and fixes.
To rotate a whole heading, label, or line as one unit, use transform: rotate(angle). To make text flow vertically, use writing-mode and, if needed, text-orientation. These solve different layout problems: transforms turn an element visually, while writing modes change the direction of text flow.
1. Rotate a whole text element
Use rotate() when the entire element should turn around a point. A positive angle rotates clockwise in a left-to-right context; a negative angle rotates the other way.
<h2 class="rotated-label">Featured</h2>
<style>
.rotated-label {
display: inline-block;
transform: rotate(-90deg);
transform-origin: top left;
}
</style>
The default pivot is the element’s center. Set transform-origin to move it. Common values include center, top left, bottom right, and coordinate values such as 10px 20px.
.badge {
transform: rotate(12deg);
transform-origin: center;
}
.side-label {
transform: rotate(-90deg);
transform-origin: top left;
}
A transform changes visual rendering, but does not make surrounding layout automatically reserve space for the rotated footprint. Check for overlap and adjust the container, margins, or positioning as needed.
2. Make text flow vertically
For a vertical heading or text flow, use writing-mode. MDN describes it as setting whether lines are laid out horizontally or vertically and the direction in which text flows. MDN writing-mode reference.
<h2 class="vertical-heading">Section title</h2>
<style>
.vertical-heading {
writing-mode: vertical-rl;
text-orientation: mixed;
}
</style>
vertical-rl makes lines vertical and advances them from right to left. vertical-lr uses the other line progression. The text-orientation property affects glyph orientation in vertical writing; it applies only with a vertical writing mode.
| Value | Effect | Use when |
|---|---|---|
mixed |
Default. Horizontal-script glyphs are turned while vertical-script characters use natural orientation. | You want conventional vertical text behavior for mixed scripts. |
upright |
Keeps characters upright. | Each glyph should remain upright in a vertical column. |
sideways |
Displays the line turned sideways. | The text should read as a rotated horizontal line. |
See the MDN text-orientation reference and MDN guide to CSS writing modes for script and flow details.
3. Choose the right technique
| Desired result | Use | What changes |
|---|---|---|
| Tilt or turn a label, heading, or complete line | transform: rotate(...) |
The element’s visual rendering around a pivot. |
| Text laid out vertically | writing-mode, optionally text-orientation |
Text flow and character orientation. |
If your goal is only to display a side label, either method might appear similar for Latin text. Prefer writing-mode when vertical flow is the intended layout; prefer a transform when the object itself should be rotated by an arbitrary angle.
4. Layout and direction details
- Pivot: rotation defaults to the element center. Use
transform-originto choose another pivot. - Angle direction: positive angles are clockwise in left-to-right contexts; direction is reversed in right-to-left contexts. See MDN rotate().
- Transform order: transform functions are applied in written order, so changing their order can change the result. For example, rotating and then translating may produce a different position than translating and then rotating.
- Layout footprint: visually transformed content can extend outside its original box. Inspect clipping, overlap, and spacing around it.
- Compatibility: MDN marks
rotate()andtext-orientationas widely available, andwriting-modeas widely available while noting that some parts vary. Check the compatibility tables for the exact value and browsers you support, especially less common sideways behavior.
5. Common problems and fixes
| Problem | Likely cause | Fix |
|---|---|---|
| The rotated element overlaps nearby content. | The transform changes visual coordinates without laying out space for the new footprint. | Adjust its containing layout, dimensions, margins, or positioning; inspect at the target viewport sizes. |
| The text turns around an unexpected point. | The default center pivot is not the intended anchor. | Set transform-origin, for example top left. |
| The writing direction is opposite of what you expect. | vertical-rl and vertical-lr advance lines in different directions. |
Choose the value matching the desired flow and test with the actual script. |
| Characters are sideways when they should be upright. | The writing mode and character orientation are separate choices. | Set text-orientation: upright or another suitable value while using a vertical writing mode. |
| A writing-mode value behaves differently across target browsers. | Support varies for some parts and values. | Check MDN’s compatibility data for the exact feature and verify the actual target browsers. |
| An animated rotation causes discomfort. | Continuous motion can be problematic for some users. | Keep decorative rotation static where possible; for motion, honor prefers-reduced-motion. |
6. Performance and reliability
A static CSS rotation is a straightforward presentation rule. Avoid repeatedly changing layout-affecting styles in script when a static rule can express the design. Test the final result with real text, scripts, font sizes, and narrow viewports: glyph metrics and line wrapping affect the visible footprint. For animated rotation, provide a reduced-motion alternative using @media (prefers-reduced-motion: reduce).
7. Inspect the result in a screenshot
A screenshot is useful for checking the rotated element’s visual footprint, overlap, clipping, and vertical text orientation across viewport sizes. You can use a browser’s built-in capture tools or automate the page with a browser setup of your choice. For repeatable visual checks, ScreenshotNeo is a website screenshot API and MCP server for developers: ScreenshotNeo.
8. Or skip the browser setup
Capture a rendered page with one GET request. The example uses the documented API endpoint and parameters; see the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));
ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server lets AI agents use screenshot tools. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for 1,000 free screenshots a month, with no card required.
9. FAQ
Can I rotate only one word?
Wrap that word in an inline element such as <span>, then apply the transform to that element. Use display: inline-block if needed so it has a transformable box.
Can I use a CSS variable for the angle?
Yes. For example, transform: rotate(var(--angle, 10deg)) lets a custom property supply the angle.
Does rotating text change its reading order?
A transform changes visual presentation; it does not rewrite the text content. Keep the source text in a sensible reading order.


