# DISCUSSION: Qwik Component Stylesheet Handling
###### tags: qwik
## Overview
Brainstorm how should Qwik handle component stylesheets
## Requirements
1. Stylesheets should be lazy loaded only when needed
- SSR code will have both the `<style>` as well as the component already in the HTML. If the component needs to be re-rendered the component template needs to be downloaded. Downloading the template should not require re-downloading the CSS (because it is already in the `<style>` doe to SSR.)
3. Stylesheets should be scoped to the component
## Ideas
A list of ideas to discuss on how such code should work.
### Scoping Stylesheet to the Component
- Each element in the component will need a custom class to narrow down the stylesheet to just that component
- The custom class name should be the SHA of the component path? But only `n` (6?) characters and all `a-z0-9` alphanumeric letters. (`36^6 = 2,176,782,336` extremely low chance of collision) For example: `A0Q1X3`
- Components will need to declare their ID This will allow the host element to know which stylsheet needs to be downloaded (and if it needs to be downloaded)
```html
<div decl:template="./MyComponent#A0Q1X3"
class="A0Q1X3">
```
- The insertion of the host element should trigger checking if a given stylesheet is already loaded and if not it should be loaded.
> **Open Questions**
> - Should the component QRL be the component SHA always? (Since it is kind of duplicate information?)
### Downloading Stylesheet only when needed
- Component is recognized by `<div decl:template="./MyComponent#A0Q1X3">`. We could institute a rule that the component's stylesheet is same QRL with `.css` suffix resulting in `./MyComponent.css`
- Only download the stylesheet on first render. (Subsequent renderings do not need stylsheet downloaded because it already has been downloaded and inserted into `<head>`)
- A stylesheet is inserted into `<head>` either directly or as a link so:
```html
<head>
...
<style decl:style="A0Q1X3">...</style>
<link decl:style="A0Q1X3" href="./MyComponent.css" rel="stylesheet">
</head>
```
- In both cases we need to include `decl:style="A0Q1X3"` so that the rendering system can easily determine if the stylesheet is already present upon Qwik resume. Upon first render Qwik can execute `querySelectorAll('[decl\\:style="A0Q1X3"]')` to determine if the stylsheets needs to be downloaded.
- `<style>` has advantage of inlining hence faster startup
- `<link>` has advantage of caching
- Both approaches should work
### Open Questions
- Would it be possible to have the tooling warn on unused styles? How would we know that the styles are unused?
- At times it is useful to be able to add styles programmatically to the components. How could we add such styles in lazy way.
### Static vs dynamic styles
- component styles which are in the `<style decl:style="A0Q1X3">` should be static. What we mean by that is that all of these styles need to be present for the component to render properly.
- At times it is desirable to have dynamic styles
```typescript
function MyComponent() {
return <span class={expr ? FOO : ''}></span>
}
```
In the above example `FOO` is added dynamically.
- It means that it is not possible to statically determine if the `FOO` class should be included in the `<style>` tag. Hence no way to know if there are unused classes in the `<style>`.
- Is it worth going through the trouble of lazy loading `FOO`?
- Maybe we separate things into static styles and dynamic styles. Static styles are included in `<style>` where as dynamic styles are inlined into the `.js` code?
---
```typescript=
// ==> Should produce a ObjectLiteral representing the style
// import * as HelloWorld_css from 'HelloWorld.css'; // Seems unecessary
type HelloWorld = QComponent<{}, {}>
const HelloWorldState = qrlState<HelloWorld>(() => {});
// TOOLING: const HelloWorldState = qrlState<HelloWorld>(QRL`chunk_abc#state`);
// const HelloWorldStyle = qrlStyle<HellWorld>(HelloWorld_css);
const HelloWorldStyle = qrlStyle<HellWorld>('./HelloWorldStyle.css');
const HelloWorldStyle = qrlStyle<HellWorld>(import('./HelloWorldStyle.css'));
// TOOLING: const HelloWorldStyle = QRL`./chunk_abc#CSS?scopeId=abc123`;
const HelloWorld = qComponent({
state: HelloWorldState,
style: HelloWorldStyle,
view: HelloWorldView
})
```
```css=
.some-class {...};
:host.some-class2 {...};
```
```typescript=
// chunk_abc.js
export const CSS = `
.🏷️abc123.some-class {...}
.📦abc123.some-class2 {...}
`;
export const state = () => {}
```
Requirements:
- Lazy load the styles
- Generate unique IDs for each component
- Munge the styles with ID prefix