Abschnitt 7 · Lektion 3
Rahmen und Radien
Rahmen und Ecken sind das, was aus einer farbigen Fläche eine Komponente macht. Beide sind schnell erklärt und haben je eine Stelle, an der man hängenbleibt.
Ohne Stil kein Rahmen
<div class="kasten ohne-stil">Breite und Farbe, aber kein Stil</div>
<div class="kasten solid">solid</div>
<div class="kasten dashed">dashed</div>
<div class="kasten double">double</div> .kasten {
padding: 16px;
margin-bottom: 12px;
font-family: system-ui, sans-serif;
border-width: 4px;
border-color: #2563eb;
}
/* Hier fehlt border-style. Der Kasten hat deshalb keinen
Rahmen und ist obendrein 8px niedriger als die anderen. */
.ohne-stil {
border-style: none;
}
.solid {
border-style: solid;
}
.dashed {
border-style: dashed;
}
/* double braucht mindestens 3px, sonst sieht man
die beiden Linien nicht getrennt. */
.double {
border-style: double;
} border ist ein Shorthand aus Breite, Stil und Farbe. border: 1px solid #d4d4d8 setzt alle drei auf einmal.
Der Standardwert von border-style ist none. Ohne Stil ist der Rahmen unsichtbar, egal wie richtig Breite und Farbe sind. Er ist dann auch gar nicht da, denn none bedeutet null Pixel Breite. Der erste Kasten im Beispiel ist deshalb acht Pixel niedriger als seine Nachbarn, oben und unten fehlen ihm je vier.
Im Inspector siehst du das. Am ersten Kasten steht border: 0px none rgb(37, 99, 235). Die Farbe ist angekommen, aber der Stil fehlt. Aus den vier Pixeln Breite im Stylesheet sind null geworden. Bei der Breite, mit der die Spalte startet, misst er 364 × 51 und seine Nachbarn 364 × 59. Die acht Pixel Unterschied sind der Rahmen, den es nicht gibt.
In der Breite sieht man nichts. Ein Block ohne eigene width füllt die Zeile ohnehin aus, und der Rahmen geht dort vom Inhalt ab, statt zur Außenbreite dazuzukommen.
Die Stile heißen solid, dashed, dotted, double, groove, ridge, inset und outset. Die letzten vier stammen aus den Neunzigern und sehen auch so aus. In der Praxis brauche ich solid, gelegentlich dashed.
Jede Seite geht auch einzeln, entweder als border-top oder feiner als border-top-width, border-top-style, border-top-color. Eine einzelne Linie unter einer Überschrift ist border-bottom: 2px solid und kein Rahmen, bei dem drei Seiten wieder abgeschaltet werden.
border-color steht standardmäßig auf currentColor. Deshalb funktioniert border: 1px solid auch ganz ohne Farbangabe. Der Rahmen nimmt dann einfach die Textfarbe, so wie in Lektion 5.2.
Ecken runden
<div class="form radius">12px</div>
<div class="form kreis"></div>
<div class="form ellipse">40px / 20px</div>
<div class="form pille">Pille</div>
<div class="aussen falsch">
<div class="innen">gleicher Radius innen, sieht falsch aus</div>
</div>
<div class="aussen richtig">
<div class="innen klein">kleinerer Radius innen</div>
</div> .form {
width: 160px;
height: 80px;
margin-bottom: 12px;
padding: 8px;
color: #ffffff;
font-family: system-ui, sans-serif;
background-color: #2563eb;
}
.radius {
border-radius: 12px;
}
/* 50% auf einem quadratischen Kasten ergibt einen Kreis,
auf einem breiten Kasten eine Ellipse. */
.kreis {
width: 80px;
border-radius: 50%;
}
/* Vor dem Schrägstrich die waagerechten Radien,
dahinter die senkrechten. */
.ellipse {
border-radius: 40px / 20px;
}
/* Größer als die halbe Höhe geht nicht, deshalb reicht
eine beliebig große Zahl für die Halbkreise. */
.pille {
border-radius: 999px;
}
.aussen {
padding: 8px;
margin-bottom: 12px;
background-color: #18181b;
border-radius: 16px;
}
.innen {
padding: 16px;
color: #18181b;
font-family: system-ui, sans-serif;
background-color: #fafafa;
border-radius: 16px;
}
.klein {
border-radius: 8px;
} border-radius nimmt einen bis vier Werte, im Uhrzeigersinn ab links oben. Eine Zahl rundet alle vier Ecken.
Prozentwerte beziehen sich auf die Größe des Elements. 50% ergibt auf einem quadratischen Kasten einen Kreis und auf einem breiten eine Ellipse. Für die Pille reicht eine beliebig große Zahl. Mehr als die halbe Höhe kann ein Radius nicht werden, der Browser deckelt ihn.
Der Schrägstrich trennt waagerechte von senkrechten Radien. border-radius: 40px / 20px ergibt flache, weit gezogene Ecken.
Interessant ist der Fall am Ende des Beispiels. Ein verschachtelter Kasten braucht einen kleineren Radius als sein Elternteil. Beide Kästen haben außen 16 Pixel Radius, und der innere sieht trotzdem falsch aus, denn zwischen den beiden Kanten liegt der Innenabstand. Ich rechne den inneren Radius deshalb als äußeren Radius minus Innenabstand. Im Beispiel sind das 16 minus 8.
Die Kontur liegt daneben
<div class="reihe">
<div class="feld"></div>
<div class="feld mit-border">border</div>
<div class="feld mit-outline">outline</div>
</div>
<p>Tab dich in die beiden Buttons, dann siehst du den Unterschied im Ring.</p>
<button type="button" class="eng">ohne Abstand</button>
<button type="button" class="luftig">mit outline-offset</button> .reihe {
font-family: system-ui, sans-serif;
margin-bottom: 16px;
}
.feld {
display: inline-block;
width: 100px;
height: 60px;
background-color: #e4e4e7;
}
/* Der Rahmen kommt zur Größe dazu und schiebt die Nachbarn. */
.mit-border {
border: 6px solid #2563eb;
}
/* Die Kontur liegt außerhalb des Layouts. Nichts rückt. */
.mit-outline {
outline: 6px solid #b91c1c;
}
button {
font: inherit;
padding: 8px 16px;
margin-right: 8px;
border: 1px solid #d4d4d8;
border-radius: 8px;
background-color: #fafafa;
}
/* outline-offset darf am Element stehen. Der Ring
erscheint trotzdem erst beim Fokus. */
.luftig {
outline-offset: 4px;
} outline sieht aus wie ein zweiter Rahmen und verhält sich völlig anders. Es liegt außerhalb des Layouts. Ein Element mit Kontur wird nicht größer, seine Nachbarn rücken nicht, nichts bricht um. Deshalb kann der Browser damit den Fokusring zeichnen, ohne dass die Seite beim Tabben springt.
Im Inspector misst der nackte Kasten 100 × 60, der mit dem sechs Pixel dicken Rahmen 112 × 72. Der mit der gleich dicken Kontur hat wieder 100 × 60. Der Rahmen macht das Element größer, die Kontur nicht.
outline-offset schiebt die Kontur vom Element weg. Ein bis vier Pixel reichen und machen den Ring deutlich sichtbarer, gerade auf Buttons mit eigenem Rahmen. Die Angabe darf am Element selbst stehen, auch wenn dort noch gar kein Ring ist. Sie wirkt, sobald einer gezeichnet wird.
Die Kontur folgt außerdem von selbst der Rundung des Elements. Das können alle großen Browser erst seit 2023, Safari als letzter mit Version 16.4. In älteren Artikeln stehen deshalb noch Umwege dafür.
Warum outline: none teuer ist
Bleibt outline: none. Das steht in vielen Stylesheets, meistens weil jemand den Ring hässlich fand.
Damit ist die Seite für alle unbenutzbar, die mit der Tastatur navigieren. Ohne Ring weißt du nicht mehr, wo du gerade bist. Das betrifft nicht nur Menschen mit Einschränkungen, sondern jeden, der ein Formular schnell durchtabben will.
Gefällt mir der Standardring nicht, ersetze ich ihn, statt ihn zu entfernen. Etwa mit :focus-visible { outline: 2px solid; outline-offset: 2px; }. Mit :focus-visible statt :focus bleibt der Ring nach einem Mausklick auf einen Button aus und erscheint bei Tastaturbedienung, und das wollten die meisten eigentlich von Anfang an. Ein Textfeld zeigt ihn auch nach einem Klick, denn dort wird gleich getippt.
In der Aufgabe bekommt das Profilbild auf der Projektkarte seine Rundung und einen Rahmen.
Zum Mitnehmen
Ein Rahmen braucht einen Stil, sonst ist er null Pixel breit, egal was bei Breite und Farbe steht. Innen gehört ein kleinerer Radius hin als außen, und eine Kontur macht nichts größer und schiebt nichts weg.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
Was in dieser Lektion steckt
-
Artikel mit 3 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe im Editor, direkt im Browser geprüft
Öffnet sich mit dem Basis Konto.