QwikDev / qwik

Instant-loading web apps, without effort
https://qwik.dev
MIT License
20.74k stars 1.29k forks source link

CSS-in-JS support #1185

Closed kee-oth closed 1 year ago

kee-oth commented 2 years ago

Is your feature request related to a problem?

Styling! Styling can be tricky business in web applications. CSS-in-JS helps solve a lot of developer experience issues in that realm.

Describe the solution you'd like

I'd like to see Qwik support and have clear documentation for using CSS-in-JS libraries.

Example libraries:

Stitches stitches.dev/

Emotion https://emotion.sh/docs/introduction

Describe alternatives you've considered

The alternative is not using CSS-in-JS for styling Qwik applications.

Additional context

No response

dephiros commented 2 years ago

I think useStylesScoped$ + css custom properties can fill a lot of css-in-js needs in a lightweight way. I think this is similar to vue and svelte's scoped style

olup commented 2 years ago

Maybe useStylesScoped$ would be better and more idiomatic, but just fyi, here is a naive use of @emotion/css with qwik : https://github.com/olup/qwik-emotion (check the root component and the entry.ssr)

ChibiBlasphem commented 2 years ago

@dephiros

I think useStylesScoped$ + css custom properties can fill a lot of css-in-js needs in a lightweight way. I think this is similar to vue and svelte's scoped style

useStylesScoped$ is like the scoped css of vue: when wanting to override child elements (to add margins or grid-area, placement properties) it becomes cumbersome to how "scoped" and encapsulated the parent styles are. And you dont want to create "global" styles too as they could conflict with css classes anywhere in your app.

By the way we're in full typescript and CSS-in-JS lets you add more typesafety to your css (by, for example, managing you css variables with TS)

kevinseabourne commented 1 year ago

Class based styles is antiquated. Using css in js by replacing all the html elements with a name reference, makes your code clean and easy to read. You can simply pass a dynamic property to any element reference and dynamically change any css properties independently, without having to change class names. It's the logical way of styling in my eyes.

osdiab commented 1 year ago

My personal big benefit for CSS in JS is that you can write your styles more modularly and easily compose them. Because you can use tools like Emotion to create modular styles that you want in your codebase, with the full expressivity of JS to refer to them by variable names rather than with opaque class names that are easy to screw up, as well as to make CSS abstractions flexibly, you can mash stuff together in really cool ways.

With React and Emotion you might do something like this contrived example:

// i can create flexible helpers that make common styles I use
const gapSizes = { xs: 4, s: 8, m: 12, l: 16, xl: 32 };
function stackCss(size: keyof typeof gapSizes, direction: "row" | "column"): CSSInterpolation {
  return { display: "flex", flexDirection: direction, gap: `${gapSizes[size]}px` };
}

// i can mishmash styles with media queries and other forms of nesting simply
function largeScreenCss(css: CSSInterpolation): CSSInterpolation {
  return { "@media (min-width: 600px)": css };
}

// i can just combine multiple styles together freely, and it's all typechecked and autosuggested by the editor
const articleListCss: CSSInterpolation = [
  stackCss("s", "column"),
  largeScreenCss(stackCss("m", "column")),
  { "> article": stackCss("s", "row") },
];

function ArticleList() {
  // the components themselves become transparent to read through, and Emotion handles the style
  // order properly so that precedence is easily predictable
  return <div css={articleListCss}>
    <article><h2>The first article</h2><p>This article comes first</p></article>
    <article><h2>The second article</h2><p>This article will come next</p></article>
    <article><h2>The third article</h2><p>All these articles are evenly spaced from one another</p></article>
  </div>;
}

(though the need for a build step to deal with the css prop in this style of Emotion is the most annoying part. Though the @emotion/css integration above looks good!)

Also interested in how one would use vanilla-extract with Qwik.

kevinseabourne commented 1 year ago

I would happily use qwik if it had a css in js library that worked with it and that library also support animation libraries like how styled components supports framer motion. An amazing spring based animation library, There is also a framework agnostic animation adaption called motion one. Ive been trying to get the ball rolling with css in js libraries to support motion one to avoid having to write plain css just to have nice animations work. Solidjs has a css in js library so I dont see why qwik cant do it as well ?

Maxximus007 commented 1 year ago

Just scratching the surface of Qwik, but perhaps vanilla-extract could be a good match as an addition?

osdiab commented 1 year ago

@Maxximus007 movement toward this here: https://github.com/BuilderIO/qwik/issues/1836

zanettin commented 1 year ago

Hi @ all 👋 Just quickly wanted to check what's missing from the original post. Vanilla extract is implemented. thanks for your reply 🙏

manucorporat commented 1 year ago

Panda CSS solution is very good!