Skip to content

Hanging Quote Section

A pull quote with the opening mark optically aligned — measured from the real glyph, not a guessed em value.

Proeditorialminimal
Category
Sections
Added
2026-09-21
Deps
none
Updated
2026-09-21

This is a viberdy Pro component

The live preview, the props panel and the write-up are open to everyone. The full source, the AI prompt and CLI install are part of Pro.

Preview
“We design the parts people actually touch. The hinge, the handle, the moment a thing answers back.”
Ana ReisFounder, Blackhorse Yard
advance 0.0px

Props

No runtime dependencies
"use client";

import { useEffect, useId, useRef, useState } from "react";

export function HangingQuoteSection({
  quote = "We design the parts people actually touch. The hinge, the handle, the moment a thing answers back.",
  attribution = "Ana Reis",
  role = "Founder, Blackhorse Yard",
}: {
  quote?: string;
  attribution?: string;
  role?: string;
}) {
  const cls = "hq-" + useId().replace(/:/g, "");
  const measureRef = useRef<HTMLSpanElement>(null);
  const [advance, setAdvance] = useState(0);

  useEffect(() => {

  // ---------------------------------------------------------------
  // Full source available with a viberdy Pro subscription.
  // https://viberdy.dev/pricing
  // ---------------------------------------------------------------
}
Notes

About this section

Optical alignment is the detail that separates typeset copy from typed copy: an opening quotation mark carries so much white space inside its own box that leaving it in the text block makes the left edge look broken, so it hangs into the margin instead. The usual implementation hardcodes a negative indent of about four tenths of an em, which is correct for exactly one typeface at one weight — the advance of an opening quote varies enormously between faces, and again between the curly and the straight form. Measuring the actual character, rendered in the same face, size and weight, and feeding the result to a custom property makes it right for whatever font the page ends up using, and re-measuring once webfonts resolve fixes the case where the first measurement belonged to a fallback. Two smaller decisions matter as much. The offset is applied with text-indent rather than a negative margin, because text-indent moves the first line only, which is precisely what hanging a quote requires, while a margin drags the whole block and every line under it. And the native hanging-punctuation property — still Safari-only — is layered in with a feature query rather than a JavaScript test, both because the two must never apply together and double the hang, and because a JS branch would render differently on the server than on the client.

Curator’s note

A hardcoded -0.4em is right for exactly one typeface. Measure the glyph you are actually rendering.

Related

Pairs well with

Matched on shared tags and category — the entries most likely to be used alongside this one.

Featured
NewPro

An editorial index with sticky year headers, and a switch that demonstrates the overflow ancestor that breaks them.

indexstickyeditorial
Featured

Oversized, tightly-stacked headline words that reveal in on mount — big type as sculpture.

herotypographyeditorial
Pro

Oversized, near-invisible ticker rows scrolling behind the fold as ambient texture.

tickermarqueecss