{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "unterstreichung-varianten",
 "name": "Unterstreichungs-Varianten",
 "name_en": "Link underline hover animations",
 "kurz": "Linien, die sich beim Hover einzeichnen: links rein, rechts raus, aus der Mitte oder als Wiederkehr, im Fließtext über Zeilenumbrüche.",
 "kategorie": "Hover",
 "kategorie_slug": "hover",
 "kategorie_nr": 7,
 "bau_chat": "C4",
 "prioritaet": "A",
 "trendstatus": "aufsteigend",
 "belegstatus": "belegt",
 "website_belege": 4,
 "stimmung": [
  "ruhig",
  "editorial",
  "präzise"
 ],
 "stimmung_roh": [
  "editorial",
  "ruhig",
  "präzise",
  "klassisch"
 ],
 "technik": [
  "css"
 ],
 "technik_gruppen": [
  "css"
 ],
 "leistungskosten": "niedrig",
 "steckbrief": {
  "beschreibung": "Links tragen eine feine Linie. Beim Hover zeichnet sie sich ein, meist von links nach rechts. Beim Verlassen läuft sie nach rechts hinaus, weil transform-origin wechselt. Andere Varianten wachsen aus der Mitte, oder eine sichtbare Linie läuft hinaus und eine zweite kommt nach. Technisch geht das per Pseudo-Element, per Hintergrund-Verlauf oder nativ mit text-decoration-inset.",
  "warum_es_wirkt": "Der Fließtext bleibt ruhig, trotzdem gibt der Link klares Feedback. Die durchlaufende Richtung, links rein und rechts raus, wirkt bewusst gestaltet und nicht wie ein Browser-Standard.",
  "wann_einsetzen": "Links im Fließtext, Navigation, Footer und Inline-CTAs in editorialen Layouts.",
  "wann_nicht": "Pseudo-Elemente nicht für Links, die umbrechen können: Die Linie sitzt dann falsch. Dort Hintergrund-Verlauf oder text-decoration nehmen. Die Linie im Fließtext nie ganz entfernen, wenn Links sonst nur an der Farbe erkennbar wären.",
  "varianten": [
   "Durchlauf: scaleX 0 → 1, rein mit origin links, raus mit origin rechts (Rejouice 600 ms, cubic-bezier(0.85, 0, 0.15, 1); Codrops 300 ms)",
   "Aus der Mitte: origin center, 2 px, 300 ms cubic-bezier(0.215, 0.61, 0.355, 1) (K72)",
   "Wiederkehr: sichtbare Linie läuft rechts hinaus (300 ms), zweite kommt von links (400 ms, 100 ms später) (Codrops)",
   "Zwei Linien gegenläufig oder Linie und Text verschieben sich gemeinsam (Codrops)",
   "Clip-Path teilt die Linie in der Mitte (Codrops)",
   "Ruhig: Linie halbtransparent, bei Hover und Fokus volle Farbe und dicker (color-mix)",
   "Kringel als SVG, per clip-path inset eingezeichnet (etwa 0,6 s)",
   "Hintergrund-Verlauf (background-size 0 → 100 %) für mehrzeilige Links",
   "Nativ: text-decoration-inset 0 100% → 0 0 (Chrome 154), dazu text-decoration-skip-spaces: all für wortweise Linien (Chrome 155); ohne Unterstützung steht die Linie"
  ],
  "umsetzung": "Einzeilig: a { position: relative } a::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: currentColor; transform: scaleX(0); transform-origin: 100% 50%; transition: transform .6s cubic-bezier(.85,0,.15,1) } a:is(:hover, :focus-visible)::after { transform: scaleX(1); transform-origin: 0 50% }. Mehrzeilig: a > span { background: linear-gradient(currentColor, currentColor) no-repeat 100% 100% / 0% 1px; transition: background-size .6s cubic-bezier(.85,0,.15,1) } a:is(:hover, :focus-visible) > span { background-size: 100% 1px; background-position-x: 0 }. Die ruhige Grundlinie liegt als zweiter Verlauf auf dem a. Nativ und progressiv: a { text-decoration: underline 1px; text-underline-offset: .26em } und in @supports (text-decoration-inset: 0 100%) unter (hover: hover) und ohne reduzierte Bewegung text-decoration-inset von 0 100% auf 0 0 (Prozent beziehen sich auf die Breite der Box; Chrome 154, Stand 02.11.2026 nur Chrome). Für eine ruhige Grundlinie im Fließtext trägt das a die blasse Linie und ein inneres span die wachsende. text-decoration-skip-spaces: all (Chrome 155) unterstreicht Wort für Wort; nur setzen, wenn das gewollt ist, normale Links brauchen es nicht. Ohne Support bleibt die Linie stehen und wird bei Hover und Fokus kräftiger. Wie die Einrückung bei umbrochenen Links wirkt, beschreibt die Chrome-Doku nicht: im Zielbrowser prüfen.",
  "mobil": "Ohne Hover steht die Linie dauerhaft, gedämpft. Beim Antippen (:active) wird sie kurz kräftig und dicker.",
  "reduzierte_bewegung": "Linie immer sichtbar. Hover und Fokus wechseln nur Farbe und Dicke, ohne Bewegung.",
  "barrierefreiheit": "Links im Fließtext nicht nur über Farbe unterscheiden: Grundlinie behalten. Fokus zeigt dasselbe wie Hover (:focus-visible)."
 },
 "messwerte": {
  "easing": "cubic-bezier(.85,0,.15,1) (Rejouice); cubic-bezier(0.215,0.61,0.355,1) (K72)",
  "dauer_ms": "500 (14islands); 600 (Rejouice); 300 (K72)",
  "stagger_ms": "",
  "distanz": "Dicke 1–2 px",
  "sonstiges": "Varianten real: origin right/left/center",
  "herkunft": "beobachtet",
  "quelle": "https://www.rejouice.com/ ; https://k72.ca/assets/styles/main.css ; https://14islands.com/"
 },
 "kurve": {
  "bezier": [
   0.85,
   0.0,
   0.15,
   1.0
  ],
  "css": "cubic-bezier(0.85, 0, 0.15, 1)",
  "name": "circ.inOut",
  "dauer_ms": 500
 },
 "gesehen_bei": [
  {
   "seite": "Codrops LineHoverStyles (Repo/Demo)",
   "url": "https://github.com/codrops/LineHoverStyles",
   "auszeichnung": "",
   "beobachtung": "CSS gelesen: ::before scaleX mit origin-Wechsel 100 %→0 %, 0.3 s; Kurven cubic-bezier(0.7,0,0.2,1) raus / (0.4,1,0.8,1) rein; zweite Linie 0.4 s mit 0.1 s Verzögerung.",
   "art": "demo"
  },
  {
   "seite": "Chrome Developers: Custom text decorations",
   "url": "https://developer.chrome.com/docs/modern-web-guidance/guides/visual-design/custom-text-decorations",
   "auszeichnung": "",
   "beobachtung": "Offiziell: text-decoration-thickness max(1px,.08em), underline-offset .2em; Reveal per text-decoration-inset 0 100% → 0 0 in 0.25 s ease-out, nur unter prefers-reduced-motion: no-preference; Squiggle per clip-path ~0.6 s.",
   "art": "artikel"
  },
  {
   "seite": "Codrops ButtonHoverStyles",
   "url": "https://github.com/codrops/ButtonHoverStyles",
   "auszeichnung": "",
   "beobachtung": "Gleiche Kurvenfamilie (0.7,0,0.2,1) für flächige scaleX-Hintergründe.",
   "art": "demo"
  },
  {
   "seite": "Osmo",
   "url": "https://www.osmo.supply/",
   "auszeichnung": "",
   "beobachtung": "Eigene Site: [data-underline-link]::before scaleX(0), transform-origin right, transition transform var(--duration-default) var(--cubic-default) – klassisches Ein-links/Aus-rechts.",
   "art": "website"
  },
  {
   "seite": "14islands",
   "url": "https://14islands.com/",
   "auszeichnung": "",
   "beobachtung": "Desktop-Links: :after border-top, transform-origin right, scaleX(0), transition transform .5s.",
   "art": "website"
  },
  {
   "seite": "Rejouice",
   "url": "https://www.rejouice.com/",
   "auszeichnung": "",
   "beobachtung": "Aktiv-Link :after Höhe 1 px, scaleX(0), transform-origin 0 50%, transition transform .6s cubic-bezier(.85,0,.15,1).",
   "art": "website"
  },
  {
   "seite": "K72",
   "url": "https://k72.ca/",
   "auszeichnung": "",
   "beobachtung": "Linie 2 px, scaleX(0) mit transform-origin center (wächst aus der Mitte), .3s cubic-bezier(0.215,0.61,0.355,1).",
   "art": "website",
   "browser_gemessen": true
  }
 ],
 "tutorials": [
  {
   "titel": "Codrops: Line Hover Styles (Artikel)",
   "url": "https://tympanus.net/codrops/?p=53312"
  },
  {
   "titel": "Chrome: Custom text decorations",
   "url": "https://developer.chrome.com/docs/modern-web-guidance/guides/visual-design/custom-text-decorations"
  }
 ],
 "kombinierbar_mit": [
  "text-roll-hover",
  "nachbarn-reagieren-hover"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/hover/unterstreichung-varianten/",
  "meta": "https://cecodesign.de/lab/fundus/hover/unterstreichung-varianten/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/hover/unterstreichung-varianten/demo"
 },
 "herkunft": {
  "quelldateien": [
   "hover.json",
   "patch-belege-1.json"
  ],
  "pruefnotizen": [
   "patch-belege-1.json: 4 Produktionsbelege."
  ]
 },
 "bau": {
  "status": "fertig",
  "kurz": "Linien, die sich beim Hover einzeichnen: links rein, rechts raus, aus der Mitte oder als Wiederkehr, im Fließtext über Zeilenumbrüche.",
  "demo": true,
  "abhaengigkeiten": [],
  "werte": {
   "durchlauf": {
    "easing": "cubic-bezier(0.85, 0, 0.15, 1)",
    "dauer_ms": 600,
    "dicke_px": 1,
    "transform_origin_ein": "0% 50%",
    "transform_origin_aus": "100% 50%",
    "quelle": "Rejouice"
   },
   "mitte": {
    "easing": "cubic-bezier(0.215, 0.61, 0.355, 1)",
    "dauer_ms": 300,
    "dicke_px": 2,
    "transform_origin": "50% 50%",
    "quelle": "K72"
   },
   "wiederkehr": {
    "raus_easing": "cubic-bezier(0.7, 0, 0.2, 1)",
    "raus_dauer_ms": 300,
    "rein_easing": "cubic-bezier(0.4, 1, 0.8, 1)",
    "rein_dauer_ms": 400,
    "rein_verzoegerung_ms": 100,
    "dicke_px": 1,
    "verlassen": "ohne Übergang (beide Linien voll, kein sichtbarer Sprung)",
    "quelle": "Codrops LineHoverStyles"
   },
   "einzeilig": "a::after, position absolute, bottom 0, height var(--dicke), background currentColor, transform scaleX(0 → 1); Link inline-block mit padding-bottom 3px",
   "fliesstext": "a trägt Grundlinie (linear-gradient, 100% × 1px, rgba(22,21,19,.26)), inneres span die aktive Linie (background-size 0% → 100% × var(--dicke), background-position-x wie transform-origin, position-y calc(100% - .08em), box-decoration-break slice)",
   "akzent_fliesstext": "#17818b (Linie und Textfarbe bei Hover, Farbe 150 ms linear)",
   "touch": "Linie fest, opacity .32; :active opacity 1 und 2px, 150 ms linear",
   "reduziert": "Linie fest, opacity .32 bzw. Grundlinie; Hover/Fokus volle Farbe und 2px, nur opacity 150 ms linear",
   "vorfuehrung": "Zeiger 650 ms Fahrt, 1300 ms Halt je Link, 5 Links, Variante wechselt pro Runde",
   "inset": {
    "technik": "native Unterstreichung, kein Pseudo-Element, kein Hintergrund-Verlauf: text-decoration-line underline, thickness var(--dicke) 1px, text-underline-offset .26em",
    "wachsen": "@supports (text-decoration-inset: 0 100%) und (hover: hover), nicht reduziert: text-decoration-inset 0 100% → 0 0",
    "easing": "cubic-bezier(0.215, 0.61, 0.355, 1)",
    "dauer_ms": 300,
    "fliesstext": "a trägt die ruhige Grundlinie (text-decoration-color rgba(22,21,19,.26)), inneres span die wachsende Akzentlinie #17818b; zwei native Linien übereinander",
    "skip_spaces": "@supports (text-decoration-skip-spaces: all): Navigation, CTA und Fuß wortweise unterstrichen",
    "rueckfall": "ohne text-decoration-inset (und auf Touch, bei reduzierter Bewegung): Linie steht in rgba(22,21,19,.26); Hover, Fokus, :active currentColor und 2 px, Farbe 150 ms linear; Werte-Zeile nennt, was der Browser kann",
    "browser": "text-decoration-inset Chrome 154 (22.09.2026), text-decoration-skip-spaces Chrome 155 (06.10.2026); Safari und Firefox ohne (Stand 02.11.2026)"
   }
  },
  "ausloeser": "hover",
  "touch": "Kein Hover: alle Linien dauerhaft sichtbar (gedämpft), beim Antippen (:active) kurz kräftig und 2 px dick.",
  "reduziert": "Keine Zeichen-Animation. Linien stehen immer; Hover und Fokus machen sie nur kräftiger und dicker (2 px).",
  "korrekturen": {
   "beschreibung": "Links tragen eine feine Linie. Beim Hover zeichnet sie sich ein, meist von links nach rechts. Beim Verlassen läuft sie nach rechts hinaus, weil transform-origin wechselt. Andere Varianten wachsen aus der Mitte, oder eine sichtbare Linie läuft hinaus und eine zweite kommt nach. Technisch geht das per Pseudo-Element, per Hintergrund-Verlauf oder nativ mit text-decoration-inset.",
   "warum_es_wirkt": "Der Fließtext bleibt ruhig, trotzdem gibt der Link klares Feedback. Die durchlaufende Richtung, links rein und rechts raus, wirkt bewusst gestaltet und nicht wie ein Browser-Standard.",
   "wann_einsetzen": "Links im Fließtext, Navigation, Footer und Inline-CTAs in editorialen Layouts.",
   "wann_nicht": "Pseudo-Elemente nicht für Links, die umbrechen können: Die Linie sitzt dann falsch. Dort Hintergrund-Verlauf oder text-decoration nehmen. Die Linie im Fließtext nie ganz entfernen, wenn Links sonst nur an der Farbe erkennbar wären.",
   "varianten": [
    "Durchlauf: scaleX 0 → 1, rein mit origin links, raus mit origin rechts (Rejouice 600 ms, cubic-bezier(0.85, 0, 0.15, 1); Codrops 300 ms)",
    "Aus der Mitte: origin center, 2 px, 300 ms cubic-bezier(0.215, 0.61, 0.355, 1) (K72)",
    "Wiederkehr: sichtbare Linie läuft rechts hinaus (300 ms), zweite kommt von links (400 ms, 100 ms später) (Codrops)",
    "Zwei Linien gegenläufig oder Linie und Text verschieben sich gemeinsam (Codrops)",
    "Clip-Path teilt die Linie in der Mitte (Codrops)",
    "Ruhig: Linie halbtransparent, bei Hover und Fokus volle Farbe und dicker (color-mix)",
    "Kringel als SVG, per clip-path inset eingezeichnet (etwa 0,6 s)",
    "Hintergrund-Verlauf (background-size 0 → 100 %) für mehrzeilige Links",
    "Nativ: text-decoration-inset 0 100% → 0 0 (Chrome 154), dazu text-decoration-skip-spaces: all für wortweise Linien (Chrome 155); ohne Unterstützung steht die Linie"
   ],
   "umsetzung": "Einzeilig: a { position: relative } a::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: currentColor; transform: scaleX(0); transform-origin: 100% 50%; transition: transform .6s cubic-bezier(.85,0,.15,1) } a:is(:hover, :focus-visible)::after { transform: scaleX(1); transform-origin: 0 50% }. Mehrzeilig: a > span { background: linear-gradient(currentColor, currentColor) no-repeat 100% 100% / 0% 1px; transition: background-size .6s cubic-bezier(.85,0,.15,1) } a:is(:hover, :focus-visible) > span { background-size: 100% 1px; background-position-x: 0 }. Die ruhige Grundlinie liegt als zweiter Verlauf auf dem a. Nativ und progressiv: a { text-decoration: underline 1px; text-underline-offset: .26em } und in @supports (text-decoration-inset: 0 100%) unter (hover: hover) und ohne reduzierte Bewegung text-decoration-inset von 0 100% auf 0 0 (Prozent beziehen sich auf die Breite der Box; Chrome 154, Stand 02.11.2026 nur Chrome). Für eine ruhige Grundlinie im Fließtext trägt das a die blasse Linie und ein inneres span die wachsende. text-decoration-skip-spaces: all (Chrome 155) unterstreicht Wort für Wort; nur setzen, wenn das gewollt ist, normale Links brauchen es nicht. Ohne Support bleibt die Linie stehen und wird bei Hover und Fokus kräftiger. Wie die Einrückung bei umbrochenen Links wirkt, beschreibt die Chrome-Doku nicht: im Zielbrowser prüfen.",
   "mobil": "Ohne Hover steht die Linie dauerhaft, gedämpft. Beim Antippen (:active) wird sie kurz kräftig und dicker.",
   "reduzierte_bewegung": "Linie immer sichtbar. Hover und Fokus wechseln nur Farbe und Dicke, ohne Bewegung.",
   "barrierefreiheit": "Links im Fließtext nicht nur über Farbe unterscheiden: Grundlinie behalten. Fokus zeigt dasselbe wie Hover (:focus-visible)."
  },
  "geprueft": "02.11.2026",
  "notiz": "Journal-Ausschnitt eines erfundenen Gestaltungsstudios. Zwei Techniken nebeneinander: Navigation, CTA und Fuß mit Pseudo-Element (scaleX), Fließtext mit Hintergrund-Verlauf auf a + span, damit die Linie über Zeilenumbrüche läuft und eine ruhige Grundlinie bleibt. Drei Varianten per Umschalter (Durchlauf, Mitte, Wiederkehr) als CSS-Token-Sätze. Vorführung: gezeichneter Zeiger fährt fünf Links ab, Variante wechselt pro Runde. Bilder 01.11.2026: eigene Bilder statt Portfolio. Zugang 02.11.2026: --leise Alpha .56 → .66 (5,5:1 auf #efece5). 320 px: body-Raster mit minmax(0, 1fr), Variantenschalter darf umbrechen, Werte-Zeile bricht lange Ketten um. Kontrastmodus: Knöpfe mit Rahmen ButtonText. Korrektur 02.11.2026: Regel 13 nachgerüstet (?v=, replaceState, bau.varianten mit knopf) und vierte Variante „inset“: native Unterstreichung mit text-decoration-inset 0 100% → 0 0 (Chrome 154, developer.chrome.com Release Notes 154 und Guide „Custom text decorations“) und text-decoration-skip-spaces: all (Chrome 155, Web Features Explorer) für Navigation, CTA und Fuß, beides per @supports. Rückfall sichtbar: ruhige native Linie, Hover/Fokus kräftig 2 px; Werte-Zeile sagt, was der Browser kann. Headless-Chromium 153 kennt beides nicht, der unterstützte Zweig ist deshalb ungeprüft. Galerie-Vorschau ohne ?v= wechselt weiter durch die ersten drei Varianten, mit ?v= bleibt sie bei der gewählten.",
  "varianten": [
   {
    "id": "durchlauf",
    "name": "Durchlauf: links rein, rechts raus",
    "knopf": "Durchlauf",
    "wann": "Editoriale Seiten, Studios, Magazine: die Grundvariante für Navigation und Fließtext, ruhig und klar gerichtet.",
    "werte": {
     "easing": "cubic-bezier(0.85, 0, 0.15, 1)",
     "dauer_ms": 600,
     "dicke_px": 1,
     "transform_origin_ein": "0% 50%",
     "transform_origin_aus": "100% 50%",
     "quelle": "Rejouice"
    }
   },
   {
    "id": "mitte",
    "name": "Aus der Mitte, 2 px",
    "knopf": "Mitte",
    "wann": "Kräftigere Marken und kurze Navigationen, wenn die Linie als Akzent sichtbar sein soll.",
    "werte": {
     "easing": "cubic-bezier(0.215, 0.61, 0.355, 1)",
     "dauer_ms": 300,
     "dicke_px": 2,
     "transform_origin": "50% 50%",
     "quelle": "K72"
    }
   },
   {
    "id": "wiederkehr",
    "name": "Wiederkehr: Linie läuft hinaus, neue kommt nach",
    "knopf": "Wiederkehr",
    "wann": "Wenn Links schon unterstrichen stehen sollen (Fließtext, Barrierefreiheit) und der Hover trotzdem Bewegung zeigt.",
    "werte": {
     "raus_easing": "cubic-bezier(0.7, 0, 0.2, 1)",
     "raus_dauer_ms": 300,
     "rein_easing": "cubic-bezier(0.4, 1, 0.8, 1)",
     "rein_dauer_ms": 400,
     "rein_verzoegerung_ms": 100,
     "dicke_px": 1,
     "verlassen": "ohne Übergang (beide Linien voll, kein sichtbarer Sprung)",
     "quelle": "Codrops LineHoverStyles"
    }
   },
   {
    "id": "inset",
    "name": "Nativ mit text-decoration-inset",
    "knopf": "Nativ inset",
    "wann": "Wenn der Code schlank bleiben soll und Chrome-Nutzer die wachsende Linie sehen dürfen: echte Unterstreichung ohne Pseudo-Element und Verlauf, andere Browser zeigen die ruhige Linie.",
    "werte": {
     "technik": "native Unterstreichung, kein Pseudo-Element, kein Hintergrund-Verlauf: text-decoration-line underline, thickness var(--dicke) 1px, text-underline-offset .26em",
     "wachsen": "@supports (text-decoration-inset: 0 100%) und (hover: hover), nicht reduziert: text-decoration-inset 0 100% → 0 0",
     "easing": "cubic-bezier(0.215, 0.61, 0.355, 1)",
     "dauer_ms": 300,
     "fliesstext": "a trägt die ruhige Grundlinie (text-decoration-color rgba(22,21,19,.26)), inneres span die wachsende Akzentlinie #17818b; zwei native Linien übereinander",
     "skip_spaces": "@supports (text-decoration-skip-spaces: all): Navigation, CTA und Fuß wortweise unterstrichen",
     "rueckfall": "ohne text-decoration-inset (und auf Touch, bei reduzierter Bewegung): Linie steht in rgba(22,21,19,.26); Hover, Fokus, :active currentColor und 2 px, Farbe 150 ms linear; Werte-Zeile nennt, was der Browser kann",
     "browser": "text-decoration-inset Chrome 154 (22.09.2026), text-decoration-skip-spaces Chrome 155 (06.10.2026); Safari und Firefox ohne (Stand 02.11.2026)"
    }
   }
  ]
 }
}
