Skip to content

Commit

Permalink
docs: split styling out into its own section
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanflorence committed Aug 19, 2023
1 parent bd3359a commit 2e2f9bf
Show file tree
Hide file tree
Showing 10 changed files with 753 additions and 813 deletions.
813 changes: 0 additions & 813 deletions docs/guides/styling.md

This file was deleted.

41 changes: 41 additions & 0 deletions docs/styling/bundling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
title: CSS Bundling
---

# CSS Bundling

Some CSS features in Remix bundle styles into a single file that you load manually into the application including:

- [CSS Side Effect Imports](./css-imports)
- [CSS Modules](./css-modules)
- [Vanilla Extract](./vanilla-extract)

Note that any [regular stylesheet imports](./css) will remain as separate files.

## Usage

Remix does not insert the CSS bundle into the page automatically so that you have control over the link tags on your page.

To get access to the CSS bundle, first install the `@remix-run/css-bundle` package.

```sh
npm install @remix-run/css-bundle
```

Then, import `cssBundleHref` and add it to a link descriptor—most likely in `root.tsx` so that it applies to your entire application.

```tsx filename=root.tsx lines=[1,5-7]
import { cssBundleHref } from "@remix-run/css-bundle";

export const links = () => {
return [{ rel: "stylesheet", href: cssBundleHref }];
};
```

With this link tag inserted into the page, you're now ready to start using the various CSS bundling features built into Remix.

## Limitations

Avoid using `export *` due to an [issue with esbuild's CSS tree shaking][esbuild-css-tree-shaking-issue].

[esbuild-css-tree-shaking-issue]: https://github.com/evanw/esbuild/issues/1370
33 changes: 33 additions & 0 deletions docs/styling/css-imports.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
title: CSS Imports
---

# CSS Side Effect Imports

Some NPM packages use side effect imports of plain CSS files (e.g. `import "./styles.css"`) to declare the CSS dependencies of JavaScript files. If you want to consume one of these packages, first ensure you've set up [CSS bundling][css-bundling] in your application.

For example, a module may have source code like this:

```tsx
import "./menu-button.css";

export function MenuButton() {
return <button data-menu-button>{/* ... */}</button>;
}
```

Since JavaScript runtimes don't support importing CSS in this way, you'll need to add any relevant packages to the [`serverDependenciesToBundle`][server-dependencies-to-bundle] option in your `remix.config.js` file. This ensures that any CSS imports are compiled out of your code before running it on the server. For example, to use React Spectrum:

```js filename=remix.config.js
/** @type {import('@remix-run/dev').AppConfig} */
module.exports = {
serverDependenciesToBundle: [
/^@adobe\/react-spectrum/,
/^@react-spectrum/,
/^@spectrum-icons/,
],
// ...
};
```

[server-dependencies-to-bundle]: ../file-conventions/remix-config#serverdependenciestobundle
91 changes: 91 additions & 0 deletions docs/styling/css-in-js.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
title: CSS in JS
---

# CSS in JS libraries

Most CSS-in-JS approaches aren't recommended to be use in Remix because they require your app to render completely before you know what the styles are. This is a performance issue and prevents streaming features like [`defer`](../utils/defer).

Here's some sample code to show how you might use Styled Components with Remix (you can also [find a runnable example in the Remix examples repository][styled-components-example]):

1. First you'll need to put a placeholder in your root component to control where the styles are inserted.

```tsx filename=app/root.tsx lines=[21-23]
import {
Links,
LiveReload,
Meta,
Outlet,
Scripts,
ScrollRestoration,
} from "@remix-run/react";

export default function App() {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1"
/>
<Meta />
<Links />
{typeof document === "undefined"
? "__STYLES__"
: null}
</head>
<body>
<Outlet />
<ScrollRestoration />
<Scripts />
<LiveReload />
</body>
</html>
);
}
```

2. Your `entry.server.tsx` will look something like this:

```tsx filename=entry.server.tsx lines=[7,16,19-24,26-27]
import type {
AppLoadContext,
EntryContext,
} from "@remix-run/node"; // or cloudflare/deno
import { RemixServer } from "@remix-run/react";
import { renderToString } from "react-dom/server";
import { ServerStyleSheet } from "styled-components";
export default function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext,
loadContext: AppLoadContext
) {
const sheet = new ServerStyleSheet();
let markup = renderToString(
sheet.collectStyles(
<RemixServer
context={remixContext}
url={request.url}
/>
)
);
const styles = sheet.getStyleTags();
markup = markup.replace("__STYLES__", styles);
responseHeaders.set("Content-Type", "text/html");
return new Response("<!DOCTYPE html>" + markup, {
status: responseStatusCode,
headers: responseHeaders,
});
}
```

Other CSS-in-JS libraries will have a similar setup. If you've got a CSS framework working well with Remix, please [contribute an example][examples]!

NOTE: You may run into hydration warnings when using Styled Components. Hopefully [this issue][styled-components-issue] will be fixed soon.
37 changes: 37 additions & 0 deletions docs/styling/css-modules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
title: CSS Modules
---

# CSS Modules

To use the built-in CSS Modules support, first ensure you've set up [CSS bundling][css-bundling] in your application.

You can then opt into [CSS Modules][css-modules] via the `.module.css` file name convention. For example:

```css filename=app/components/button/styles.module.css
.root {
border: solid 1px;
background: white;
color: #454545;
}
```

```tsx filename=app/components/button/index.js lines=[1,9]
import styles from "./styles.module.css";

export const Button = React.forwardRef(
({ children, ...props }, ref) => {
return (
<button
{...props}
ref={ref}
className={styles.root}
/>
);
}
);
Button.displayName = "Button";
```

[css-bundling]: ./bundling
[css-modules]: https://github.com/css-modules/css-modules
Loading

0 comments on commit 2e2f9bf

Please sign in to comment.