futursolo / stylist-rs

A CSS-in-Rust styling solution for WebAssembly Applications
https://crates.io/crates/stylist
MIT License
366 stars 22 forks source link

CSS Variable Support #65

Open futursolo opened 2 years ago

futursolo commented 2 years ago

When using a SSR'ed page with dark mode support, as WebAssembly bundles are non render blocking content, users that defaults to dark mode will see a flash of light mode page.

The solution is to use CSS Variables (alongside a small render blocking JavaScript script to help detect which theme to use) which can be loaded before the page is rendered.

However, I find it difficult to ensure a globally unique css variable name across the entire application.

This issue aims to introduce a CssVariables derive macro that helps with the implementation.

WorldSEnder commented 2 years ago

It seems generating unique names will be needed more often. I've also needed it to generate unique names for animations. It could make sense to have a more general setup, if it's not too complicated with the different naming schemes.

futursolo commented 2 years ago

I thought we are adding a keyframes! to generate keyframes?

simbleau commented 1 year ago

I think a full variable management system is worth the R&D, because it can be useful in other aspects.

In general, I've seen a use-case for this, and it's faster to let the browser update via variables? (#79)

Here's a use-case I've battled with, and I'm not sure if there's a better way.

I set a global variable for font size, :root {--fs: 1em}, and upscaled for media queries, @media (min-width: 768px) { :root { --fs: 1.04em } }.

I'd love a way to respond to the variable changes, and use these variables in other classes, with the current value of --fs at any time, e.g.

#[function_component(Icon)]
pub fn icon(props: &Props) -> Html {
    let font_size = variables::get("--fs");
    html! {
        <i class={css!("height: ${fs}; width: ${fs};", fs=font_size)}> 
            /* Icon SVG Mask which could be 1.04em or 1em! */
        </i>
    }

My best solution so far has been storing my font sizes in my theme context, but I can't get media query updates this way.

futursolo commented 1 year ago

I have implemented what described in this issue a couple month ago but only had time to copy the implementation into this repository last week.

You can find the work under the branch css-vars.

Feel free to give it a shot and let me know how it works.

The css_var! macro is not documented and can be used with css_var!(theme.color).

It enforces reading a field from a CssVariables struct so that a fallback value will always be available if for some reason the css variable fails to register. The user can choose a non-changing value (e.g.: light theme as fallback) if they wish to switch via css variables.

simbleau commented 1 year ago

Brilliant, I may have time to give this a shot and give feedback.

dahlhugo commented 1 year ago

do you have an example of how to use css_var! with yew?