Text✨ Premium

Hover Weight

Pure CSS transition from light to black on hover — weight, spacing, and color animate simultaneously, with zero JavaScript.

CSSHoverWeight

You'll get access to the interactive demo with a free account.

This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Text has 56 effects, including 4 free. Explore the category →

3 usage examples

Primary menu — Variable-weight navigation links — Hover Weight example 1

① Primary menu — Variable-weight navigation links

WhenIn a primary navigation (sidebar, header, mobile menu) where labels are short words — Home, Services, About, Contact.
WhyThe weight shift replaces the usual underline or color change with something more expressive: the word 'takes up more space' on hover, making the active item perceivable even against a very dark background.
SettingsOverride on nav items: font-weight 300 → 700 (avoid 900 for short labels — too compressed), letter-spacing 1.5px → 0px, font-size 0.85rem, transition .2s for snappy feedback.
Typographic poster — Large brand keywords — Hover Weight example 2

② Typographic poster — Large brand keywords

WhenA brand presentation screen, portfolio, or typography-centered homepage where each word is a concept (DESIGN · MOTION · CRAFT).
WhyAt large sizes (3rem+), the variable weight axis is spectacular: the Light → Black shift creates strong contrast that catches the eye. Tightening letter-spacing amplifies the visual impact.
Settingsfont-size 3.5rem, font-weight 100 → 900, letter-spacing 10px → -3px, transition .35s, neutral color → brand signature color.
Skills list — Service tags in a portfolio section — Hover Weight example 3

③ Skills list — Service tags in a portfolio section

WhenAn 'Expertise' or 'Services' section listing domains (Branding · UX Design · Motion · Development) that users explore on hover.
WhyThe subtle hover-only effect allows passive exploration. Bolding on hover implicitly signals the item is selectable or expandable, without heavy UI overhead.
Settingsfont-size 1.25rem, font-weight 300 → 800, letter-spacing 2px → 0px, gap 8px, color #fff → #a78bfa (softer violet for body-size text).

How it works

The effect relies entirely on the :hover pseudo-class and the CSS transition property. No JavaScript is needed: each .vf-hover-word declares transition: font-weight .3s, letter-spacing .3s, color .3s, letting the browser interpolate all three properties simultaneously as the pointer enters the element.

The weight transition from 300 (Light) to 900 (Black) exploits the wght axis of the Inter variable font. With a static font, font-weight would snap to the nearest threshold; with Inter (a variable font), the browser continuously interpolates along the weight axis for a smooth animation.

Letter-spacing simultaneously shifts from 4px (expanded) to -1px (tight). This visually compensates for the extra horizontal width that heavier weights introduce in a variable font — condensing the spacing keeps the word's perceived footprint balanced. Color switches from white #fff to violet #8b5cf6, marking the active state without relying on underlines or highlights.

All three properties animate at the same .3s duration, producing a unified visual movement. The structure is minimal: a .vf-hover-scene centered flex column and <span class="vf-hover-word"> elements for each interactive word.

Accessibility

  • prefers-reduced-motion: not implemented — no @media (prefers-reduced-motion) rule is present; transitions always run, including for users who have enabled motion reduction in their OS. Add the rule if the effect is used on a large surface or many words.
  • The effect uses :hover only — no :focus or :focus-visible state is styled in the code. Keyboard-navigating users will not see the weight change. If the effect carries meaning (not purely decorative), add :focus-visible alongside :hover.
  • Color contrast: white #fff on dark background #0a0a0f → ratio ≈ 19.8:1 (WCAG AAA). Violet #8b5cf6 on #0a0a0f → ratio ≈ 4.7:1 (WCAG AA). Both states pass AA.
  • No ARIA attributes are present in the base code. If the words form a navigation or menu, wrap them in a semantic <nav aria-label="…"> or <ul>.
  • The effect is purely visual and decorative in its base form — no modal, no focus trap, no JavaScript focus management.

Browser compatibility

Requires CSS Transitions (universal) and a variable font for smooth weight animation. Inter is available via Google Fonts or locally.

Chrome 86+✓ Full
Firefox 80+✓ Full
Safari 14+✓ Full
Edge 86+✓ Full
Mobile iOS✓ Full
Android Chrome✓ Full

Without a variable font loaded, the <code>font-weight</code> transition snaps to available thresholds (300 → 400 → 700 → 900) instead of animating continuously. The effect still works — weight changes on hover, only the interpolation smoothness is absent. Without CSS Transitions (IE 9 and earlier), the style change is instant but still visible.

The code

HTML structure to paste into your page (CSS + JS available with a premium account):

index.html — structure
<div class="vf-hover-scene">
  <span class="vf-hover-word">WORD 1</span>
  <span class="vf-hover-word">WORD 2</span>
  <span class="vf-hover-word">WORD 3</span>
  <!-- Optional: -->
  <span class="vf-hover-label">Hover the words</span>
</div>
🔒 Unlock the full code — from €2.99 the first month

Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
font-weight (normal state) 300 Starting weight. 100–300 = very light, creates strong contrast with 900. 400 = regular, moderate contrast.
font-weight (:hover state) 900 Target weight on hover. 700 = classic Bold, 900 = maximum Black. Only visible with a variable font loaded.
letter-spacing (normal state) 4px Initial spacing. The wider it is, the more the hover compression feels dramatic.
letter-spacing (:hover state) -1px Spacing on hover. -1px to -3px visually condenses the heavy word; stay above -3px for readability.
color (:hover state) #8b5cf6 Word color on hover. Replace with your accent color to match your design system.
transition .3s Duration for all 3 simultaneous transitions (weight, spacing, color). 0.2s = dry and snappy, 0.5s = slow and smooth.
font-size (on .vf-hover-word) 2rem Base size. The larger the size, the more perceivable the weight animation. Go 4–5rem for poster use.
gap (on .vf-hover-scene) 12px Vertical spacing between words. Increase for breathing room, reduce for a dense list.

FAQ

Smooth with a variable font. The browser interpolates continuously along the wght axis of the typeface. With a static font (legacy Google Fonts or a non-variable custom font), the transition snaps to available thresholds (400, 700…). To guarantee smooth animation, load Inter as a variable font: @import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap').
Add the vf-hover-word class to each target <a>, <span>, or <li>. The effect only touches elements with that class. For smaller nav items, override font-size and the letter-spacing / font-weight values via a more specific selector (nav .vf-hover-word).
Yes, if the text is in a continuous inline flow — the wider word displaces following words. In a centered flex column (as in the demo), each word is on its own line and no shift occurs. Apply the effect to isolated words (headings, labels) or inside a display:flex; flex-direction:column container to avoid the issue.