Skip to content

Commit a03cbcc

Browse files
authored
docs: rewrite css and styling section for start v2 (#1585)
1 parent 3f0d159 commit a03cbcc

1 file changed

Lines changed: 201 additions & 0 deletions

File tree

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
---
2+
title: CSS and styling
3+
use_cases: >-
4+
styling components, css modules, scoped styles, component styling, design
5+
system setup, visual customization
6+
tags:
7+
- css
8+
- styling
9+
- modules
10+
- components
11+
- design
12+
- vite
13+
version: "2.0"
14+
description: >-
15+
Style your SolidStart components with CSS, CSS modules, and other styling
16+
solutions. Implement scoped styles and design systems.
17+
---
18+
19+
SolidStart 2.0 introduces a completely revamped CSS rendering mechanism:
20+
21+
- CSS deduplication during server-side rendering works more consistently across the board.
22+
- Hot module replacement (HMR) of route CSS is now directly managed by Vite instead of SolidStart.
23+
- CSS in `lazy`-loaded components is now properly server-side rendered and does not result in flashes of unstyled content.
24+
- Client-side navigation now mounts new CSS directly via Vite instead of SolidStart.
25+
- Server HTML responses no longer have to include the whole assets manifest.
26+
- Client-side navigation no longer unmounts old CSS, more closely following Vite's native behaviour.
27+
28+
## Styling components
29+
30+
You can import CSS using ESM syntax anywhere within the component tree. Styles imported as such, are globally mounted in your app.
31+
32+
```tsx title="Card.tsx" tab="component"
33+
import "./Card.css";
34+
35+
const Card = (props) => {
36+
return (
37+
<div class="card">
38+
<h1>{props.title}</h1>
39+
<p>{props.text}</p>
40+
</div>
41+
);
42+
};
43+
```
44+
45+
```css title="Card.css" tab="component"
46+
.card {
47+
background-color: #446b9e;
48+
}
49+
50+
h1 {
51+
font-size: 1.5em;
52+
font-weight: bold;
53+
}
54+
55+
p {
56+
font-size: 1em;
57+
font-weight: normal;
58+
}
59+
```
60+
61+
## Locally scoped styles
62+
63+
SolidStart supports [CSS modules](https://github.com/css-modules/css-modules), allowing you to locally scope the imported CSS.
64+
65+
As is standard with [Vite](https://vitejs.dev/guide/features.html#css-modules), any file ending with `.module.css`, `.module.scss` or `.module.sass` is considered a CSS module. Reference the generated css class names via the imported object, e.g. `styles.card`.
66+
67+
```tsx title="Card.tsx" tab="component"
68+
import styles from "./Card.module.css";
69+
70+
const Card = (props) => {
71+
return (
72+
<div class={styles.card}>
73+
<h1>{props.title}</h1>
74+
<p>{props.text}</p>
75+
</div>
76+
);
77+
};
78+
```
79+
80+
```css title="Card.module.css" tab="component"
81+
.card {
82+
background-color: #446b9e;
83+
}
84+
85+
div.card > h1 {
86+
font-size: 1.5em;
87+
font-weight: bold;
88+
}
89+
90+
div.card > p {
91+
font-size: 1em;
92+
font-weight: normal;
93+
}
94+
```
95+
96+
## Route-specific global styles
97+
98+
Imported CSS stays in the document when navigating to different routes. Therefore routes with different global styles will overlap each other. There exist several strategies to get around this limitation:
99+
100+
### Apply \:has pseudo-class
101+
102+
If you only have to apply few global CSS rules for one specific route, you can use the CSS [\:has](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:has) pseudo-class, to tie the global CSS to the route:
103+
104+
```tsx title="routes/about.tsx" tab="component"
105+
import "./about.css";
106+
107+
export default function About() {
108+
return (
109+
<main data-route="about">
110+
<h1>About us</h1>
111+
</main>
112+
);
113+
}
114+
```
115+
116+
```css title="routes/about.css" tab="component"
117+
body:has(main[data-route="about"]) {
118+
background-color: #446b9e;
119+
color: white;
120+
}
121+
```
122+
123+
### Import with ?url
124+
125+
If the route depends on complex global CSS (e.g. using Tailwind only in one specific route), optimizing all selectors with `:has` might not always be possible. Instead you can import the CSS file by URL and mount it through JSX:
126+
127+
```tsx title="routes/about.tsx" tab="component"
128+
import { Link } from "@solidjs/meta";
129+
import styleUrl from "./about.css?url";
130+
131+
export default function About() {
132+
return (
133+
<main>
134+
<Link rel="stylesheet" href={styleUrl} />
135+
<h1>About us</h1>
136+
</main>
137+
);
138+
}
139+
```
140+
141+
```css title="routes/about.css" tab="component"
142+
@import "tailwindcss";
143+
```
144+
145+
## Lazy loading
146+
147+
[Lazy](https://docs.solidjs.com/reference/component-apis/lazy) loading components with CSS is now fully supported in SolidStart 2.0 and no longer results in flashes of unstyled content (FOUC):
148+
149+
```tsx title="App.tsx" tab="component"
150+
import { lazy } from "solid-js";
151+
152+
// Lazy with dynamic import
153+
const Card = lazy(() => import("./Card.tsx"));
154+
155+
// Lazy with glob import
156+
const components = import.meta.glob("./Car*.tsx");
157+
const Card2 = lazy(Object.values(components)[0]);
158+
159+
const App = (props) => {
160+
return (
161+
<main>
162+
<Card />
163+
<Card2 />
164+
</main>
165+
);
166+
};
167+
```
168+
169+
```tsx title="Card.tsx" tab="component"
170+
import "./Card.css";
171+
172+
const Card = (props) => {
173+
return (
174+
<div class="card">
175+
<h1>{props.title}</h1>
176+
<p>{props.text}</p>
177+
</div>
178+
);
179+
};
180+
```
181+
182+
```css title="Card.css" tab="component"
183+
.card {
184+
background-color: #446b9e;
185+
}
186+
187+
h1 {
188+
font-size: 1.5em;
189+
font-weight: bold;
190+
}
191+
192+
p {
193+
font-size: 1em;
194+
font-weight: normal;
195+
}
196+
```
197+
198+
## Other ways to style components
199+
200+
SolidStart is built on top of Solid, meaning styling is not limited to CSS.
201+
To see other ways to style components, see the [styling section in the Solid documentation](/guides/styling-your-components).

0 commit comments

Comments
 (0)