Styling
In diesem Bereich gibt es einen Überblick über verschiedene Ansätze zur Gestaltung von React-Komponenten. Behandelt werden klassische CSS-Dateien, Inline-Styles, CSS-Module sowie moderne Lösungen wie Styled Components.
Inhaltsverzeichnis
Inline Styles
Der einfachste Ansatz React Components zu stylen ist die Verwendung von Inline Styles. Bei Inline Styles wird die Objekt-Notation verwendet.
const CardStyledInline = ({ cardTitle, children }) => {
return (
<div
className="styled_card"
style={{
border: '2px solid lightblue',
padding: '10px',
boxSizing: 'border-box',
borderRadius: '4px'
}}
>
<h2 style={{ marginTop: 0 }}>{cardTitle}</h2>
<div className="card_content">{children}</div>
</div>
);
};
export default CardStyledInline;
Die Verwendung dieses Components erfolgt auf dem klassischen Wege.
<CardStyledInline cardTitle="Inline Styles">
<p>Ein Card-Element mit Inline-Styles.</p>
</CardStyledInline>
Inline Styles als Objekt
Da es sich bei den Inline-Styles um eine Objekt-Notation handelt, kann man diese genauso in einer Variable speichern oder von anderswo importieren.
Im folgenden Beispiel verlagern wir die Inline-Styles im CardStyledInline
Component in eine Variable.
const CardStyledInline = ({ cardTitle, children }) => {
const cardStyles = {
border: '2px solid lightblue',
padding: '10px',
boxSizing: 'border-box',
borderRadius: '4px'
};
return (
<div
className="styled_card"
style={cardStyles}
>
<h2 style={{ marginTop: 0 }}>{cardTitle}</h2>
<div className="card_content">{children}</div>
</div>
);
};
export default CardStyledInline;
CSS-Modules
CSS-Module sind eine der beliebtesten Lösungen für CSS-Kapselung in React.
CSS-Module transformieren Klassennamen zur Laufzeit, um sicherzustellen, dass sie einzigartig sind. Eine Klasse .button
in einem Modul könnte zu etwas wie .MyComponent_button_1a2b3c
kompiliert werden.
Hier ein Beispiel, um es besser zu greifen und zu verstehen.
Zuerst erstellen wir ein Button-Element direkt in unserer App.jsx
. Dieses Button-Element stylen wir auf eine bestimmte Art und Weise.
import './App.scss';
const App = () => {
return (
<>
<button>Globaler Button</button>
</>
);
};
In zugehöriger App.scss
definieren wir Stile für diesen Button.
button {
padding: 6px;
color: #ffffff;
box-sizing: border-box;
border: 2px solid rgb(0, 73, 73);
}
Unser globaler Button aus der App.jxs
sieht also wie folgt aus.
Nun erstellen wir ein normales Component. Wir nennen ihn in diesem Fall CssModuleExample
. Dort platzieren wir einen Button. Diesem Button geben wir zunächst gar keine Stile.
const CssModuleExample = () => {
return (
<button>
Component Button
</button>
);
};
Wie wir sehen können, hat dieser Button die Stile aus der App.scss
übernommen. Warum? Weil die Stile in React ohne gesonderter Kapselung global sind.
Nun werden wir CSS-Modul verwenden, um dieses Component zu mit den Stilen zu kapseln.
Dazu erstellen zu unserem Component die Daten CssModuleExample.module.css
.
.button {
color: #ffffff;
border-radius: 6px;
border: 4px solid rgb(247, 104, 247);
background-color: rgb(152, 38, 152);
cursor: pointer;
font-size: 1.2rem;
}
Diese CSS-Datei soll nun im Component selbst importiert werden.
import styles from './CssModuleExample.module.css';
const CssModuleExample = () => {
return (
<button className={styles.button}>Component Button</button>
);
};
export default CssModuleExample;
Das Ergebnis zeigt nun, dass dieser Button tatsächlich abweichende Stile angenommen hat. Und zwar die, welche wir in der CssModuleExample.module.css
definiert haben.
Der Builder (Vite oder Webpack) transformieren die Stile aus der verlinkten CSS und wandeln diese in JavaScript-Objekte um, welche wir dann über den vergebenen Namen, hier styles
, ansprechen können.
Wenn wir also unsere Stile in der CssModuleExample.module.css
ergänzen, wächst auch unsere JavaScript-Objekt mit den erzeugten Klassennamen als Schlüsselnamen im Objekt.
Angenommen, wir fügen folgende CSS-Definition hinzu.
.btn_primary {
color: #ffffff;
background-color: #b3680c;
}
Unser JavaScript-Objekt wird dann folgendermaßen aussehen.
Styled Components
Styled Components ist eine beliebte Bibliothek, um CSS direkt in JavaScript zu definieren und so Komponenten-basiertes Styling umzusetzen. Diese Bibliothek basiert auf Tagged Template Literals und nutzt die volle Power von JavaScript, um Styles dynamisch, wiederverwendbar und wartbar zu gestalten.
Installation
Bevor man diese Bibliothek verwenden kann, muss sie installiert werden. Das kann man mit folgender Anweisung im Root-Ordner des Projekts tun.
npm install styled-components
Damit ist die Bibliothek installiert und kann nun verwendet werden.
Beispiel - Ohne Stile
Wie immer, brauchen wir ein Beispiel, an dem alles verständlicher wird. Zuerst definieren wir ein normales Component, ohne besondere Stile.
const StyledComponentExample = () => {
return (
<>
<p>First paragraph.</p>
<p>Second paragraph.</p>
</>
);
};
export default StyledComponentExample;
Als Ergebnis hätten wir reguläre Ausgabe von zwei p-Tags. Soweit nichts besonderes.
Beispiel - mit Stile
Nun importieren wir die Bibliothek, bzw. die Funktion styled
aus styled-components
.
Mit Hilfe von dieser Funktion können wir benutzerdefinierte Tags, eine Art Components, aufbauen und diesen spezifische Styles zuweisen.
In unserem Beispiel möchten wir ein Paragraph mit spezifischen Styles haben. Wir erstellen ein ParagraphLightBlue
Component und weisen diesem bestimmte Stile zu.
import styled from 'styled-components';
const ParagraphLightBlue = styled.p`
padding: 10px;
border: 1px solid blue;
background-color: lightblue;
`;
const StyledComponentExample = () => {
console.log(styled);
return (
<>
<ParagraphLightBlue>First line.</ParagraphLightBlue>
<p>Second line.</p>
</>
);
};
export default StyledComponentExample;
Statt unserem normalen p
Tag, verwenden wir nun ParagraphLightBlue
. Weil wir styled.p
verwendet haben, erhalten wir ein p
-Tag. Mit styled.div
würden wir ein div
-Elemente stattdessen erhalten.
Als Ergebnis erhalten wir unseren Paragraphen mit entsprechenden Styles, die wir über styled.p
definiert haben.
Weil es sich hierbei um eine Art Component handelt, können wir es problemlos wiederverwenden. Wir ergänzen unser Beispiel und werden auch den zweiten Paragraphen durch ParagraphLightBlue
ersetzen.
import styled from 'styled-components';
const ParagraphLightBlue = styled.p`
padding: 10px;
border: 1px solid blue;
background-color: lightblue;
`;
const StyledComponentExample = () => {
console.log(styled);
return (
<>
<ParagraphLightBlue>First line.</ParagraphLightBlue>
<ParagraphLightBlue>Second line.</ParagraphLightBlue>
</>
);
};
export default StyledComponentExample;
Props-basiertes Styling
Styled Components erlauben, Styles anhand von React-Props zu ändern.
Für diesen Fall erstellen wir ein React Component mit styled
Verwendung StyledComponentButton
. Dort definieren wird ein paar Stile für die Buttons.
import styled from 'styled-components';
const Button = styled.button`
color: #333333;
padding: 0.5em 1em;
border: none;
border-radius: 4px;
display: inline-block;
background-color: #a3d6d6;
`;
const StyledComponentButton = () => {
return (
<>
<Button>Standard Button</Button>
<hr/>
<Button>Primary Button</Button>
</>
);
};
export default StyledComponentButton;
Als Ergebnis haben wir folgende Ausgabe. Zwei gleich aussehende Buttons.
Anschließend erweitern wir unser Component und fügen die Verwendung von Props hinzu, sodass wir mithilfe von Props-Eigenschaften die Stile etwas anpassen können.
import styled from 'styled-components';
const Button = styled.button`
color: #333333;
padding: 0.5em 1em;
border: none;
border-radius: 4px;
display: inline-block;
background-color: ${({ $primary }) =>
$primary ? '#68a7eb' : '#a3d6d6'};
`;
const StyledComponentButton = () => {
return (
<>
<Button>Standard Button</Button>
<hr/>
<Button $primary>Primary Button</Button>
</>
);
};
export default StyledComponentButton;
Wie wir an der Ausgabe sehen können, sind die Buttons nun unterschiedlich. Dazu ist ebenfalls sichtbar, dass die eine CSS-Klasse gemeinem von beiden Buttons und eine unterschiedliche (für abweichende Stile) verwendet werden.
Icons
Für React gibt es viele verschiedene Icon-Bibliotheken. In folgenden wird die Verwendung von React Icons gezeigt.
Zuerst soll das Paket im Projekt-Ordner installiert werden.
npm install react-icons --save
Im nächsten Schritt soll ein Icon ausgesucht werden, welches verwendet werden soll. Jedes Icon dieser Bibliothek ist ein Component. Dieses Component kann importiert und wie jedes andere Component verwendet werden.
import { CiDesktop } from "react-icons/ci";
const IconExample = () => {
return (
<span>
<CiDesktop />
</span>
);
};
export default IconExample;
Man kann nun, wie in diesem Beispiel, das Icon in einem Component kapseln oder einfach in anderen Components einsetzen.
<IconExample />
Konfiguration von Icons
React Icon stellen ein paar Konfigurationsoptionen bereit, welche man als Props in das jeweilige Icon-Component übergeben kann.
Im nächsten Beispiel erweitern wir die Verwendung von CiDesktop
Icon um Angabe von size
und color
Eigenschaften.
import { CiDesktop } from "react-icons/ci";
const IconExample = () => {
return (
<span>
<CiDesktop size={100} color="teal" />
</span>
);
};
export default IconExample;