Vaadin Flow ermöglicht es, komplette Webanwendungen ausschließlich in Java zu entwickeln. Komponenten, Layouts, Navigation und sogar komplexe UI-Strukturen lassen sich serverseitig modellieren, ohne direkt mit HTML oder JavaScript arbeiten zu müssen. Dieser Ansatz ist einer der Hauptgründe, warum Vaadin besonders in Java-zentrierten Projekten beliebt ist.
Mit zunehmender Größe eines Projekts entsteht jedoch ein typisches Problem: Styling wird häufig direkt im Java-Code vorgenommen. Vaadin erlaubt dies bequem über die Methode getStyle().set(…). Dadurch lassen sich Abstände, Farben oder Layout-Eigenschaften schnell anpassen. In kleinen Prototypen wirkt dieses Vorgehen zunächst harmlos und sogar praktisch.
Table of Contents
- Das Problem mit Inline-Styling in Vaadin Flow
- Trennung von Struktur und Darstellung: Java vs. CSS
- Inline-Styles durch CSS-Klassen ersetzen
- Struktur der CSS-Dateien in einer Vaadin-Flow-Anwendung
- Refactoring realer Views: Beispiele aus dem URL-Shortener
- Best Practices für CSS in Vaadin-Flow-Anwendungen
- Fazit der Refaktorierung
In größeren Anwendungen führt diese Praxis jedoch schnell zu einem schwer wartbaren Codezustand. Styling-Informationen verteilen sich über zahlreiche Views und Komponenten. Änderungen am Design müssen an vielen Stellen im Java-Code vorgenommen werden. Wiederverwendbarkeit von Styles wird praktisch unmöglich, und die Trennung zwischen UI-Logik und Präsentationsebene verschwimmt zunehmend.
Ein typisches Beispiel sieht in vielen Vaadin-Projekten etwa so aus:
component.getStyle()
.set("padding", "var(--lumo-space-m)")
.set("border-radius", "var(--lumo-border-radius-l)");
Solche Konstrukte finden sich dann häufig in nahezu jeder View. Mit der Zeit entsteht eine Mischung aus Layoutlogik, Komponentenstruktur und CSS-Definitionen direkt im Java-Code.
Im Open-Source-Projekt URL-Shortener, zeigte sich genau dieses Problem. Mehrere Views enthielten Inline-Styling, das ursprünglich für schnelle UI-Anpassungen gedacht war. Mit wachsender Funktionalität wurde jedoch deutlich, dass dieses Muster langfristig nicht tragfähig ist.
Das Ziel der folgenden Refaktorierung war daher klar definiert:
- Entfernen von Inline-Styling aus den Views
- Einführung klarer CSS-Klassen
- saubere Trennung zwischen Struktur (Java) und Darstellung (CSS)
- bessere Wartbarkeit und Wiederverwendbarkeit der UI
Der Artikel beschreibt Schritt für Schritt, wie eine bestehende Vaadin-UI von Inline-Styling zu einer strukturierten CSS-Architektur überführt werden kann. Die Beispiele stammen direkt aus der realen Anwendung und zeigen typische Situationen, die in vielen Vaadin-Projekten auftreten.
Dabei geht es nicht darum, Vaadin komplett CSS-getrieben zu machen. Vaadin bleibt weiterhin ein serverseitiges UI-Framework. Vielmehr geht es darum, eine klare Verantwortungsaufteilung einzuführen: Java definiert die Struktur der Benutzeroberfläche, während CSS für deren visuelle Gestaltung zuständig ist.
Diese scheinbar kleine Änderung hat erhebliche Auswirkungen auf die Wartbarkeit einer Anwendung – besonders dann, wenn eine Vaadin-Anwendung über Jahre hinweg weiterentwickelt wird.
Das Problem mit Inline-Styling in Vaadin Flow
Auf den ersten Blick wirkt die Methode getStyle().set(…) in Vaadin Flow äußerst praktisch. Mit wenigen Zeilen lassen sich Abstände anpassen, Layoutprobleme korrigieren oder Farben verändern – direkt im Java-Code der jeweiligen View. Gerade in frühen Projektphasen oder während der Entwicklung von Prototypen erscheint dieser Ansatz schnell und unkompliziert.
In realen Anwendungen zeigt sich jedoch häufig eine andere Entwicklung. Mit zunehmender Größe eines Projekts beginnen sich Inline-Styles über zahlreiche Views hinweg zu verteilen. Was zunächst nur kleine Anpassungen waren, wird nach und nach zu einer Vielzahl lokaler Layout- und Stylingkorrekturen, die direkt im Java-Code implementiert sind.
Ein typischer Ausschnitt aus einer Vaadin-Anwendung könnte beispielsweise so aussehen:
component.getStyle().set("padding", "var(--lumo-space-m)");
layout.getStyle().set("gap", "var(--lumo-space-l)");
button.getStyle().set("margin-left", "auto");
Jede einzelne dieser Zeilen ist für sich genommen harmlos. Zusammengenommen führen sie jedoch zu mehreren strukturellen Problemen.
Erstens verteilt sich das Styling über die gesamte Anwendung. Anstatt eine zentrale Stelle zu haben, an der das visuelle Erscheinungsbild definiert ist, befinden sich Designentscheidungen in vielen verschiedenen Java-Klassen. Wenn sich später beispielsweise die Abstände eines Layouts oder die Darstellung bestimmter Komponenten ändern soll, müssen Entwickler zunächst die entsprechenden Stellen im Code finden.
Zweitens wird Wiederverwendbarkeit erschwert. Viele Layoutmuster – etwa Kartenlayouts, typische Abstände oder Ausrichtungen – tauchen in einer Anwendung mehrfach auf. Werden diese jedoch als Inline-Styles definiert, existieren sie in jeder View erneut. Änderungen müssen dann an mehreren Stellen vorgenommen werden.
Drittens verwischt Inline-Styling die architektonische Trennung zwischen Struktur und Darstellung. Java-Klassen definieren eigentlich die Struktur der Benutzeroberfläche, orchestrieren Komponenten und reagieren auf Benutzerinteraktionen. Wenn CSS-Eigenschaften direkt in diese Klassen integriert werden, vermischt sich Präsentationslogik mit der strukturellen Definition der UI.
Dieses Problem tritt besonders deutlich in größeren Vaadin-Anwendungen auf, die über einen längeren Zeitraum weiterentwickelt werden. Kleine visuelle Anpassungen sammeln sich an, und aus einzelnen getStyle().set(…)-Aufrufen entsteht nach und nach eine implizite Stylingstrategie – verteilt über zahlreiche Klassen.
Im Open-Source-Projekt URL-Shortener zeigte sich genau dieses Muster. In mehreren Views, darunter MainLayout, AboutView und CreateView, wurden Layout- und Stylinganpassungen direkt im Java-Code vorgenommen. Obwohl die Anwendung funktional korrekt blieb, wurde das visuelle Verhalten der UI zunehmend schwieriger nachzuvollziehen.
Die Refaktorierung zielte daher nicht lediglich darauf ab, einzelne Style-Aufrufe zu entfernen. Stattdessen sollte eine klare Regel eingeführt werden:
Java definiert die Struktur der Benutzeroberfläche – CSS definiert deren visuelle Gestaltung.
Diese Trennung wirkt zunächst wie eine kleine organisatorische Änderung. In der Praxis verbessert sie jedoch die Wartbarkeit der Anwendung erheblich. Styles lassen sich zentral definieren, wiederverwenden und konsistent über mehrere Views hinweg einsetzen.
In den folgenden Abschnitten wird Schritt für Schritt gezeigt, wie sich diese Trennung in einer bestehenden Vaadin-Flow-Anwendung umsetzen lässt.
Trennung von Struktur und Darstellung: Java vs. CSS
Nachdem die Probleme von Inline-Styling in Vaadin Flow deutlich geworden sind, stellt sich die zentrale Frage: Wie lässt sich eine saubere Trennung zwischen der Struktur der Benutzeroberfläche und deren visueller Darstellung herstellen?
In klassischen Webanwendungen ist diese Aufteilung klar definiert. HTML beschreibt die Struktur der Seite, CSS steuert das visuelle Erscheinungsbild, und JavaScript kümmert sich um Interaktion und Logik. In Vaadin Flow verschiebt sich diese Architektur leicht, da die UI-Struktur vollständig in Java definiert wird. Dennoch bleibt die grundlegende Idee bestehen: Struktur und Darstellung sollten voneinander getrennt werden.
Struktur gehört in Java
Java definiert in einer Vaadin-Anwendung die Struktur der Benutzeroberfläche. Dazu gehören insbesondere:
die Zusammensetzung von Komponenten
- Layoutstrukturen
- Navigation und Routing
- Event-Handling
- Datenbindung
Ein typisches Beispiel ist der Aufbau eines Layouts:
VerticalLayout container = new VerticalLayout();
container.add(new H2("Create new short links"), form, actions);
Hier beschreibt der Code ausschließlich die Struktur der Oberfläche: welche Komponenten vorhanden sind und wie sie angeordnet werden.
Darstellung gehört in CSS
Die visuelle Darstellung der Komponenten sollte dagegen über CSS definiert werden. Dazu gehören unter anderem:
- Abstände und Padding
- Farben und Hintergründe
- Schatten und Rahmen
- Typografie
- responsive Layout-Anpassungen
Anstatt beispielsweise direkt im Java-Code ein Padding zu setzen
component.getStyle().set(“padding”, “var(–lumo-space-m)”);
wird eine CSS-Klasse verwendet:
component.addClassName(“card”);
Die eigentliche visuelle Definition befindet sich dann im Stylesheet:
.card {
padding: var(--lumo-space-m);
border-radius: var(--lumo-border-radius-l);
}
Diese Aufteilung sorgt dafür, dass Layoutentscheidungen zentral verwaltet werden können und nicht mehr über mehrere Views verteilt sind.
Vorteile dieser Trennung
Die konsequente Trennung zwischen Java-Struktur und CSS-Darstellung bringt mehrere Vorteile mit sich.
Erstens wird der Java-Code deutlich lesbarer. Views konzentrieren sich auf die Komposition der UI-Komponenten, ohne durch Stylingdetails überladen zu werden.
Zweitens lassen sich Styles zentral verwalten und wiederverwenden. Eine einmal definierte CSS-Klasse kann in verschiedenen Views eingesetzt werden, ohne dass Layoutregeln mehrfach im Code auftauchen.
Drittens wird die Wartbarkeit der Anwendung verbessert. Änderungen am Design erfordern keine Anpassungen in zahlreichen Java-Klassen, sondern können zentral im Stylesheet erfolgen.
Gerade in größeren Vaadin-Projekten mit mehreren Entwicklern zeigt sich schnell, wie wichtig diese klare Verantwortungsaufteilung ist.
Im nächsten Abschnitt wird anhand konkreter Beispiele aus der Anwendung gezeigt, wie bestehende Inline-Styles Schritt für Schritt durch CSS-Klassen ersetzt werden können.
Inline-Styles durch CSS-Klassen ersetzen
Nachdem die grundlegende Trennung zwischen Struktur (Java) und Darstellung (CSS) definiert wurde, stellt sich in bestehenden Vaadin-Anwendungen eine praktische Frage: Wie lässt sich eine vorhandene Codebasis schrittweise von Inline-Styling auf CSS-Klassen umstellen?
Die Umstellung erfolgt in der Praxis meist inkrementell. Statt die gesamte Anwendung auf einmal zu refaktorieren, werden zunächst einzelne Views oder Komponenten bereinigt. Dabei werden direkte Style-Definitionen im Java-Code entfernt und durch CSS-Klassen ersetzt.
Ein typisches Beispiel
Ein häufiges Muster in Vaadin-Views besteht darin, Layoutverhalten direkt über Inline-Styles zu steuern. Ein Beispiel aus der Anwendung ist das Verschieben einer Komponente an das rechte Ende eines Layouts.
Vor der Refaktorierung sah der Code beispielsweise so aus:
storeIndicator.getStyle().set(“margin-left”, “auto”);
Der Code erfüllt seinen Zweck: Die Komponente wird nach rechts verschoben. Das Problem liegt jedoch darin, dass diese Layoutregel nun fest im Java-Code verankert ist.
Schritt 1: Einführung einer CSS-Klasse
Statt die Style-Eigenschaft direkt zu setzen, wird zunächst eine passende CSS-Klasse definiert. Diese befindet sich typischerweise in einer globalen Stylesheet-Datei der Anwendung.
.mainlayout-right {
margin-left: auto;
}
Der Vorteil dieser Lösung liegt darin, dass die Layoutregel nun zentral definiert ist und von mehreren Komponenten wiederverwendet werden kann.
Schritt 2: Verwendung der Klasse im Java-Code
Im nächsten Schritt wird der Inline-Style im Java-Code entfernt und durch die CSS-Klasse ersetzt.
storeIndicator.addClassName(“mainlayout-right”);
Damit bleibt der Java-Code ausschließlich für die Struktur der UI verantwortlich. Die visuelle Ausrichtung der Komponente wird vollständig über CSS gesteuert.
Ein weiteres Beispiel aus einer View
Auch größere Layoutdefinitionen lassen sich auf diese Weise bereinigen. In vielen Vaadin-Views finden sich beispielsweise Konstrukte wie:
container.getStyle()
.set("border-radius", "var(--lumo-border-radius-l)")
.set("gap", "var(--lumo-space-l)");
Diese Styledefinitionen können in eine CSS-Klasse überführt werden:
.card-container {
border-radius: var(--lumo-border-radius-l);
gap: var(--lumo-space-l);
}
Im Java-Code reduziert sich die Definition anschließend auf:
container.addClassName(“card-container”);
Vorteile dieses Ansatzes
Durch diese Refaktorierung entstehen mehrere Verbesserungen.
Erstens wird der Java-Code deutlich kompakter und besser lesbar. Layoutdetails verschwinden aus den View-Klassen.
Zweitens lassen sich Styles zentral verwalten. Änderungen an einem Layout müssen nur noch an einer Stelle im Stylesheet vorgenommen werden.
Drittens entsteht eine konsistente visuelle Sprache innerhalb der Anwendung, da wiederverwendbare CSS-Klassen genutzt werden.
Die Migration von Inline-Styles zu CSS-Klassen ist daher ein zentraler Schritt, um Vaadin-Anwendungen langfristig wartbar zu halten.
Im nächsten Kapitel wird gezeigt, wo CSS-Dateien in einer Vaadin-Flow-Anwendung abgelegt werden und wie sie korrekt in die Anwendung eingebunden werden.
Struktur der CSS-Dateien in einer Vaadin-Flow-Anwendung
Nachdem Inline-Styles aus dem Java-Code entfernt und durch CSS-Klassen ersetzt wurden, stellt sich die nächste wichtige Frage: Wo sollten diese CSS-Definitionen in einer Vaadin-Flow-Anwendung abgelegt werden?
Vaadin Flow basiert intern auf Web Components und verwendet das Frontend-Verzeichnis der Anwendung, um statische Ressourcen wie Stylesheets, JavaScript oder Bilder bereitzustellen. Für CSS ergibt sich daraus eine klare Struktur, die sich in der Praxis bewährt hat.
Das frontend-Verzeichnis
In einer typischen Vaadin-Anwendung befindet sich ein Verzeichnis mit dem Namen frontend. Dieses enthält alle Ressourcen, die vom Browser direkt geladen werden.
Eine häufig verwendete Struktur sieht beispielsweise so aus:
frontend/
styles/
main.css
layout.css
components.css
Innerhalb dieses Ordners können die Styles logisch nach Verantwortungsbereichen organisiert werden.
- main.css enthält grundlegende Styles der Anwendung
- layout.css definiert Layoutregeln
- components.css enthält wiederverwendbare Komponentenstyles
Diese Aufteilung verhindert, dass alle Styles in einer einzigen Datei landen und erleichtert die langfristige Wartung.
Einbindung der Styles in Vaadin
Damit die CSS-Dateien in der Anwendung wirksam werden, müssen sie von Vaadin geladen werden. Dies geschieht typischerweise über Annotationen wie @CssImport.
Ein Beispiel in einer zentralen Layoutklasse könnte so aussehen:
@CssImport("./styles/main.css")
public class MainLayout extends AppLayout {
...
}
Sobald diese Annotation vorhanden ist, werden die darin definierten Styles in der gesamten Anwendung verfügbar.
Alternativ kann ein globales Theme verwendet werden, bei dem die Styles automatisch geladen werden. In diesem Fall liegen die CSS-Dateien beispielsweise im Verzeichnis:
frontend/themes/<theme-name>/
Gerade in größeren Anwendungen empfiehlt sich dieser Ansatz, da das Theme als zentrale Stelle für alle Designentscheidungen dient.
Trennung von Layout- und Komponentenstyles
Eine weitere bewährte Praxis besteht darin, zwischen Layout-Styles und Komponenten-Styles zu unterscheiden.
Layout-Styles beschreiben beispielsweise:
- Container-Abstände
- Grid- oder Flex-Layouts
- responsive Verhalten
Komponenten-Styles hingegen definieren das visuelle Erscheinungsbild wiederverwendbarer UI-Elemente wie Karten, Badges oder Toolbars.
Diese Trennung verhindert, dass Layoutregeln und visuelle Komponentenlogik vermischt werden.
Konsistente Benennung von CSS-Klassen
Damit CSS-Klassen langfristig verständlich bleiben, sollte eine konsistente Namenskonvention verwendet werden.
Ein mögliches Muster orientiert sich an der jeweiligen View oder Komponente:
.about-card
.about-hero
.mainlayout-right
.searchbar-container
Dadurch wird sofort erkennbar, zu welchem Bereich der Anwendung ein bestimmter Style gehört.
Eine klar strukturierte CSS-Organisation ist die Grundlage dafür, dass die zuvor eingeführte Trennung zwischen Java und CSS dauerhaft funktioniert.
Während Java weiterhin die Struktur und das Verhalten der Benutzeroberfläche definiert, wird das visuelle Erscheinungsbild der Anwendung zentral über Stylesheets gesteuert. Dies reduziert Redundanzen, erleichtert Designänderungen und sorgt für eine konsistente Benutzeroberfläche über alle Views hinweg.
Im nächsten Kapitel wird gezeigt, wie konkrete Refaktorierungen aus der Anwendung umgesetzt wurden und welche Patterns sich dabei als besonders hilfreich erwiesen haben.
Refactoring realer Views: Beispiele aus dem URL-Shortener
Die bisher beschriebenen Prinzipien – Trennung von Struktur und Darstellung sowie der Ersatz von Inline-Styles durch CSS-Klassen – lassen sich am besten anhand konkreter Beispiele nachvollziehen. Im Open‑Source‑Projekt URL‑Shortener wurden mehrere Views schrittweise refaktoriert, um genau diese Trennung umzusetzen.
Dieses Kapitel zeigt exemplarisch, wie bestehender Vaadin‑Code angepasst wurde und welche Muster sich dabei als besonders praktikabel erwiesen haben.
Beispiel 1: MainLayout
Im MainLayout wurde ursprünglich ein Inline‑Style verwendet, um ein Element innerhalb eines Layouts nach rechts zu verschieben.
Vor der Refaktorierung sah der Code so aus:
storeIndicator.getStyle().set(“margin-left”, “auto”);
Diese Lösung funktioniert technisch einwandfrei, führt jedoch dazu, dass Layoutregeln direkt im Java‑Code definiert werden.
Nach der Refaktorierung wurde stattdessen eine CSS‑Klasse eingeführt.
Java:
storeIndicator.addClassName(“layout-spacer-right”);
CSS:
.layout-spacer-right {
margin-left: auto;
}
Die Layoutregel befindet sich nun ausschließlich im Stylesheet, während der Java‑Code nur noch die strukturelle Information enthält, dass diese Komponente eine bestimmte Layoutrolle einnimmt.
Beispiel 2: Kartenlayout in der AboutView
Die AboutView verwendet mehrere Container, die visuell als Karten dargestellt werden. Ursprünglich wurden diese Layoutregeln direkt über Style‑Aufrufe definiert.
Typischer Inline‑Code sah etwa so aus:
card.getStyle()
.set("background", "var(--lumo-base-color)")
.set("border-radius", "var(--lumo-border-radius-l)")
.set("box-shadow", "var(--lumo-box-shadow-s)");
Diese Styles wurden anschließend in eine wiederverwendbare CSS‑Klasse überführt.
CSS:
.card {
background: var(--lumo-base-color);
border-radius: var(--lumo-border-radius-l);
box-shadow: var(--lumo-box-shadow-s);
padding: var(--lumo-space-l);
}
Java:
card.addClassName(“card”);
Der Vorteil besteht darin, dass alle Karten der Anwendung nun ein konsistentes Erscheinungsbild besitzen und Änderungen zentral vorgenommen werden können.
Beispiel 3: Strukturierte Layoutklassen
Ein weiteres Muster besteht darin, Layoutrollen explizit über CSS‑Klassen zu benennen. Statt generischer Styles werden semantische Klassen eingeführt, die den Zweck eines Elements beschreiben.
Beispiele hierfür sind:
.searchbar-container
.bulk-actions-bar
.overview-grid
Solche Klassen helfen dabei, das Layout der Anwendung auch im CSS leichter nachvollziehen zu können.
Refactoring als inkrementeller Prozess
Wichtig ist, dass diese Umstellung nicht zwingend in einem einzigen Schritt erfolgen muss. In der Praxis hat sich ein inkrementeller Ansatz bewährt.
Neue Komponenten werden direkt mit CSS‑Klassen entwickelt
Bestehende Inline‑Styles werden bei Gelegenheit refaktoriert
wiederkehrende Style‑Muster werden schrittweise zentralisiert
Auf diese Weise kann eine bestehende Vaadin‑Anwendung ohne größere Risiken in eine sauber strukturierte CSS‑Architektur überführt werden.
Die Beispiele aus dem URL‑Shortener zeigen, dass selbst kleine Refactorings einen großen Einfluss auf die Wartbarkeit einer Anwendung haben können. Durch das Entfernen von Inline‑Styles wird der Java‑Code klarer, während das visuelle Design zentral im Stylesheet gepflegt werden kann.
Im nächsten Kapitel wird gezeigt, welche allgemeinen Best Practices sich aus dieser Refaktorierung ableiten lassen und wie sie in zukünftigen Vaadin‑Projekten angewendet werden können.
Best Practices für CSS in Vaadin-Flow-Anwendungen
Nachdem die Refaktorierung der bestehenden Views abgeschlossen ist, stellt sich die Frage, welche allgemeinen Regeln sich daraus ableiten lassen. In der Praxis hat sich gezeigt, dass einige einfache Prinzipien bereits ausreichen, um Vaadin-Flow-Anwendungen langfristig wartbar und konsistent zu halten.
Dieses Kapitel fasst die wichtigsten Best Practices zusammen, die sich während der Umstellung des URL-Shortener-Projekts bewährt haben.
Java beschreibt Struktur – CSS beschreibt Darstellung
Die wichtigste Regel ist zugleich die einfachste: Java definiert die Struktur der Benutzeroberfläche, CSS deren visuelle Gestaltung.
In Vaadin wird die gesamte UI-Komposition in Java modelliert. Layoutcontainer, Komponenten und deren Hierarchie gehören daher eindeutig in den Java-Code.
Beispiele für strukturelle Definitionen in Java sind:
- Layoutcontainer (VerticalLayout, HorizontalLayout, FormLayout)
- Komponentenstruktur
- Event-Handling
- Datenbindung
Visuelle Aspekte sollten dagegen über CSS geregelt werden. Dazu gehören insbesondere:
- Abstände
- Farben
- Schatten
- Typografie
- visuelle Hervorhebungen
Diese klare Trennung verhindert, dass UI-Logik und Präsentationsdetails im selben Code vermischt werden.
CSS-Klassen statt Inline-Styles
Inline-Styles sollten nur in Ausnahmefällen verwendet werden. Stattdessen empfiehlt es sich, konsistente CSS-Klassen zu definieren und diese über addClassName() an Komponenten zu binden.
Beispiel:
component.addClassName(“card”);
Die visuelle Definition erfolgt anschließend im Stylesheet:
.card {
padding: var(--lumo-space-m);
border-radius: var(--lumo-border-radius-l);
}
Dieser Ansatz sorgt dafür, dass Layoutregeln zentral gepflegt werden können.
Nutzung der Lumo-Designvariablen
Vaadin verwendet mit Lumo ein konsistentes Designsystem, das zahlreiche CSS-Variablen bereitstellt.
Typische Beispiele sind:
–lumo-space-m
–lumo-border-radius-l
–lumo-box-shadow-s
–lumo-primary-color
Diese Variablen sollten bevorzugt verwendet werden, da sie automatisch mit dem gewählten Theme harmonieren und konsistente Abstände und Farben sicherstellen.
Ein Beispiel:
.card {
padding: var(--lumo-space-l);
border-radius: var(--lumo-border-radius-l);
}
Semantische Klassennamen
CSS-Klassen sollten nicht nur beschreiben wie etwas aussieht, sondern welche Rolle ein Element im Layout spielt.
Weniger hilfreich wären beispielsweise Namen wie:
.box1
.red-border
.container-large
Besser sind semantische Bezeichnungen, die sich an Views oder Komponenten orientieren:
.about-card
.searchbar-container
.bulk-actions-bar
.overview-grid
Dadurch bleibt auch in größeren Stylesheets nachvollziehbar, zu welchem Bereich der Anwendung ein Style gehört.
Responsive Layouts bewusst einsetzen
Vaadin stellt mit Komponenten wie FormLayout, FlexLayout oder SplitLayout bereits viele Mechanismen für responsive Layouts bereit.
Beispielsweise lassen sich FormLayouts direkt über Java konfigurieren:
form.setResponsiveSteps(
new FormLayout.ResponsiveStep("0", 1),
new FormLayout.ResponsiveStep("900px", 2)
);
Diese strukturellen Layoutentscheidungen gehören bewusst in den Java-Code, da sie Teil der UI-Komposition sind. CSS ergänzt anschließend nur das visuelle Verhalten.
Inline-Styles als bewusst eingesetzte Ausnahme
Trotz aller Empfehlungen gibt es Situationen, in denen Inline-Styles sinnvoll sein können.
Typische Beispiele sind:
- dynamisch berechnete Layoutwerte
- kurzfristige UI-Anpassungen
- experimentelle Prototypen
Wichtig ist jedoch, dass diese Fälle die Ausnahme bleiben und nicht zum Standardstil einer Anwendung werden.
Die Kombination aus klarer Verantwortungsaufteilung, wiederverwendbaren CSS-Klassen und konsistenten Designvariablen führt zu einer deutlich wartbareren Vaadin-Anwendung.
Besonders in Projekten, die über längere Zeit weiterentwickelt werden, zahlt sich diese Struktur schnell aus. Änderungen am visuellen Design lassen sich zentral umsetzen, während der Java-Code weiterhin ausschließlich die Struktur und das Verhalten der Benutzeroberfläche beschreibt.
Fazit der Refaktorierung
Die Umstellung von Inline-Styling auf eine klar strukturierte CSS-Architektur mag auf den ersten Blick wie eine kleine kosmetische Änderung erscheinen. In der Praxis zeigt sich jedoch schnell, dass diese Refaktorierung tiefgreifende Auswirkungen auf die Wartbarkeit und Verständlichkeit einer Vaadin-Flow-Anwendung hat.
Im ursprünglichen Zustand der Anwendung waren viele Layout- und Darstellungsdetails direkt im Java-Code der Views verankert. Methodenaufrufe wie getStyle().set(…) sorgten zwar kurzfristig für schnelle UI-Anpassungen, führten langfristig jedoch zu einer Vermischung von Struktur und Präsentation. Das Ergebnis war eine Codebasis, in der Designentscheidungen über zahlreiche Klassen verteilt waren.
Durch die Einführung von CSS-Klassen und die konsequente Auslagerung visueller Eigenschaften in Stylesheets wurde diese Vermischung wieder aufgelöst. Java beschreibt nun ausschließlich die Struktur der Benutzeroberfläche: Komponenten, Layoutcontainer, Navigation und Interaktionen. Die visuelle Gestaltung hingegen wird zentral über CSS definiert.
Diese Trennung bringt mehrere unmittelbare Vorteile mit sich.
Erstens verbessert sich die Lesbarkeit des Java-Codes erheblich. Views konzentrieren sich auf die Komposition der Benutzeroberfläche, ohne durch Layoutdetails überladen zu sein. Entwickler können schneller nachvollziehen, welche Struktur eine View besitzt und welche Komponenten miteinander interagieren.
Zweitens wird das Design der Anwendung konsistenter. Wiederverwendbare CSS-Klassen stellen sicher, dass ähnliche Komponenten in verschiedenen Views auch visuell gleich gestaltet sind. Änderungen am Erscheinungsbild lassen sich zentral im Stylesheet durchführen, ohne zahlreiche Java-Klassen anpassen zu müssen.
Drittens erleichtert diese Struktur die Zusammenarbeit im Team. Entwickler können sich auf die Java-Seite der Anwendung konzentrieren, während Designanpassungen unabhängig davon im CSS erfolgen können. Gerade in größeren Projekten reduziert dies Konflikte und vereinfacht die Weiterentwicklung der UI.
Die Refaktorierung des URL-Shortener-Projekts hat gezeigt, dass selbst relativ kleine Änderungen an der Struktur der Styles einen großen Einfluss auf die langfristige Wartbarkeit haben können. Besonders bei Anwendungen, die über Jahre hinweg weiterentwickelt werden, zahlt sich eine klare Trennung zwischen Struktur und Darstellung schnell aus.
Vaadin Flow bleibt weiterhin ein serverseitiges UI-Framework, das Java in den Mittelpunkt der UI-Entwicklung stellt. Dennoch profitiert auch eine solche Architektur erheblich von den klassischen Prinzipien der Webentwicklung: Struktur, Darstellung und Verhalten sollten klar voneinander getrennt sein.
Wer diese Grundregel konsequent anwendet, erhält eine Vaadin-Anwendung, die nicht nur funktional stabil ist, sondern auch langfristig verständlich und wartbar bleibt.