CSS Custom Properties, JavaScript On-Demand und flexible Typografie

Eine neue Ära für Frontend-Entwickler:innen

Mit dem lang ersehnten Meilenstein in diesem Jahr – der Einstellung von Internet Explorer – sind Frontend-Entwickler endlich in der Lage, eine ganze Reihe von modernen Browserfunktionen zu nutzen. Das haben wir natürlich direkt zum Anlass genommen, Kundenprojekte nach den aktuellsten Standards zu entwickeln und unser Basis-Theme um einiges effizienter und übersichtlicher zu gestalten. Gemeinsam mit einem grossen Refactoring, unser Basis-Theme komplett auf WordPress Full-Site-Editing umzustellen, ist dieses nun unter anderem 40% kleiner als vorher.

Die grossen Verbesserungen, die im WordPress Core in den Versionen 5.9 und 6.0 ausgeliefert wurden – unter anderem die automatische Bereitstellung vieler Ausrichtungs- und Layoutregeln – bedeuteten, dass wir einen Grossteil unseres Legacy-Codes entfernen konnten. Weniger Boilerplate CSS bedeutet vor allem, dass wir uns voll auf das konzentrieren können, was unsere Kundenprojekte erfordern.

CSS Custom Properties

2019 haben wir damit begonnen, benutzerdefinierte CSS Custom Properties – auch als CSS-Variablen bekannt – zu verwenden. Diese ermöglichen es uns, mit Variablen in unserer CSS Codebasis so zu arbeiten, wie wir es eigentlich immer mit SCSS getan haben. Allerdings mit dem grossen Vorteil, dass Custom Properties direkt im Browser landen und auch dort manipulierbar sind.

Anstatt unseren Code immer wieder neu kompilieren zu müssen – zum Beispiel bei einer Änderung der Farbwerten – können wir nun einfach den Wert der CSS-Eigenschaft ändern. Und das nicht nur während der Entwicklung, sondern abhängig von Runtime-Eigenschaften oder gar innerhalb der Kaskade-Hierarchie in CSS. Dadurch wird unser CSS viel übersichtlicher und effizienter.

/* Wir nutzen 'body' als Basis-Element anstelle ':root', damit unser CSS mit WordPress Core konform bleibt. */

body {
    --sht--text-color: #111;
    color: var(--sht--text-color);
}

aside {
    --sht--text-color: #444;
}

Daneben ermöglichen moderne Browser auch die Verwendung von JavaScript, um die Werte von benutzerdefinierten CSS Custom Properties festzulegen. Diese Funktionalität hat unsere Codebasis – vor allem das Zusammenspiel von CSS und JavaScript – ebenfalls in einigen Stellen erheblich vereinfacht. Beispielsweise bei Projekten, in denen der Seitenkopf fixiert ist und den Inhalt versetzt werden muss.

Indem wir die Höhe des Seitenkopfs mithilfe von JavaScript-Event-Listenern beobachten, können wir den Wert einer benutzerdefinierten CSS-Eigenschaft laufend neu definieren. Wir könnten dies auch mit einen berechneten Pixelwert direkt auf das Element erreichen. Durch die Verwendung von CSS Custom Properties können wir den Wert viel einfacher auf mehrere Elemente anwenden.

In JavaScript…

const watchPageHeaderHeight => (){
    document.documentElement.style.setProperty(
        '--sht--page-header--height',
        document.querySelector('.c-masthead').offsetHeight + 'px'
    );
};

watchPageHeaderHeight();
window.addEventListener('load', watchPageHeaderHeight);
window.addEventListener('resize', watchPageHeaderHeight);

…und in CSS…

main, aside {
    padding-top: var(--sht--page-header--height);
}

Performantes JavaScript

Wir legen viel Wert auf der Performance unserer Projekte. Gerade das Laden von JavaScript ist eine dieser Stellen, an denen wir sehr effizient sowohl Lade- als auch Renderzeit sparen können. Wir haben 2019 grundsätzlich aufgehört, jQuery zu verwenden: Wir schreiben seither fast alle unsere Funktionen mit “Vanilla”-JavaScript. Bei komplexeren Interfaces und Webapp-Features nutzen wir vorwiegend Preact, eine extrem kleine Alternative zur ReactJS.

