Tools für externe Stylesheets:
CSS-in-JS libraries:
Hilfs-Utility: npm-Paket classnames:
import classNames from 'classnames';
<div
className={classNames({
todoitem: true,
completed: props.completed,
})}
>
[...]
</div>;
Bei create-react-app sind CSS-Module vorkonfiguriert; Diese erlauben das Verwenden von CSS-Klassennamen, die garantiert über CSS-Dateien hinweg eindeutig sind.
import styles from './TodoItem.module.css';
<div className={styles.todoItem + ' ' + styles.completed}>
...
</div>;
möglicher Output im HTML:
<div
class="TodoItem_todoItem__L9V1E TodoItem_completed__9bPW1"
>
...
</div>
<div className={classNames({
[styles.todoitem]: true,
[styles.completed]: props.completed
})}>
CSS-in-JS: JavaScript wird verwendet, um Stylesheets zu erzeugen und anzufügen
Heutzutage wird es als ok angesehen, Styling-Informationen in der gleichen Datei abzulegen, wie JavaScript / HTML
Libraries:
grundlegendes Beispiel in Emotion:
import { css } from '@emotion/css';
<button
className={css({
color: 'blue',
'@media (min-width: 600px)': { color: 'green' },
'&:hover': { color: 'red' },
})}
>
foo
</button>;
alternative Notation: via "tagged template strings"
<button
className={css`
color: blue;
&:hover {
color: red;
}
`}
>
foo
</button>
Empfehlung: Verwenden der css
-Property statt className
(benötigt zusätzliche Source-Code-Transformation):
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
<button css={css({ color: 'blue' })}>foo</button>;
styled components: Zugang, bei dem Komponenten erstellt werden, deren einzige Aufgabe es ist, Styling auf bestehende HTML-Elemente anzuwenden
Beispiel: PrimaryButoon
= ein button
-Element mit zusätzlichem Styling
Erstellen eines "styled component" mit emotion:
import styled from '@emotion/styled';
const PrimaryButton = styled.button({
color: 'blue',
'&:hover': { color: 'red' },
});
theoretische manuelle Variante:
function PrimaryButton(props) {
return (
<button
{...props}
className={css({
color: 'blue',
'&:hover': { color: 'red' },
})}
/>
);
}
dynamische Stile via Props:
mit JavaScript:
const Button = styled.button({
padding: 8,
color: (props) => (props.primary ? 'blue' : 'black'),
});
mit TypeScript:
const Button = styled.button<{ primary: boolean }>({
padding: 8,
color: (props) => (props.primary ? 'blue' : 'black'),
});
Übung: Verwende Styling-Tools, um zusätzliches Styling zu einer bestehenden Anwendung hinzuzufügen (z.B. zur Slideshow)
Animation des Erscheinens / Verschwindens von Elementen:
erweiterte Libraries:
grundlegende Animationen: via CSS Transitions
.TodoItem {
background-color: salmon;
transition-property: background-color;
transition-duration: 0.5s;
}
.TodoItem--Completed {
background-color: lightgrey;
}
Phasen für das Erscheinen / Verschwinden von Elementen:
react-transition-group: basiert auf CSS-Klassennamen
Beispiel mit framer motion:
<AnimatePresence>
{hovered ? (
<motion.button
animate={{ opacity: 1 }}
initial={{ opacity: 0 }}
exit={{ opacity: 0 }}
onClick={() => props.onDelete(props.todo.id)}
>
delete
</motion.button>
) : null}
</AnimatePresence>
Beispiel mit framer motion:
<AnimatePresence>
{todos.map((todo) => (
<motion.li
key={todo.id}
animate={visibleStyle}
initial={hiddenStyle}
exit={hiddenStyle}
>
{todo.title}
</motion.li>
))}
</AnimatePresence>
Beispiel mit react-spring:
<Transition
items={hovered}
from={{ opacity: 0 }}
enter={{ opacity: 1 }}
leave={{ opacity: 0 }}
reverse={hovered}
>
{(style, hovered) =>
hovered ? (
<animated.button
style={style}
onClick={() => props.onDelete(props.todo.id)}
>
delete
</animated.button>
) : null
}
</Transition>