SolutionsCase StudiesAI ToolsResourcesAboutContact
Get Your Free AI Automation Audit Book a Free 30-Minute Strategy Call
Playground~/frontend Open editor

~/css/text-hover-effects

7 CSS Text Hover Effects

7 Pure CSSPublished 2026-10-05Free · no sign-up

Seven hover effects for headings, menu labels and short phrases: a colour that sweeps across the letters, text that slides up to an identical copy, letters that spread apart, a 3D extrusion that lifts, letters that flip in turn, a strike-through that draws and a covered word that is revealed.

01. Colour Fill Sweep on Hover

TextHover

Hovering a heading sweeps a second colour across the letters from left to right. The heading has a two-colour background split at 50 percent, clipped to the text and twice as wide, and hover shifts its position. Focus within the card triggers it too.

View code
<a class="th1" href="#process"><span>Our process</span></a>
.th1 { font: 900 40px Inter, system-ui, sans-serif; text-decoration: none; color: #101828; }
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .th1 span { background: linear-gradient(90deg, #db2777 50%, #101828 50%) 100% 0 / 200% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; transition: background-position .5s ease; }
  .th1:hover span, .th1:focus-visible span { background-position: 0 0; }
}
.th1:focus-visible { outline: 3px solid #f9a8d4; outline-offset: 4px; border-radius: 4px; }
@media (prefers-reduced-motion: reduce) { .th1 span { transition: none; } }

02. Text Slides Up to a Copy

TextHover

On hover the label slides up out of view and an identical copy slides up into its place, a crisp effect for nav items and buttons. The copy is a pseudo-element reading the text from a data attribute, so it is not read twice by screen readers.

View code
<a class="th2" href="#work" data-t="View our work"><span>View our work</span></a>
.th2 { position: relative; display: inline-block; overflow: hidden; height: 1.25em; color: #f8fafc; font: 800 28px/1.25 Inter, system-ui, sans-serif; text-decoration: none; }
.th2 span, .th2::after { display: block; transition: transform .35s cubic-bezier(.2,.8,.2,1); }
.th2::after { content: attr(data-t); position: absolute; left: 0; top: 100%; color: #22d3ee; }
.th2:hover span, .th2:hover::after, .th2:focus-visible span, .th2:focus-visible::after { transform: translateY(-100%); }
.th2:focus-visible { outline: 2px solid #22d3ee; outline-offset: 4px; }
@media (prefers-reduced-motion: reduce) { .th2 span, .th2::after { transition: none; } }

03. Letter Spacing Expand

TextTypography

Uppercase text spreads its letters apart on hover, a refined effect for fashion and luxury menus. The link has a fixed width and centred text so expanding letters do not push the items around it.

View code
<nav class="th3" aria-label="Collections"><a href="#women">Women</a><a href="#men">Men</a><a href="#home">Home</a></nav>
.th3 { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; box-sizing: border-box; max-width: 100%; }
.th3 a { width: 96px; padding: 8px 0; color: #1c1917; font: 600 13px Inter, system-ui, sans-serif; text-align: center; text-decoration: none; text-transform: uppercase; letter-spacing: .08em; transition: letter-spacing .35s ease, color .35s; }
.th3 a:hover, .th3 a:focus-visible { letter-spacing: .3em; color: #9a3412; }
.th3 a:focus-visible { outline: 2px solid #9a3412; outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .th3 a { transition: color .35s; } }

04. 3D Text Shadow Lift

TextShadow

Stacked text-shadows build a solid 3D extrusion under the word, and on hover the text rises while the extrusion lengthens. Each shadow layer is 1px further down and to the right, and the hover state adds layers for the deeper look.

View code
<a class="th4" href="#arcade">ARCADE</a>
.th4 { display: inline-block; color: #fde047; font: 900 54px Inter, system-ui, sans-serif; text-decoration: none; text-shadow: 1px 1px #ca8a04, 2px 2px #ca8a04, 3px 3px #a16207; transition: transform .25s ease, text-shadow .25s ease; }
.th4:hover, .th4:focus-visible { transform: translate(-3px, -3px); text-shadow: 1px 1px #ca8a04, 2px 2px #ca8a04, 3px 3px #ca8a04, 4px 4px #a16207, 5px 5px #a16207, 6px 6px #854d0e; }
.th4:focus-visible { outline: 2px solid #fde047; outline-offset: 6px; }
@media (prefers-reduced-motion: reduce) { .th4 { transition: none; } .th4:hover, .th4:focus-visible { transform: none; } }

05. Letters Flip One by One

Text3D

Each letter turns a full circle on the y-axis in sequence when the word is hovered. Letters are spans with an index for the delay, wrapped in an element with an aria-label holding the whole word, and the spans are aria-hidden.

View code
<a class="th5" href="#studio" aria-label="Studio"><span aria-hidden="true"><i style="--i:0">S</i><i style="--i:1">t</i><i style="--i:2">u</i><i style="--i:3">d</i><i style="--i:4">i</i><i style="--i:5">o</i></span></a>
.th5 { color: #4338ca; font: 900 48px Inter, system-ui, sans-serif; text-decoration: none; }
.th5 i { display: inline-block; font-style: normal; transition: transform .5s ease; transition-delay: calc(var(--i) * 50ms); }
.th5:hover i, .th5:focus-visible i { transform: rotateY(360deg); }
.th5:focus-visible { outline: 3px solid #a5b4fc; outline-offset: 4px; border-radius: 4px; }
@media (prefers-reduced-motion: reduce) { .th5 i { transition: none; } .th5:hover i, .th5:focus-visible i { transform: none; } }

06. Strike-Through Draw

TextLine

A line draws through the old price when the line is hovered, useful for prices, to-do items or a playful menu. It is decoration only, since the words Was and now already carry the meaning. The line is a pseudo-element scaled from zero along the x axis with a slight skew.

View code
<p class="th6">Was <span>$120</span> now <b>$84</b></p>
.th6 { margin: 0; color: #cbd5e1; font: 600 22px Inter, system-ui, sans-serif; }
.th6 span { position: relative; color: #e2e8f0; cursor: default; }
.th6 span::after { content: ""; position: absolute; left: -4px; right: -4px; top: 52%; height: 3px; border-radius: 2px; background: #f43f5e; transform: scaleX(0) rotate(-6deg); transform-origin: left; transition: transform .35s ease; }
.th6:hover span::after { transform: scaleX(1) rotate(-6deg); }
.th6 b { color: #4ade80; }
@media (prefers-reduced-motion: reduce) { .th6 span::after { transition: none; } }

07. Hidden Word Revealed on Hover

TextReveal

Part of the headline is covered by a solid block that slides away on hover or focus to reveal the punchline. The hidden words are still real text in the DOM, so screen readers read the full sentence whether or not the block has moved.

View code
<p class="th7" tabindex="0">We build stores that <span class="w">actually sell<span class="cov" aria-hidden="true"></span></span>.</p>
.th7 { width: 300px; max-width: 100%; margin: 0; color: #101828; font: 800 26px/1.3 Inter, system-ui, sans-serif; }
.th7 .w { position: relative; display: inline-block; color: #7c3aed; }
.th7 .cov { position: absolute; inset: -2px -4px; background: #101828; border-radius: 4px; transform-origin: right; transition: transform .45s cubic-bezier(.7,0,.3,1); }
.th7:hover .cov, .th7:focus-visible .cov { transform: scaleX(0); }
.th7:focus-visible { outline: 3px solid #c4b5fd; outline-offset: 4px; border-radius: 4px; }
@media (prefers-reduced-motion: reduce) { .th7 .cov { transition: none; } }

About these CSS Text Hover Effects

Hover effects belong on interactive text

If text reacts to the pointer, people assume it does something. Put these effects on links and buttons, and mirror the hover state on :focus-visible so keyboard users see it too.

Gradient tricks with background-clip

Clipping a two-colour background to the text and moving its position paints a colour sweep across the letters. Keep a plain color as a fallback inside @supports.

Duplicates must not be read twice

The slide-to-copy effect draws its second line with a pseudo-element from a data- attribute, so the label is announced once. Split-letter effects put the real word in an aria-label on the link.

Stop layout from shifting

Effects that change letter spacing or weight change the text's width. Give the element a fixed width or use transforms so neighbouring items do not move on hover.

Frequently asked questions

Do these work on touch screens?

The hover state shows briefly on tap. The text is always fully readable without it.

Which effect is best for a nav menu?

The slide-to-copy and letter-spacing effects suit menus; fills and 3D shadows suit single headings.

Will the 3D shadow hurt performance?

Text shadows are cheap at this size. Avoid animating dozens of them at once.