Früher haben wir unseren gesamten JavaScript-Code in einer einzigen, komprimierten Datei geladen. Inzwischen könnten wir dies aber optimieren: Da wir unsere Skripte erst ganz am Ende des HTML-Renderingprozesses laden, können wir sofort erkennen, welche HTML-Elemente sich auf der Seite befinden. Und indem wir unser JavaScript während der Entwicklung bereits in kleinere Dateien aufteilen, können wir nun einzelne Skripte nur dann laden, wenn sie auch wirklich benötigt werden.

// sht_scripts wird als Objekt aus dem HTML durch den Einsatz von wp_localize_script übergeben.
const accordions = document.querySelectorAll('[data-accordion]');

if (!!accordions.length) {
    let script = document.createElement('script');
    script.setAttribute(
        'src',
        sht_scripts.theme.directory_uri + '/assets/scripts/accordion.min.js?version=' + sht_scripts.theme.version
    );
    document.head.appendChild(script);
}

Flexible Typografie

Seit 2010 habe ich die Schriftgrössen für Mobilgeräte, Tabletts und Desktopcomputer auf Mobile-First-Basis mithilfe von CSS Breakpoints definiert. Mit der Übung bei jedem Projekt haben wir eine effiziente Routine erschafft, und es gab selten Probleme. Es kam aber in paar Ausnahmefälle zu Unstimmigkeiten, wo ein Besucher mit einer sehr aussergewöhnlichen Bildschirmgrösse auf die Website kam. Zudem war das CSS teilweise recht komplex. Nämlich dann, wenn viele Breakpoints zum Einsatz kamen oder wo viele Elemente eigene Schriftgrössen hatten.

Um die Problematik zu lösen, unser CSS zu vereinfachen und eine aufgeräumte Typografie zu implementieren, setzen wir nun auf eine eher neue Logik. Und zwar die flexible Definition von typografischen Regeln. Wir beginnen mit der kleinsten Textgrösse – meist für Besucher mit Smartphones – und setzen CSS clamp ein, sodass der Text fliessend grösser wird, bis zu einer maximalen Grösse bei Desktopcomputer.

Entsprechend können wir garantieren, dass die Schriftgrösse bei jeder beliebigen Bildschirmbreite perfekt abgeglichen und lesbar bleibt. Zudem ist unser Code leichter, einfacher und in dieser Zusammenhang ganz von Breakpoints befreit. (Ein Beispielverhalten sieht man bei Codepen.)

body {
    --font-size--0: clamp(1.00rem, calc(0.89rem + 0.54vw), 1.38rem);
    --font-size--1: clamp(1.20rem, calc(1.07rem + 0.64vw), 1.65rem);
    --font-size--2: clamp(1.44rem, calc(1.29rem + 0.77vw), 1.98rem);
    --font-size--3: clamp(1.73rem, calc(1.54rem + 0.93vw), 2.38rem);
    --font-size--4: clamp(2.07rem, calc(1.85rem + 1.11vw), 2.85rem);
    --font-size--5: clamp(2.49rem, calc(2.22rem + 1.33vw), 3.42rem);
    --font-size--6: clamp(2.99rem, calc(2.67rem + 1.60vw), 4.11rem);

    font-size: var(--font-size--0);
}

h1, .h1 {
    font-size: var(--font-size--6);
}

h2, .h2 {
    font-size: var(--font-size--5);
}

/* ...usw. */

Fazit

Moderne Browserfeatures wie CSS Custom Properties Lösen eine ganze Reihe von Problemen, mit denen wir Webentwickler:innen bereits seit jeher zu kämpfen hatten. Gemeinsam mit Meilensteinen im WordPress-Core können wir die Entwicklung stark vereinfachen, legacy Code entfernen und effizienter an den Wünschen unserer Kund:innen arbeiten.

WordPress stellt die Unterstützung von Internet Explorer ein Nächster Post