In this post we gonna deep dive into styles and Css in JS .
Lately, i receive some question about: how does Styled components works ? Why Styled is still not working in Server Components ? And so on…
So i decided to start this repository to bring some answers to these questions.
When we use
<link> and refer to a css file, the browser will download the css file and apply the styles to the page.
You can see this behavior in the
The page will render without styles, and after the browser download the css file, the styles will be applied to the page.
When we use
<style> tag, the browser will apply the styles to the page.
You can see this behavior in the
The page will render with styles.
Is that the solution ? No, because we will have a lot of
<style> tags in our html file, and this is not a good practice.
Before start talking about styled-components, let's talk start a new example:
You can browse the
2_clientside_render folder, and run:
To start the server:
In the image below, you can see that first the browser will render the page without content.
Of course, our index.html file just have a
<!doctype html> <html lang="en"> <head> <script type="module" crossorigin src="/assets/index-44b5bae5.js"></script> <link rel="stylesheet" href="/assets/index-48a8825f.css"> </head> <body> <div id="app"></div> </body> </html>
Let's make it more interesting, i will copy the
2_render_csr folder to
After this, i will create a server.js to read dist folder and serve the files to the browser with server side rendering.
I had to add:
- Fastify (server)
- @fastify/static (to serve the files)
let's fix this:
I will remove some assets, because i need a the DOM Tree, chunks, etc… so i will only have the counter component and css preloaded.
lets browse the
4_preact_ssr folder, run:
yarn yarn ssr
Wow, thats awesome, the page will be rendered with the content by the server side. And if you are paying attencion until now, the only thing that is missing here is the styles.
so let's add this on server side also. The POOR way to do that is injecting inline styles in the html file.
Conclusion: at this point, we understand how browser works, and how to render the page with CONTENT AND STYLE in the server side.
But, WHEN WE GONNA TALK ABOUT STYLED COMPONENTS ?
Right now, my baby padawan.
Just a disclaimer: 1 - Styled components and SSR is not a good idea, because the styles will be injected in the html file, and this will make the file bigger, and the browser will take more time to download the file. 2 - Start to learn and use css modules, tailwind, etc… because you will not have a headache with SSR. Runtime styles is not a good idea for meta-framework today.
Let's browse the
5_styled_components folder, run:
yarn yarn dev
Note: Even using tailwind, the page will be rendered without styles.
But remember, we need to have a solid understanding about how the browser works.
How it works under the hood, or the basic things.
In this point, i will not fix whole page, but i will create 2 different component that will be rendered in the server side.
The first component will be rendered with styles, and the second will be rendered without styles.
1 - When we use styled components, the styles will be injected in the html file, and this will make the file bigger, and the browser will take more time to download the file.
2 - You must use "use client". This could be confused to have "use server" here, and client there, etc…
if you remove the "use client" directive, you will see this error: Error: createContext only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/context-in-server-component
Conclusion: styled components is not a good idea for SSR. The [G]OLD way to do that is using css modules ou scss.
The css is too small and just download what you are using, not the whole styles resources.
If you are using emotion today, because you need to use css in js ( mantine or Material UI ), no problem. Dont worry about that.
Hype comes and goes, but the basics will be always the same.
"Tools cannot change how browser works, only make it easier to do something." - Castro, Alexandro (aka me)
In a Next.js discussion, there is a comment that talk about experimental features, and one of them is `optimizeCss`, so let's try this. They use this package: https://www.npmjs.com/package/critters This package will extract the critical css and inject in the html file. I really think this have issues yet, so i will not use this approach.