-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Styling Brainstorming #533
Comments
I think the system for styling would be best as a separate system, where individual properties are ideally strictly typed. Then the library could be integrated here. |
I agree with @ThomasdenH and think this could start out as a separate crate but could eventually get added to @jkelleyrtp are you thinking of taking approach like https://cssinjs.org/? I would love having a way to use declarative styles like this. Then the integration with |
@jstarry I was definitely feeling inline CSS in the same way that JSS works - I like having the state of the component directly tied to its appearance. I'm going to approach this in the same way that styled-components work so we can just drop existing stylesheets into components but also be able to modify them on component updates. |
Personally I just use bootstrap. Then apply the class attributes as needed: https://hackerthemes.com/bootstrap-cheatsheet/ I don't use the JS part of it; just the stylesheets. I can imagine possibly a high level API that just applies those, but I think I would prefer to just apply them myself. The question is where does the scope of yew end ? perhaps what's needed is a separate yew-styling plugin/library ? |
@jkelleyrtp Have you made any progress towards this? |
Nevermind, I've got a prototype in the works here in case anyone wants to check it out: |
Here is my thoughts on building styling system. I think there are two different places that we need to handle style:
A default style for every componentEvery component can have it's own default style, let's say a
At this point we need to defined the behavior of the styling system, thus we need to answer these questions:
A unique style for every component instateSome times we change style for component instate, by adding, removing .. etc styles to the component instate, thus we need to defined a how the styling system would allow us to do that. possible answer for the 1st question
|
I'm having a play with writing a css parser from rust tokens, and it seems to be going well. It's available at https://github.com/derekdreery/style. The idea is that you can do things like <div style={{font-size: 10px; flex-direction: column}}></div> from within a macro in rust code, making using css/styles feel really natural. |
Wow, awesome @derekdreery! Looks like the yew html macro could depend on your style macros under the hood. Is that what you had in mind? |
I agree with
from #533 (comment). |
Happy to help out however you want to use them. There are a couple of small caveats:
The lib I'm working on does typecheck your CSS, so only valid types of property values are allowed for a given property name. |
My preference is to use css modules, or css that's localised to the component, keeping components from conflicting with each other automatically. To this end there is the css-modules crate, which simply aliases all of the class names in a css file and imports a list of those aliases into rust. The author of the crate was recently harassed into deleting their GitHub account by a group of transphobes but everything still works just fine. Edit: I forgot to say that I also use it with rollup for post processing. |
First off, New to rust & New to yew... Figure it would be a great place to learn both! Recently been using a lot of Svelte and I have really enjoyed their take on styling. <style>
p {
color: purple;
font-family: 'Comic Sans MS', cursive;
font-size: 2em;
}
</style>
<p>Styled!</p> They do stuff under the hood of generating classes and attaching them to the elements but it avoids concepts of theming and leaves it to the developer/css. Ideally (for me) an API like so would exist like so where I could leverage css variables to do the theming/customization of a child component in CSS. impl Component for Model {
fn style(&self) -> Css {
css! {
div {
background: black;
--main-text-color: white;
}
}
}
fn view(&self) -> Html {
html! {
<div>
<MyComponent /> <!-- changes child's --main-text-color by setting the var -->
</div>
}
} It may not be possible (still learning) but I would be interested if it does. |
@bl42 I like the look of that. Minor detail: the function signature wouldn't quite work like that if the CSS was generated at compile time since we wouldn't have an instance of the component then.
I don't quite understand your vision here, could you elaborate a bit more? |
I have developed trait with similar functionality, Component should declare their Style struct that will be used to style the component (e.g. Entry) instead of using some sort of collection that doesn't help at checking the used style if it works with the Component or not. My project using Seed, but I'm pretty sure this idea is applicable in Yew too. |
My preferred output would have some "Global Styles" that I can declare for the app (on mount) Something like @import 'google fonts...'
@import 'css animations lib...'
html {
font-size: 65.25%
--primary-color: #000;
--primary-text: #fff;
etc..
} and in each component have the ability to call We could easily store these values in Rust... but I suggest to let CSS do what it is good at. |
Hi I just published a library that is supposed to help with that. I was in need for a framework that works in a way that styled components work. Here is what I came up with: CSSinRust https://crates.io/crates/css-in-rust. Feel free to open Issues and/or PR's. The target is to make it work with any components framework. |
Since this PR's title is brainstorming. I'll throw in my 5 cents with Components as a way to hide style implementation details. Libraries like Styled Components enable developers to bind style at a Component level, which leads to the removal of the class to node mapping. It also enforces more declarative In JS, template literals give the ability to evaluate the Component's CSS declaration (a string mixed with expressions) through the components own props. I guess in rust a macro would do this instead. These styles are added to the I disagree with having defaults for styles, because the browser already takes care of that. One should also consider, how could I reset, or normalize, or simply set some global properties on my stylesheet? What about prefixes? Perhaps this is out of the scope of Yew. |
@icyJoseph this sounds good. It would be nice to typecheck the styles at compiletime then generate the appropriate string templates for use at runtime. |
Similar to @icyJoseph I'm just throwing my ideas at the wall here, but as a web developer my experience is that developers are embracing tools such as styled components as it means everything is "just JS" - meaning one can handle dynamic prop based styles intuitively whilst the clear component scoping reduces the classic "why has my div flew half down the screen I only want the title to be red". I believe the "just JS" approach to styling in yew ( "just rust" ) and building a rust-y implementation of "styled-components"-ish style system thats fits the needs of yew could lead to not only a more consistent developer experience due to projects being only one language but also gives oppurtunity to build more advanced tooling around styles be that in the editor or oppurtunity for minimising style size at build. The things styled components does well and has brought to the ecosystem, are almost dying to implemented in the rust. I would also like to say I would like to keep an eye on this and am happy to discuss further and get involved in any proof of concepts. Not sure the etiquette here but if I wanted to start work on this to see how it would work, would I need for this discussion to be resolved or would I need to create some code and build a discussion around a PR. Thanks for any pointers. |
What if we use something like Rust structs and enums, something like:
Rather than going for parsing or macros, I feel this might be better. |
I like the way material UI supported styles (it's CSS framework for react): They are using type definitions for css properties from https://github.com/frenic/csstype (it's for typescript) and use it in functions like createStyles, where user defines named classes (similar to css classes) and then can use those named classes later in tsx template. They also allow theming, when createStyles call wrapped to makeStyles, which receive (contextual) theme. I think it's a great example and it would be cool to have something similar for yew. The most complicated part in this is (I think) typing all of css properties in Rust types, but that work worth it. |
I like the idea behind StyledComponents but in practice, it's just pure pain.
The nicest approach to CSS I saw so far is bs-css that is Statically typed DSL for writing css in reasonML It's similar to what @emmanuelantony2000 proposed. Instead of enums reasonML have variadic types and polymorphic variant types (sure it's not the same as Enums, I'm not saying it can be easily replicated in Rust). open Css;
let card = style([
display(flexBox),
flexDirection(column),
alignItems(stretch),
backgroundColor(white),
boxShadow(Shadow.box(~y=px(3), ~blur=px(5), rgba(0, 0, 0, 0.3))),
unsafe("-webkit-overflow-scrolling", "touch"),
padding(Theme.basePadding)
]); (all definitions are imported by opening Css module) <div className=card></div> The only |
^ related prior art: https://github.com/purescript-contrib/purescript-css |
A couple of observations:
|
Just saw this on my feed today, a Sass compiler built in pure Rust: https://github.com/connorskees/grass |
CSSinRust is now compatible with yew 0.17.* (https://crates.io/crates/css-in-rust). Check out https://github.com/lukidoescode/yew-fullstack-boilerplate on how to use it. I'd appreciate any PRs. |
This looks great. Is there a way of providing a sass or css file that overrides these defaults? It would be great to give to an artist for them to tweak. |
How about the way vueJS does it: https://vue-loader.vuejs.org/guide/scoped-css.html#deep-selectors You could add an unique id to every component, modify the css which should be pretty simple, and recursively add an attribute to every DOM element in the component, perhaps at render time. |
My dream is to have a component-oriented solution like Yew, but to be able to use some custom styling/layout language instead of HTML/CSS, something like iced has, or like elm-ui. The biggest issue I see with CSS is that styles are separated from HTML and the view is splitted into two parts as a result. You can also take a look at elm-css that solves this by allowing you to embed CSS directly into HTML and then auto-generates classes from that, but I don't believe that's the right direction. I'm convinced that the better solution is to build abstractions over HTML/CSS instead (that maybe could then even compile to other platforms like in the case of iced). I haven't tried Yew yet actually, just trying to contribute to the discussion by bringing some ideas :) |
I have one possible solution: https://github.com/lovelace-ed/lovelace/blob/main/utils/mercutio/src/lib.rs Note that it depends on Malvolio (another crate I've written) and I can't publish the next version of that until Rocket cuts its next release 🤷🏼 |
Reading this conversation, the bs-css was the best implementation example, I think. One more thing to consider is that the browser downloads the whole wasm code at once. As far as I know, yew cannot split bundles currently. So maybe it's not the best performance to keep the CSS in rust right now. Also, CSS in WASM requires two compilations, one for WASM, one for CSS. As I see, currently the css-modules is the best performing option with in-rust syntax checking. |
I think I'm approaching the "styling" question from a slightly different angle. "CSS-in-<language>" may be a good fit for modular aesthetic/layout styling, but it seems a bit heavy-handed for data-driven styles where object-identity of an element/component matters more than its semantic-identity. For example, I'm currently working on a The obvious workaround is to use Handling a |
Composable styles are becoming popular, via https://tailwindcss.com/ Today I can use the twind shim in a Yew app and get Tailwind support for free, but a proper CSS compiler that generates only the classes in use inside the |
Tailwindcss JIT compiler |
Since there have been no commits on the css-in-rust crate for over a year, I have decided to create a fork to provide Yew 0.18 support and fix a couple known issues that I had when using the crate as well as some improvement on the internals. https://github.com/futursolo/stylist-rs I would appreciate any feedback on this. |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
I'd like to add a styling system to yew - not having a built-in way of styling components seems a bit unfinished to me. If we want to build better, bigger, and faster web apps, then we need a way of managing styles that doesn't clobber a global namespace and makes sense when looking at the components.
I'd like to see a Stylable trait where we can pull in an existing stylesheet (using css-parser for the servo project), modify it (override the defaults), and then set that as the element style.
We could also have a special style property for each element where we can inject style into even the subdivs of elements.
I personally favor parsing an external stylesheet and doing inline modification because of autocompletes working with .css files, but there is also room for a css! macro and reserve a keyword for the element that the style is being applied to, to access subdivs in that element.
Curious what the thoughts of the community is before I try pull my changes into the project.
The text was updated successfully, but these errors were encountered: