CSS-in-JS
Bei CSS-in-JS schreibst du Styles direkt in JavaScript — keine separaten CSS-Dateien, keine manuellen Klassennamen. Die bekannteste Bibliothek dafür ist Emotion. Sie besteht aus zwei Paketen, die jeweils eine eigene Coding-Variante einführen:
@emotion/react— das Kernpaket. Ermöglicht dencss-Prop, mit dem du Styles direkt auf JSX-Elemente schreibst.@emotion/styled— ein Zusatzpaket, das diestyled-API bereitstellt. Die Syntax ist von styled-components übernommen: Du erstellst neue Komponenten, die ihre Styles bereits eingebaut haben.
Installation & Konfiguration
Abschnitt betitelt „Installation & Konfiguration“npm install @emotion/react @emotion/styledDamit der css-Prop funktioniert, muss Vite wissen, wie es JSX transformieren soll. Dazu passt du die Vite-Konfiguration an:
import { defineConfig } from 'vite';import react from '@vitejs/plugin-react';
export default defineConfig({ plugins: [ react({ jsxImportSource: '@emotion/react', }), ],});Die Einstellung jsxImportSource: '@emotion/react' sorgt dafür, dass JSX-Elemente den css-Prop unterstützen.
Verwendung
Abschnitt betitelt „Verwendung“Der css-Prop
Abschnitt betitelt „Der css-Prop“Der css-Prop akzeptiert Styles, die mit der css-Funktion erzeugt werden. Diese Funktion unterstützt zwei Schreibweisen:
Tagged Template Literal — CSS-Syntax wie gewohnt:
const headerCss = css` padding: 16px 20px; border-bottom: 1px solid #e5e7eb; background-color: #f9fafb;`;Objekt-Syntax — CSS als JavaScript-Objekt (Properties in camelCase):
const headingCss = css({ margin: 0, fontSize: '18px',});Beide Varianten sind gleichwertig — verwende die, die dir besser gefällt. Hier CardTitle mit beiden:
import { css } from '@emotion/react';
const headerCss = css` padding: 16px 20px; border-bottom: 1px solid #e5e7eb; background-color: #f9fafb;`;
const headingCss = css({ margin: 0, fontSize: '18px',});
function CardTitle({ children }) { return ( <header css={headerCss}> <h2 css={headingCss}>{children}</h2> </header> );}
export default CardTitle;styled — Styled Components
Abschnitt betitelt „styled — Styled Components“styled erstellt eine neue Komponente mit eingebauten Styles:
import styled from '@emotion/styled';
const StyledCard = styled.article` border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;`;
function Card({ children }) { return <StyledCard>{children}</StyledCard>;}
export default Card;Alle Komponenten mit Emotion
Abschnitt betitelt „Alle Komponenten mit Emotion“Button.jsx
Abschnitt betitelt „Button.jsx“import styled from '@emotion/styled';
const StyledButton = styled.button` padding: 8px 16px; border: 1px solid #d1d5db; border-radius: 6px; background-color: ${({ variant }) => variant === 'primary' ? '#2563eb' : '#ffffff'}; color: ${({ variant }) => variant === 'primary' ? '#ffffff' : '#374151'}; border-color: ${({ variant }) => variant === 'primary' ? '#2563eb' : '#d1d5db'}; font-size: 14px; cursor: pointer;
&:hover { background-color: ${({ variant }) => variant === 'primary' ? '#1d4ed8' : '#f3f4f6'}; }`;
function Button({ variant = "default", children }) { return ( <StyledButton variant={variant}>{children}</StyledButton> );}
export default Button;Beachte, wie der variant-Prop direkt in den Styles verwendet wird. Kein manuelles Zusammensetzen von Klassennamen — die Logik lebt dort, wo die Styles definiert sind.
CardContent.jsx
Abschnitt betitelt „CardContent.jsx“import styled from '@emotion/styled';
const StyledCardContent = styled.div` padding: 20px;`;
function CardContent({ children }) { return <StyledCardContent>{children}</StyledCardContent>;}
export default CardContent;App.jsx
Abschnitt betitelt „App.jsx“import styled from '@emotion/styled';import Card from "./Card";import CardTitle from "./CardTitle";import CardContent from "./CardContent";import Button from "./Button";
const Layout = styled.div` max-width: 600px; margin: 0 auto; padding: 20px; font-family: system-ui, sans-serif;`;
const Header = styled.header` display: flex; align-items: center; gap: 12px; margin-bottom: 24px;
h1 { margin: 0; font-size: 24px; }`;
const Actions = styled.div` display: flex; gap: 8px; margin-top: 16px;`;
function App() { return ( <Layout> <Header> <img src="https://react.dev/images/brand/logo_light.svg" alt="React Logo" width="40" height="40" /> <h1>CSS mit React</h1> </Header>
<main> <Card> <CardTitle>Willkommen</CardTitle> <CardContent> <p> Diese kleine App zeigt, wie du React-Komponenten mit verschiedenen CSS-Ansätzen stylen kannst. Die Struktur bleibt immer gleich — nur das Styling ändert sich. </p> <Actions> <Button>Zurück</Button> <Button variant="primary">Weiter</Button> </Actions> </CardContent> </Card> </main> </Layout> );}
export default App;Vor- und Nachteile
Abschnitt betitelt „Vor- und Nachteile“| Vorteile | Nachteile |
|---|---|
| Volle JavaScript-Power in Styles | Runtime-Overhead — Styles werden zur Laufzeit berechnet |
| Dynamische Styles basierend auf Props | Größeres Bundle durch die Bibliothek |
| Keine Klassennamen-Verwaltung nötig | Lernkurve — neue API zusätzlich zu CSS |
| Styles sind automatisch an die Komponente gebunden | Weniger vertraut für reine CSS-Entwickler |