% ============================================ % STEP 02: STYLING MIT TAILWIND & URBANIST % ============================================ \section{Styling mit Tailwind CSS und Urbanist-Schriftart} \label{sec:step02} In diesem Schritt gestalten wir unsere Portfolio-Seite mit Tailwind CSS, binden eine eigene Schriftart ein und erstellen einen benutzerdefinierten Scrollbalken. Jede Zeile Code wird ausführlich erklärt. \subsection{Schriftart Urbanist installieren} Urbanist ist eine moderne, serifenlose Schriftart von Google Fonts mit 18 verschiedene Schnitten (Thin bis Black, jeweils normal und italic). Wir verwenden fünf Grundschnitte. \textbf{Schritt 1: Schriftart-Dateien ins Projekt kopieren} \begin{lstlisting}[language=Bash, caption={Schriftart-Dateien ins Public-Verzeichnis kopieren}] cd ~/projects/portfolio cp -r Urbanist apps/web/public/Urbanist \end{lstlisting} \textbf{Warum \texttt{public/}?} \begin{itemize} \item Alles im \texttt{public/}-Ordner wird von Vite unverändert übernommen \item Dateien sind unter \texttt{/Urbanist/static/...} im Browser erreichbar \item Kein Import nötig – direkter Pfad in CSS \end{itemize} \subsection{Index.css – Das Herzstück des Stylings} Die Datei \texttt{apps/web/src/index.css} vereint Tailwind, Schriftarten und Custom-Styles. Hier jede Zeile im Detail erklärt. \subsubsection{Tailwind Import} \begin{lstlisting}[language=CSS, caption={Tailwind CSS importieren}] @import "tailwindcss"; \end{lstlisting} \textbf{Erklärung:} \begin{itemize} \item \texttt{@import} – CSS-Regel zum Importieren anderer Stylesheets \item \texttt{"tailwindcss"} – Lädt alle Tailwind-Basis-Styles, Komponenten und Utilities \item In Tailwind 4 \textbf{kein} \texttt{@tailwind base/components/utilities} mehr! \item Diese einzige Zeile ersetzt Hunderte von handgeschriebenen CSS-Zeilen \end{itemize} \subsubsection{Schriftart-Definitionen (5 Schnitte)} \begin{lstlisting}[language=CSS, caption={Urbanist Regular (400)}] @font-face { font-family: "Urbanist"; src: url("/Urbanist/static/Urbanist-Regular.ttf") format("truetype"); font-weight: 400; font-style: normal; font-display: swap; } \end{lstlisting} \textbf{Zeile für Zeile:} \begin{itemize} \item \texttt{@font-face} – CSS-At-Regel zum Definieren einer eigenen Schriftart \item \texttt{font-family: "Urbanist"} – Der Name, unter dem wir die Schrift später verwenden (z.B. in \texttt{font-family: var(--font-display)}) \item \texttt{src: url("/Urbanist/...")} – Pfad zur Schriftdatei. Beginnt mit \texttt{/}, ist also relativ zur Domain-Root \item \texttt{format("truetype")} – Sagt dem Browser, welches Format die Datei hat (.ttf = TrueType) \item \texttt{font-weight: 400} – Diesen Schnitt für normale Textstärke verwenden (400 = Regular) \item \texttt{font-style: normal} – Kein Kursiv (italic wäre \texttt{font-style: italic}) \item \texttt{font-display: swap} – WICHTIG! Zeigt sofort Text in einer Ersatzschrift an und tauscht sie aus, sobald Urbanist geladen ist. Verhindert "Flash of Invisible Text" (FOIT) \end{itemize} \textbf{Die 5 definierten Schnitte:} \begin{enumerate} \item \texttt{Urbanist-Light.ttf} – Gewicht 300 (dünn, für Fließtext) \item \texttt{Urbanist-Regular.ttf} – Gewicht 400 (normal, Standard) \item \texttt{Urbanist-Medium.ttf} – Gewicht 500 (halbfett) \item \texttt{Urbanist-SemiBold.ttf} – Gewicht 600 (fast fett) \item \texttt{Urbanist-Bold.ttf} – Gewicht 700 (fett, für Überschriften) \end{enumerate} \subsubsection{Tailwind Theme} \begin{lstlisting}[language=CSS, caption={Tailwind Custom Theme}] @theme { --font-display: "Urbanist", sans-serif; --breakpoint-3xl: 1920px; --color-primary: #8dff69; } \end{lstlisting} \textbf{Zeile für Zeile:} \begin{itemize} \item \texttt{@theme} – Tailwind 4 Direktive zum Erweitern/Überschreiben des Standard-Themes \item \texttt{--font-display: "Urbanist", sans-serif} – Definiert eine neue Schrift-Klasse \texttt{font-display}. \texttt{sans-serif} ist der Fallback, falls Urbanist nicht lädt \item \texttt{--breakpoint-3xl: 1920px} – Neuer Breakpoint für sehr große Bildschirme. Nutzbar als \texttt{3xl:text-7xl} \item \texttt{--color-primary: \#8dff69} – Definiert eine neue Farbe \texttt{primary} (helles Grün). Nutzbar als \texttt{text-primary}, \texttt{bg-primary}, \texttt{border-primary}, etc. \end{itemize} \textbf{Verwendung der Custom-Properties in Tailwind:} \begin{itemize} \item \texttt{font-display} in \texttt{font-family: var(--font-display)} \item \texttt{3xl} als Breakpoint: \texttt{3xl:grid-cols-4} \item \texttt{primary} als Farbe: \texttt{text-primary}, \texttt{bg-primary/50}, \texttt{border-primary} \end{itemize} \subsubsection{Base-Layer (globale Stile)} \begin{lstlisting}[language=CSS, caption={Globale Stile}] @layer base { html { font-family: var(--font-display); scroll-behavior: smooth; } body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; background-color: #000000; color: #ffffff; overflow-x: hidden; } } \end{lstlisting} \textbf{Zeile für Zeile:} \begin{itemize} \item \texttt{@layer base} – Tailwinds "base"-Layer. Styles hier haben niedrigste Spezifität und können von Utilities überschrieben werden \item \texttt{font-family: var(--font-display)} – Setzt Urbanist als Standardschrift für die gesamte Seite \item \texttt{scroll-behavior: smooth} – Sanftes Scrollen bei Ankerlinks (z.B. \texttt{\#projekte}) \item \texttt{-webkit-font-smoothing: antialiased} – Glättet Schrift auf macOS/iOS (WebKit-Browser) \item \texttt{-moz-osx-font-smoothing: grayscale} – Gleiches für Firefox auf macOS \item \texttt{background-color: \#000000} – Schwarzer Hintergrund \item \texttt{color: \#ffffff} – Weiße Schrift als Standard \item \texttt{overflow-x: hidden} – Verhindert horizontales Scrollen (wichtig für Animationen, die über den Rand hinausgehen) \end{itemize} \subsubsection{Custom Scrollbar (WebKit)} \begin{lstlisting}[language=CSS, caption={Scrollbar für Chrome, Edge, Safari}] ::-webkit-scrollbar { width: 16px; } ::-webkit-scrollbar-track { background: #1a1a1a; } ::-webkit-scrollbar-thumb { background: linear-gradient(180deg, #8dff69, #6fe047); border-radius: 8px; } ::-webkit-scrollbar-thumb:hover { background: linear-gradient(180deg, #a8ff8d, #5bc92e); } \end{lstlisting} \textbf{Zeile für Zeile:} \begin{itemize} \item \texttt{::-webkit-scrollbar} – Pseudo-Element für die gesamte Scrollbar (Breite, Hintergrund) \item \texttt{width: 16px} – Breite der Scrollbar. Größer = dickerer Balken \item \texttt{::-webkit-scrollbar-track} – Der "Hintergrund" der Scrollbar (die Schiene) \item \texttt{background: \#1a1a1a} – Dunkelgrauer Track (fast schwarz) \item \texttt{::-webkit-scrollbar-thumb} – Der bewegliche "Griff" der Scrollbar \item \texttt{linear-gradient(180deg, \#8dff69, \#6fe047)} – Farbverlauf von hellgrün (oben) nach dunkelgrün (unten). \texttt{180deg} = von oben nach unten \item \texttt{border-radius: 8px} – Abgerundete Ecken am Griff \item \texttt{::-webkit-scrollbar-thumb:hover} – Wenn die Maus über dem Griff ist \item \texttt{\#a8ff8d, \#5bc92e} – Hellere Grüntöne beim Hover für visuelles Feedback \end{itemize} \subsubsection{Firefox Scrollbar} \begin{lstlisting}[language=CSS, caption={Scrollbar für Firefox}] * { scrollbar-width: auto; scrollbar-color: #6fe047 #1a1a1a; } \end{lstlisting} \textbf{Erklärung:} \begin{itemize} \item Firefox unterstützt \texttt{::-webkit-scrollbar} \textbf{nicht} \item \texttt{scrollbar-width: auto} – Normale Breite (Alternative: \texttt{thin}) \item \texttt{scrollbar-color: GRIFF SCHIENE} – Erste Farbe = Griff, zweite Farbe = Schiene \end{itemize} \subsubsection{Hilfsklasse: Scrollbar ausblenden} \begin{lstlisting}[language=CSS, caption={Hilfsklasse für Karussells}] .hide-scrollbar::-webkit-scrollbar { display: none; } \end{lstlisting} Für horizontale Karussells – der Inhalt scrollt, aber die Scrollbar ist unsichtbar. \subsection{App.tsx – Die React-Komponente erklärt} \begin{lstlisting}[language=TypeScript, caption={Vollständige App.tsx mit Zeilen-Erklärung}] function App() { return ( // Äußerster Container // min-h-screen: mindestens Bildschirmhöhe (wichtig für zentrierte Inhalte) // bg-black: schwarzer Hintergrund // text-white: weiße Schrift als Basis // p-8: 32px Innenabstand auf allen Seiten
Ich baue moderne Webanwendungen mit React, .NET und Docker. Minimalistisch, schnell und zuverlässig.
{/* Button-Gruppe */} {/* mt-10: 40px Abstand nach oben */} {/* flex: Flexbox-Layout */} {/* gap-4: 16px Abstand zwischen den Buttons */} {/* justify-center: Buttons horizontal zentrieren */}