Contao-Summit 2026

Ankündigung

Collapse
No announcement yet.

Fluid Typography clamp() mit nativem CSS und Custom Properties

Collapse
X
 
  • Filter
  • Zeit
  • Show
Clear All
new posts

    Fluid Typography clamp() mit nativem CSS und Custom Properties

    Ich habe mir eine kleine Lösung für fluid typography nur mit nativem CSS gebaut. Dabei wollte ich die Schriftgrößen zwischen einem Minimum und einem Maximum dynamisch an die Viewport-Breite anpassen, basierend auf der bekannten Formel:
    Code:
    slope = (maxFontSize - minFontSize) / (maxWidth - minWidth)
    yAxisIntersection = -minWidth * slope + minFontSize
    preferredValue = yAxisIntersection[rem] + (slope * 100)[vw]
    Link zur Beschreibung bei CSS-Tricks: https://css-tricks.com/linearly-scal...-the-viewport/

    Tokens im :root

    Zuerst definiere ich die Fontgrößen und Breakpoints als Custom Properties.
    Dabei gibt es zwei Varianten pro Wert:
    • einmal mit Einheit (rem) ? für die direkte Verwendung in clamp()
    • einmal ohne Einheit (nur Zahl) ? damit ich im calc() rechnen kann.


    Beispiel:
    Code:
    :root {
        /* font sizes */
        --font-size-heading-lg-min: 2.125rem;
        --font-size-heading-lg-max: 2.5rem;
        --font-size-heading-lg-min-no-unit: 2.125;
        --font-size-heading-lg-max-no-unit: 2.5;
        --font-size-heading-xl-min: 2.65rem;
        --font-size-heading-xl-max: 3.625rem;
        --font-size-heading-xl-min-no-unit: 2.65;
        --font-size-heading-xl-max-no-unit: 3.625;
        --font-size-heading-xxl-min: 2.875rem;
        --font-size-heading-xxl-max: 6rem;
        --font-size-heading-xxl-min-no-unit: 2.875;
        --font-size-heading-xxl-max-no-unit: 6;
    
        /* breakpoints for fluid typography */
        --fluid-breakpoint-min: 26.25rem; /* 420px */
        --fluid-breakpoint-max: 90rem; /* 1440px */
        --fluid-breakpoint-min-no-unit: 26.25; /* 420px */
        --fluid-breakpoint-max-no-unit: 90; /* 1440px */
    }
    Warum das?
    CSS erlaubt es nicht, Einheiten zu „wegzudividieren“. Man kann keine Länge durch eine Länge teilen (10rem / 2rem ist ungültig).
    Darum trenne ich die Zahlen (unitless) und die Längen.

    Anwendung in h1 und h2

    Für jedes Heading berechne ich lokal die Parameter:
    Code:
    h1 {
        /* fluid typography parameters */
        --min-font-size: var(--font-size-heading-xxl-min);
        --max-font-size: var(--font-size-heading-xxl-max);
    
        --min-font-size-no-unit: var(--font-size-heading-xxl-min-no-unit);
        --max-font-size-no-unit: var(--font-size-heading-xxl-max-no-unit);
    
        /* fluid typography */
        --slope: calc(
            (var(--max-font-size-no-unit) - var(--min-font-size-no-unit)) /
                (var(--fluid-breakpoint-max-no-unit) - var(--fluid-breakpoint-min-no-unit))
        );
        --intercept: calc(
            var(--min-font-size) - (var(--max-font-size-no-unit) - var(--min-font-size-no-unit)) /
                (var(--fluid-breakpoint-max-no-unit) - var(--fluid-breakpoint-min-no-unit)) * var(--fluid-breakpoint-min)
        );
    
        font-size: var(--font-size-heading-xl-min); /* Fallback */
        font-size: clamp(var(--min-font-size), calc(var(--intercept) + var(--slope) * 100vw), var(--max-font-size));
    }
    
    h2 {
        /* fluid typography parameters */
        --min-font-size: var(--font-size-heading-xl-min);
        --max-font-size: var(--font-size-heading-xl-max);
    
        --min-font-size-no-unit: var(--font-size-heading-xl-min-no-unit);
        --max-font-size-no-unit: var(--font-size-heading-xl-max-no-unit);
    
        /* fluid typography */
        --slope: calc(
            (var(--max-font-size-no-unit) - var(--min-font-size-no-unit)) /
                (var(--fluid-breakpoint-max-no-unit) - var(--fluid-breakpoint-min-no-unit))
        );
        --intercept: calc(
            var(--min-font-size) - (var(--max-font-size-no-unit) - var(--min-font-size-no-unit)) /
                (var(--fluid-breakpoint-max-no-unit) - var(--fluid-breakpoint-min-no-unit)) * var(--fluid-breakpoint-min)
        );
    
        font-size: var(--font-size-heading-xl-min); /* Fallback */
        font-size: clamp(var(--min-font-size), calc(var(--intercept) + var(--slope) * 100vw), var(--max-font-size));
    }
    • clamp() sorgt dafür, dass die Schrift nie kleiner als das Minimum und nie größer als das Maximum wird.
    • Der mittlere Teil (intercept + slope * 100vw) gibt den fließenden Übergang zwischen den beiden Werten.
    • Die erste font-size-Zeile ist ein Fallback für alte Browser, die clamp() nicht verstehen.


    Alternativ gibt es auch Apps zum Berechnen der Werte: https://fluid.style
    Last edited by Kopfnuss; 24.09.2025, 15:39.

    #2
    I like!
    Contao-Association unterstützen

    Comment


      #3
      Zitat von Kopfnuss Beitrag anzeigen
      Alternativ gibt es auch Apps zum Berechnen der Werte: https://fluid.style
      Oder https://utopia.fyi/type/calculator/

      Da kann man auch noch Abstände und Grids berechnen.

      Gruß
      Mathias
      The idea is to die young as late as possible!

      Comment


        #4
        Es gibt etliche solcher Generatoren. Derzeit mein Favorit https://www.fluid-type-scale.com/calculate
        Hier kann man auch die Einheit cqi (container inline size) verwenden, was z.B. sehr hilfreich für Schriftgrößen in Textboxen ist.
        Contao-Dokumentation: Contao-Handbuch und Contao-Entwickler-Doku
        Contao-Online-Video-Kurse: Contao Academy
        Funktionalität erweitern: Contao-Erweiterungen

        :cool:Für Dinge die man mit HTML und CSS lösen kann, braucht man kein javascript.





        Comment

        Working...
        X