Formulare/Gestaltung mit CSS
Für die bedienungsfreundliche Nutzbarkeit von Webseiten spielt ein gutes UI-Design eine große Rolle. Nur wenn interaktive Elemente schnell und intuitiv erkannt und bedient werden können, werden die Nutzer deiner Webseite die vorhandenen Angebote nutzen.
In diesem Kapitel lernst du, wie man Call-To-Action-Buttons mit den passenden HTML-Elementen erzeugt und mit CSS an verschiedene Viewports und das Look and Feel der Webseite anpasst.
Dabei wollen wir unser CSS aber so organisieren, dass künftige Änderungen mit nur wenigen Stellschrauben vorgenommen werden können.
Dabei wird das Single Point of Truth-Prinzip vorgestellt. Der Artikel basiert auf einer Idee von Lea Verou aus ihrem Buch CSS-Secrets.[1]
Inhaltsverzeichnis
Vorüberlegungen
Im Forum gibt es immer wieder Fragen, wie man Buttons „unauffälliger gestalten könne“.[2], was Gunnar Bittersmann zu folgendem Beispiel motivierte:
<p>Vielleicht nicht die beste Idee, einen <button class="seamless">Button</button> nicht aussehen zu lassen wie einen <button>Button</button>.
</p>
Buttons und andere Eingabeelemente sollten immer sowohl mit Maus als auch Tastatur ansteuer- und bedienbar sein!
Magic Numbers
Code so übersichtlich zu gestalten, dass er später leicht les- und änderbar ist, ist eine der größten Herausforderungen im Webdesign. Eigentlich ist CSS gut lesbar – trotzdem kann das bedenkenlose Hinzufügen weiterer Eigenschaften schnell zu unübersichtlichem Code führen:
button {
padding: 6px 16px;
border: 1px solid red;
background: #5a9900 linear-gradient(#8db243, red);
border-radius: 0 8px 8px;
box-shadow: 0 lpx 5px gray;
color: white;
text-shadow: 0 -1px 1px #333;
font-size: 20px;
line-height: 30px;
}
Der Button enthält CSS-Festlegungen mit festen Pixelwerten. Wenn man nur einen Wert ändert, kann das Layout „zerschossen“ werden, indem Texte nicht mehr in fest angelegte Boxen passen. Solche festen Zahlenwerte (hard coded values), die nur in einem bestimmten Kontext das Gewünschte erreichenn nennt man Magic Numbers. Ihr Einsatz sollte vermieden werden.
In CSS führen doppelte oder verstreute Stildefinitionen schnell zu unübersichtlichem und schwer wartbarem Code. Wenn dieselben Farben, Abstände oder Schriftgrößen an vielen Stellen wiederholt werden, muss man bei jeder Designänderung alles manuell anpassen – das ist fehleranfällig und kostet Zeit.
Wartungsfreundliches CSS
Einer der wichtigsten Grundsätze, um Code wartungsfreundlich zu gestalten, ist DRY ("Don't repeat yourself!"). So ist es sinnvoll, dass CSS-Regelsätze zentral oder wiederverwendbar definiert werden. So bleibt der Code schlanker und Änderungen können leichter durchgeführt werden.
Dieses Kapitel soll zeigen, wie du mit der Verwendung des relativen Längenmaßes em gegenüber einem Einsatz von festen Pixelwerten flexible und später einfach zu ändernde Layouts erreichst. So kann die Anzahl der Stellschrauben bei späteren Änderungen weiter reduziert werden.
Bezug auf die Schriftgröße
Einige CSS-Werte stehen nicht für sich alleine, sondern beziehen sich auf andere, vorher getroffene Festlegungen. So ist der Zeilenabstand direkt von der Schriftgröße abhängig. Wenn die Bedeutung des Buttons hervorgehoben werden soll, kann er etwas größer dargestellt werden. Im oberen Beispiel müssen dafür sowohl die CSS-Eigenschaften font-size als auch line-height angepasst werden, hier werden beide nun miteinander verknüpft:
button {
font-size: 20px;
line-height: 1.5;
}
Die Zeilenhöhe passt sich nun automatisch an eine Anpassung der Schriftgröße an. Ein Wert von 150% (kurz: 1.5) lässt genug Platz nach oben und unten.
Bei einer etwaigen Änderung der Schriftgröße der Elternelemente, bzw. des gesamten Dokuments muss hier der Wert für die Schriftgröße des Buttons entsprechend angepasst werden. Besser ist es, relative Längenmaße auch für die Schriftgröße zu verwenden:
button {
font-size: 125%;
line-height: 1.5;
}
Die Schriftgröße des Buttons wird nun auf 125% des vererbten Werts festgelegt. (Der Wert von 125% entsteht aufgrund der Beobachtung, dass die voreingestellte Schriftgröße in den meisten Browsern 16px beträgt.)
em oder rem fest.Eine Standardschriftgröße sollte, wenn überhaupt, nur zentral für das html oder body-Element festgelegt werden.
skalierbare Werte für Ränder und Schatten
Wenn die Schriftgröße nun geändert wird, vergrößert sich der Button. Gleichzeitig bleiben die auf die originale Größe abgestimmten Effekte unverändert, sodass die Proportionen nicht mehr stimmen und der Button „komisch“ aussieht.
Abhilfe schafft eine Verknüpfung der Ränder und Schatten mit der Schriftgröße:
.btn-em {
padding: 0.9em 1.4em;
background: oklch(0.70 0.10 120);
color: black;
border-radius: 0.4em;
border: none;
cursor: pointer;
font-size: var(--base-font);
box-shadow: 0 .2em .4em gray;
color: white;
text-shadow: 0 -.05em .05em #333;
}
In diesem Beispiel wurden alle Werte bis auf die Dicke des Rands in em notiert.
Bei einer späteren Änderung der Schriftgröße skalieren die Werte für (Innen)-Abstände, Ränder und Schatten einfach mit. Dadurch bleiben die Proportionen erhalten.
Gleichzeitig entsteht so ein Single Point of Truth: Die Schriftgröße wirkt als zentrale Bezugsgröße, von der sich alle weiteren Maße ableiten. Ändert man diesen einen Wert, passt sich das gesamte Erscheinungsbild konsistent an — ohne dass man jede einzelne Eigenschaft manuell nachjustieren muss.
Information: Single Point of Truth
Das Single Point of Truth (SPOT)[3] sorgt dafür, dass jede wichtige Design-Information – etwa Farben, Schriftarten oder Spacing-Werte – nur an einer Stelle definiert ist. Dadurch ist sichergestellt, dass das gesamte Stylesheet immer konsistent bleibt und Änderungen sofort überall greifen.Gemeinsam sorgen diese Prinzipien dafür, dass CSS übersichtlicher, konsistenter und langfristig wartbarer wird – ein großer Vorteil, besonders in größeren Projekten oder bei der Zusammenarbeit im Team.
Vermeide Magic Numbers!
Verwende Variablen als einzigen Single Point of Truth (SPOT).
So kannst du Eigenschaften zentral an einer Stelle ändern, vermeidest Fehler und verlierst nicht die Übersicht!
Perfekte Kreise
Im Tutorial zu Bildergalerien gibt es viele Regelsätze, in denen Buttons und Marker kreisförmig formatiert werden sollen.
@supports selector(::scroll-marker) {
::scroll-button(*) {
font-size: 1.5em;
width: 1.5em;
aspect-ratio: 1;
border-radius: 50%;
}
Der Scroll-Button erhält eine Breite von 1.5em - eigentlich sollte jetzt eine identische Höhenangabe folgen. Das Seitenverhältnis legen wir aber mit aspect-ratio: 1; so fest, dass wir bei späteren Änderungen nur die Breite ändern müssen.
Die Abrundung wird mit border-radius erzielt. Der Wert 50% ist ebenfalls unabhängig von festen Größen - anders als ein Wert von z. B. 1em, der bei einer Größe von 4em nur für abgrundete Ecken, aber nicht für einen Kreis sorgen würde.
Farbgestaltung
Neben der Skalierbarkeit der Abmessungen sollte auch Augenmerk auf die Farbgestaltung gelegt werden. Häufig gibt es mehrere Buttons mit unterschiedlichen Funktionen auf der Webseite.
Im derzeitigen Zustand müssen die vier Deklarationen für border-color, background, box-shadow und text-shadow geändert werden. Dabei bleibt der Arbeitsaufwand für ein Berechnen der Farbwerte der einzelnen Schattierungen und Farbtöne noch unberücksichtigt. Der verwendete graue Schatten funktioniert nur bei einem weißen Hintergrund, auf einem farbigen Hintergrund wäre er wirkungslos.
Diese Mühe kann man sich durch die Verwendung von costum properties und Relativen Farbangaben sparen:
:root {
--primary: oklch(0.96 0.03 78);
--primary-dark: oklch(0.55 0.13 48); /* SELF-Braun */
--secondary: oklch(0.70 0.10 120);
--radius: .4em;
--spacing: 1rem;
}
.btn {
color: white;
background: var(--hue);
border: thin solid var(--hue);
--shadow-strength: 20%;
box-shadow: 0 .15rem .35rem
color-mix(in oklch, black var(--shadow-strength), transparent);
}
.btn-primary {
--hue: var(--primary-dark);
}
.btn-secondary {
--hue: var(--secondary);
border-color: oklch(0.4 0.1 120);
}
.btn:hover,
.btn:focus {
background: color-mix(in oklch, white, var(--hue));
color: color-mix(in oklch, black, var(--hue));
--shadow-strength: 35%;
box-shadow: 0 .25rem .5rem
color-mix(in oklch, var(--hue) var(--shadow-strength), transparent);
}
Die Buttons erhalten je nach ihrer Aufgabe eine Klasse, die einen Farbton der custom property --hue zuweist. Mit dieser wird nun gearbeitet:
Alle Buttons erhalten nun über …
- background: var(--hue); einen flächigen Hintergrund im jeweiligen Farbton
-
border: thin solid var(--hue);eine entsprechende Randlinie
und - einen halbschwarzen Schlagschatten
Wird ein Button mit der Maus oder Tatatur ausgewählt, ändert sich
- der Hintergrund:
color-mix(in oklch, white, var(--hue));die color-mix()-Funktion mischt den Farbton mit Weiß - die Textfarbe:
color-mix(in oklch, black, var(--hue));Anstelle der weißen Textfarbe wird nun eine dunklere Variante des Farbtons verwendet. - der Schlagschatten:
- der Wert für
--shadow-strengthwird erhöht; - anstelle Schwarz wird der Farbton für den Schatten verwendet.
- der Wert für
Die Farbgestaltung der Buttons folgt gemeinsamen Prinzipien und wird deshalb nur einmal zentral festgelegt; durch die verschiedenen Farbtöne sehen sie aber unterschiedlich aus!
Anwendungsbeispiele
Bonbon-Buttons
Ursprünglich waren die HTML-Elemente eben little boxes, die flächig gefüllt waren. Mit CSS3 kamen ab 2010 neue Eigenschaften und Designtrends. Candy Buttons (deutsch: Bonbon Buttons) sollten die Benutzeroberfläche der iOS 6-Ära nachahmen: skeuomorph, glänzend, mit zuckergussartigen Oberflächen.[4]
Heute wirken sie nostalgisch, aber es macht immer noch Spaß, damit die Möglichkeiten von CSS zu demonstrieren.
.btn { /* Candy look */
background: linear-gradient(color-mix(in oklch, white, var(--hue)), var(--hue));
border: thin solid var(--hue);
border-radius: var(--radius);
--shadow-strength: 20%;
box-shadow:
0 .15rem .35rem color-mix(in oklch, black var(--shadow-strength), transparent), /* drop shadow */
inset 0 .1em .2em rgb(255 255 255 /0.7), /* glossy edges */
inset 0 -.2em .2em rgb(0 0 0 / 0.2); /* depth */
}
- abgerundete Ecken mit großem Radius
- Verläufe im Hintergrund und
- mehrere, übereinander gelegte Schlagschatten, darunter auch zwei Innenschatten sorgen für einen 3D-Look.
Durch die CSS-Variablen und die relativen Farbangaben kann die Formatierung für alle Buttons zentral erfolgen.
Frosted Glass
Der Frosted-Glass-Look ist durch Apples Betriebssystem populär geworden. Er sieht aus wie milchiges, halbtransparentes Glas, durch das man den Hintergrund noch erkennt – aber unscharf.[5]
.frosted-glass {
font-size: 1.1em;
background: rgb(255 255 255 /0.2);
border: thin solid rgb(255 255 255 /.4);
border-radius: 0 var(--radius) var(--radius);
backdrop-filter: blur(6px);
}
Hauptmerkmale des Glass-Morphism-Look sind der halbtransparente Button, der mit background: rgb(255 255 255 /.2); den Hintergrund der Webseite durchscheinen lässt. Auch die Randlinie ist durchscheinend.
Dieser Hintergrund wird durch backdrop-filter weichgezeichnet.
Gerade bei einen detaillierten Hintergund sieht das gut aus, erschwert aber auch die Lesbarkeit. Deshalb hat Apple in IOS26.1 nachgesteuert und die Lesbarkeit durch höhere Deckkraft verbessert.
Hier noch ein bewegtes Beispiel, um den dynamisch Effekt zu veranschaulichen. Auch wenn Nutzer mit prefers-reduced-motion gefragt werden, ob sie auf eine solche Animation verzichten wollen, ist dies eher ein 'proof of concept'" als ein empfehlenswertes Beispiel für die Praxis.
document.addEventListener("DOMContentLoaded", function () {
const ok = window.matchMedia("(prefers-reduced-motion: no-preference)").matches;
if (!ok) return;
...
function step() {
if (paused || userPaused) return;
window.scrollBy(0, direction * speed);
....
requestAnimationFrame(step);
}
setTimeout(() => requestAnimationFrame(step), pause);
function toggleUserPause() {
userPaused = !userPaused;
if (!userPaused && !paused) {
requestAnimationFrame(step);
}
}
document.addEventListener("mousedown", toggleUserPause);
document.addEventListener("touchstart", toggleUserPause, { passive: true });
});
Ghost-Buttons
Unter Ghost-Buttons versteht man Links oder Buttons, die auf ein Minimum reduziert werden. Sie verzichten auf typische Link-Effekte wie text-decoration, besitzen keine Hintergrundfarbe und haben meist nur einen sehr dünnen Rand. Damit sind sie quasi ein Schatten ihrer selbst – ein Geist.
Beim Berühren oder Drüberfahren mit der Maus, bzw. beim Durchtabben mit der Tastatur ändern sich dann Text- und Hintergrundfarbe.
p.choice {
margin-top: 6em;
}
button {
position: relative;
margin: 2em;
padding: .5em 1em;
width: 8em;
background: transparent;
color: white;
border: thin solid white;
border-radius: .2em;
cursor: pointer;
transition: all ease 2s;
}
button:hover, button:active {
outline: none;
background: white;
color: darkblue;
}
button::before, button::after {
position: absolute;
width: 100%;
height: 150px;
left: 0;
color: white;
}
button::before {
content: " ";
top: -120px;
background: none center no-repeat transparent;
background-size: 30px 30px;
transition: all ease 1s;
transform: rotate(0deg);
}
button:hover::before {
background-size: 80px 80px;
transform: rotate(360deg);
}
button::after {
bottom: -520%;
transition: transform ease-in .5s, opacity ease-out 1s;
}
#win::before {
background-image: url(/images/2/29/Win.png);
}
#and::before {
background-image: url(/images/3/32/And.png);
}
#mac::before {
background-image: url(/images/6/69/Mac.png);
}
#win::after {
content: "7, 9, 10";
transform: translatex(-200%);
opacity: 0;
}
#win:hover::after {
transform: translatex(0);
opacity: 1;
}
#and::after {
content: "4.3, 4.4, 5.0";
transform: translatey(200px);
opacity: 0;
}
#and:hover::after {
transform: translatey(0);
opacity: 1;
}
#mac::after {
content: "iOS 7, iOS 8";
transform: translatex(200%);
opacity: 0;
transition: transform ease-in .5s, opacity ease-out 1s;
}
#mac:hover::after {
transform: translatex(0);
opacity: 1;
}
In diesem Beispiel werden die Buttons nach dem Vorbild sogenannter Ghost-Buttons gestaltet. Hierbei handelt es sich um sehr minimalistisch gehaltene Elemente, die sich gerade deshalb vom Hintergrund abheben.
SPOT vs DRY CSS
In den gezeigten Beispielen wurde demonstriert, wie man wartungsarmes CSS organisiert: Formatierungen werden so gegliedert und notiert, dass sie nicht mit Magic Numbers, sondern mit relativen Werten und CSS-Variablen funktionieren. So kann man mit einem Handgriff Farbe und Schriftgrößen an einer Stelle ändern und so die gesamte Seite anpassen.
Dies folgt dem Prinzip des DRY (Don't repeat yourself!). Wie bei jedem Prinzip gibt es Anwender, die ein Prinzip auf die Spitze treiben. Abgerundete Ecken gibt es nicht nur bei Buttons, sondern auch bei anderen Elementen. Könnte man das nicht zentral festlegen und den betroffenen Elementen eine Klasse zuweisen?
In der Idealform besteht dann jeder CSS-Regelsatz nur aus einer Zuweisung. Dafür muss dann aber das HTML zahllose Klassen aufnehmen.
Weniger ist mehr!
Frameworks wie Tailwind, die ein solches Atomic CSS propagieren, waren vor ein paar Jahren voll im Trend, mittlerweile findet man aber einen gesunden Mittelweg.
Siehe auch
- Guter CSS-Stil

(Einstieg in CSS)
- Relative Farbangaben
aus einem Farbwert automatisch weitere Farbtöne erzeugen
Weitere Artikel zum Thema em:
- CSS/Wertetypen/Maßangaben/relative Einheiten (em, rem, ex und ch)
- Vergiss den Begriff Pixel!
Weblinks
- ↑ lea.verou.me: Publications CSS Secrets, O'Reilly Media 2015
- ↑ SELF-Forum: Navigation nachbauen vom 24.02.2019 von Gunnar Bittersmann
- ↑ Single Point of Truth (de.wikipedia.org)
- ↑ 50 CSS3 button examples with effects & animations
- ↑ https://css.glass/
DRY Switching with CSS Variables: The Difference of One Declaration Ana Tudor on Dec 6, 2018 (css-tricks)