Styled Components in React
Styled Components in React
Styled Components ist einer von mehreren Ansätzen für CSS-in-JS. Die Bibliothek erfreut sich großer Beliebtheit unter React-Entwicklern, deshalb habe ich sie ausgewählt. Es handelt sich um ein externes Werkzeug und wird über die Befehlszeile installiert:
{title=“Command Line”,lang=“text”}
npm install styled-components
Importiere Styled Components nach der Installation in deine Anwendung. Füge die Anweisung hierzu in die src/App.js-Datei ein:
import React from 'react';
import axios from 'axios';
# start-insert
import styled from 'styled-components';
# end-insert
Wie die Bezeichnung CSS-in-JS vermuten lässt, erstellst du Styled Components innerhalb von JavaScript. Definiere deine ersten gestalteten Komponenten in der Datei src/App.js:
const StyledContainer = styled.div`
height: 100vw;
padding: 20px;
background: #83a4d4;
background: linear-gradient(to left, #b6fbff, #83a4d4);
color: #171212;
`;
const StyledHeadlinePrimary = styled.h1`
font-size: 48px;
font-weight: 300;
letter-spacing: 2px;
`;
Wenn du gestaltete Komponenten einsetzt, verwendest du Template-Strings genauso wie Funktionen. Alles zwischen den Backticks ist ein Argument, und das styled
-Objekt gibt dir Zugriff auf alle erforderlichen HTML-Elemente (beispielsweise div, h1). Sobald eine Funktion mit dem Stil aufgerufen wird, gibt sie eine Komponente zurück, die in der App verwendbar ist:
const App = () => {
...
return (
# start-insert
<StyledContainer>
<StyledHeadlinePrimary>My Hacker Stories</StyledHeadlinePrimary>
# end-insert
<SearchForm
searchTerm={searchTerm}
onSearchInput={handleSearchInput}
onSearchSubmit={handleSearchSubmit}
/>
{stories.isError && <p>Something went wrong ...</p>}
{stories.isLoading ? (
<p>Loading ...</p>
) : (
<List list={stories.data} onRemoveItem={handleRemoveStory} />
)}
# start-insert
</StyledContainer>
# end-insert
);
};
Styled Components folgen denselben Regeln wie gewöhnliche. Alles, was zwischen den Element-Tags eingefügt ist, wird als children
-Eigenschaft (Props) übergeben. Für Item verwenden wir diesmal keine Inline-Styles, sondern definieren eine gestaltete Komponente. StyledColumn
erhält seine Stile dynamisch mithilfe einer Eigenschaft (Props):
const Item = ({ item, onRemoveItem }) => (
# start-insert
<StyledItem>
<StyledColumn width="40%">
# end-insert
<a href={item.url}>{item.title}</a>
# start-insert
</StyledColumn>
<StyledColumn width="30%">{item.author}</StyledColumn>
<StyledColumn width="10%">{item.num_comments}</StyledColumn>
<StyledColumn width="10%">{item.points}</StyledColumn>
<StyledColumn width="10%">
<StyledButtonSmall
# end-insert
type="button"
onClick={() => onRemoveItem(item)}
>
Dismiss
# start-insert
</StyledButtonSmall>
</StyledColumn>
</StyledItem>
# end-insert
);
Die flexible width
-Eigenschaft (Props) ist über den Template-String der gestalteten Komponente als Argument einer Inline-Funktion zugreifbar. Der Rückgabewert der Funktion ist ein String. Wir benötigen keine explizite Return-Anweisung. Deshalb überarbeiten wir die Pfeilfunktion zu einer knappen und prägnanten Inline-Funktion:
const StyledItem = styled.div`
display: flex;
align-items: center;
padding-bottom: 5px;
`;
const StyledColumn = styled.span`
padding: 0 5px;
white-space: nowrap;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
a {
color: inherit;
}
width: ${props => props.width};
`;
Erweiterte Funktionen wie die CSS-Verschachtelung sind standardmäßig in gestalteten Komponenten verfügbar. Greife auf verschachtelte Elemente zu und wähle das aktuelle mit dem CSS-Operator &
aus:
const StyledButton = styled.button`
background: transparent;
border: 1px solid #171212;
padding: 5px;
cursor: pointer;
transition: all 0.1s ease-in;
&:hover {
background: #171212;
color: #ffffff;
}
`;
Erstelle spezielle Versionen von gestalteten Komponenten, indem du eine andere an die Funktion styled
übergibst. StyledButtonSmall und StyledButtonLarge übernehmen alle Stile der zuvor definierten StyledButton-Komponente:
const StyledButtonSmall = styled(StyledButton)`
padding: 5px;
`;
const StyledButtonLarge = styled(StyledButton)`
padding: 10px;
`;
const StyledSearchForm = styled.form`
padding: 10px 0 20px 0;
display: flex;
align-items: baseline;
`;
Wenn wir eine gestaltete Komponente wie StyledSearchForm verwenden, werden die zugrunde liegenden Elemente (form
, button
) in der realen HTML-Ausgabe verwendet. So ist es möglich, weiterhin die nativen HTML-Attribute (onSubmit
, type
, disabled
) zu verwenden:
const SearchForm = ({ ... }) => (
# start-insert
<StyledSearchForm onSubmit={onSearchSubmit}>
# end-insert
<InputWithLabel
id="search"
value={searchTerm}
isFocused
onInputChange={onSearchInput}
>
<strong>Search:</strong>
</InputWithLabel>
# start-insert
<StyledButtonLarge type="submit" disabled={!searchTerm}>
# end-insert
Submit
# start-insert
</StyledButtonLarge>
</StyledSearchForm>
# end-insert
);
Zuletzt integrieren wir die bisher nicht definierten Komponenten StyledLabel und StyledInput in InputWithLabel:
const InputWithLabel = ({ ... }) => {
...
return (
<>
# start-insert
<StyledLabel htmlFor={id}>{children}</StyledLabel>
# end-insert
# start-insert
<StyledInput
# end-insert
ref={inputRef}
id={id}
type={type}
value={value}
onChange={onInputChange}
/>
</>
);
};
Die Komponenten StyledLabel und StyledInput definieren wir in derselben Datei:
const StyledLabel = styled.label`
border-top: 1px solid #171212;
border-left: 1px solid #171212;
padding-left: 5px;
font-size: 24px;
`;
const StyledInput = styled.input`
border: none;
border-bottom: 1px solid #171212;
background-color: transparent;
font-size: 24px;
`;
Styled Components sind im Grunde genommen Styles in Form von React-Komponenten ohne CSS-Zwischendatei. Wenn eine solche in JavaScript definiert ist, aber nicht verwendet wird, erkennt eine integrierte Entwicklungsumgebung (IDE) dies und gibt dir einen Hinweis. Beide Methoden, CSS-in-JS und CSS-in-CSS, und ihre Ansätze (zum Beispiel gestaltete Komponenten und CSS-Module) sind bei React-Entwicklern beliebt. Deshalb war es mir wichtig, sie dir hier vorzustellen. Du bist aber völlig frei: Verwende an Werkzeugen ausschließlich das, was am besten zu dir und deinem Team passt.
Übungen:
- Begutachte den Quellcode dieses Abschnitts.
- Reflektiere die Änderungen gegenüber dem letzten Abschnitt.
- Lese mehr zum Thema Styled Components.
- Normalerweise gibt es keine src/index.css-Datei für globale Stile, wenn Styled Components verwendet werden. Finde heraus, ob und wie es möglich ist, globale Stile in Kombination mit gestalteten Komponenten zu verwenden.