2 unstable releases
Uses new Rust 2024
0.2.0 | Apr 30, 2025 |
---|---|
0.1.0 | Jan 24, 2025 |
#608 in Game dev
158 downloads per month
1MB
13K
SLoC
About
Bevy Flair enables developers to style Bevy UI interfaces using familiar CSS syntax.
With Bevy Flair, you can define the appearance and layout of Bevy UI components efficiently, leveraging the simplicity and power of CSS.
Features
- Use CSS assets to apply format to any Bevy UI element.
- Inherited stylesheets. Just specify the stylesheet using
NodeStyleSheet
in the root node, and all children will inherit the same stylesheet. - Support for css reloading. Just edit your .css files and the styles will be re-applied on the fly. This is one of the main advantages over specifying the styles directly.
- Almost All existing UI components and properties are supported:
- All
Node
properties are supported. - Components
BorderColor
,BackgroundColor
,BorderRadius
,Outline
,BoxShadow
andZIndex
are supported, and inserted automatically when the corresponding property is used (e.g. usingbackground-color: red
will automatically insert theBackgroundColor
component )
- All
- Use of non-standard css to support
ImageNode
(e.g:background-image: url("panel-border-030.png")
,background-image-mode: sliced(20.0px)
). - Color parsing. (e.g.
red
,#ff0000
,rgb(255 0 0)
,hsl(0 100% 50% / 50%)
,oklch(40.1% 0.123 21.57)
) - Most common css selectors works by default (Thanks to selectors crate).
:root
selector#id
selector. Works by using theName
component.class
selector. Works by using theClassList
componentType
selector. Works by using theTrackTypeNameComponentPlugin
plugin configured by default to track:Node
,Button
,Label
andText
,:hover
,:active
and:focus
pseudo class selectors.:hover
and:active
are automatically tracked for buttons.:nth-child(_)
,:first-child
works just fine. e.g::nth_child(2n + 1)
- Most common css selector combinators (Thanks to selectors crate):
- Descendant:
ul.my-things li
. - Child:
ul.my-things > li
. - Next sibling:
img + p
. - Subsequent-sibling:
img ~ p
.
- Descendant:
- Fancy selectors like
:not()
,:has()
,:is()
and:where()
. - Nested selectors are supported.
- You can add
&:hover { .. }
inside a selector and it will work.
- You can add
- Import other stylesheets using
@import
. - Support for custom properties using
var()
.- Fallback is currently not supported
- Basic support for calc expressions using
calc()
.- This is currently limited by Bevy support of mixing different types. For example, this cannot not work currently:
calc(100% - 20px)
. - Currently, is valuable to do calculations using vars. For example:
calc(var(--spacing) * 2)
.
- This is currently limited by Bevy support of mixing different types. For example, this cannot not work currently:
- Support for inherited properties (e.g.
color
,font-family
are inherited by default). - Font loading support using
@font-face
. - Animated property changes using
transition
. - Custom animations using
@keyframes
. - Different stylesheets per subtree. With the use of a different
NodeStyleSheet
per subtree. It's even possible to not apply any style for a given subtree. - Supports for custom properties. (Example TBA)
- Supports for custom parsing. (Example TBA)
Missing features and limitations
- Multiple stylesheets at the same time. Right now it's restricted to a single stylesheet per entity.
- This is partially mitigated by the use of
@imports
.
- This is partially mitigated by the use of
- Global stylesheets. It's not possible to define a stylesheet that is applied everywhere.
- Inline css. Right now it's not possible to define css directly in code. It has to be defined directly into an asset with the
.css
extension. It wouldn't be as easy as creating a simple macro for it, but it most definitely something to be considered. - Support for
@media
queries. It could be interesting to see what features make sense to implement. - Support for
!important
.- I don't really know if it's something people use nowadays.
One possible first step would be detected the presence of an
!important
and ignore it (with a warning) instead of throwing a parse error.
- I don't really know if it's something people use nowadays.
One possible first step would be detected the presence of an
- Support for
@layer
.- Some modern frameworks like tailwind make use of this so it could be interesing to add support to.
- Support for local fonts or support fallback fonts. Right now a single font is specified using
@font-face
. In bevy this should work for the majority of users. - Advance color parsing like using
color-mix()
or relative colors likelch(from blue calc(l + 20) c h)
.- This should be relatively easy to add.
- Support for pre-processors like
sass
. It should be relatively simple to add crate that generates css from sass code.
Showcase
This example works by only using CSS (See example)
https://github.com/user-attachments/assets/792b9cfa-42fb-4e50-a85f-8d21aafeb1e5
Getting started
-
Add
bevy_flair
to yourCargo.toml
. -
Create your UI structure and attach
NodeStyleSheet
the root:
main.rs
:
use bevy::prelude::*;
use bevy_flair::prelude::*;
fn main() {
App::new()
.add_plugins((DefaultPlugins, FlairPlugin))
.add_systems(Startup, setup)
.run();
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(Camera2d);
commands
.spawn((
Node::default(),
NodeStyleSheet::new(asset_server.load("my_stylesheet.css")),
))
.with_children(|parent| {
parent
.spawn((Button, Node::default()))
.with_child(Text::new("Button"));
});
}
Save your css file under assets/my_stylesheet.css
:
:root {
display: flex;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
flex-direction: column;
}
Button {
display: flex;
align-items: center;
justify-content: center;
width: 150px;
height: 65px;
background-color: rgb(15%, 15.0%, 15.0%);
border-radius: 30px;
transition: background-color 0.3s;
&:hover {
background-color: rgb(25.0%, 25.0%, 25.0%);
}
&:active {
background-color: rgb(35.0%, 75.0%, 35.0%);
}
Text {
font-size: 35px;
color: rgb(30% 30% 30%);
}
}
You can see more examples in the examples folder.
Project goals
- Support all Bevy UI features from css.
- Efficient and reactive when applying styles.
- If there are no modifications to the state of the UI tree, the styles should not be re-applied.
- When modifications are detected in the UI tree, just the minimum affected nodes should get their style reapplied.
- Invalid css should be reported and discarded.
- Any unrecognized property should be reported, not silently ignored.
- A badly written property should not stop the parsing of the rest of the css file
- An invalid css select, should only affect its rule set, and not the rest of the css
- No panics while parsing css.
- Css that would make your application panic should be rejected and reported.
- If any correctly parsed css can cause a panics in bevy, it should be treated as a bug.
Non goals
- Care about how developers spawn the Bevy UI elements.
- If you want to use any fancy macro to spawn your bevy UI elements, or if you want to do it in a manual way, it should not matter, it should work the same way.
- Define a default style.
- By default, if a property is not defined, such property will not be modified. This means that is up to the author to set up fallback styling if it's needed.
- Support all css features / properties.
- CSS is a vast specification, so there are plenty of features that might not make sense to support.
- Being consistent with the css standard.
- CSS is a standard and such it defines certain behaviours very well, for example, current implementation of
animation
ortransition
is quite possible not 100% consistent with the standard.
- CSS is a standard and such it defines certain behaviours very well, for example, current implementation of
- Implement missing Bevy UI features.
- If a certain feature does not exist in bevy UI, it will not implement, e.g. it will not implement
transform
norlinear-gradient
if bevy UI does not implement them. - There is always an option to implement custom properties with custom parsers.
- If a certain feature does not exist in bevy UI, it will not implement, e.g. it will not implement
Bevy compatibility
bevy | bevy_flair |
---|---|
0.16 | 0.2 |
0.15 | 0.1 |
Contributing
Contributions are welcome! Feel free to fork the repository and submit a pull request.
License
This project is licensed under the MIT License. See the LICENSE file for more details.
The assets included in this repository (for our examples) fall under different open licenses.
Assets
- Poppins font. Designed by Indian Type Foundry, Jonny Pinhorn, Ninad Kale (https://fonts.google.com/specimen/Poppins) (SIL Open Font License, Version 1.1: assets/fonts/OFL.txt)
- Kenney Space Font from Kenney Fonts (CC0 1.0 Universal)
- UI borders from Kenny's Fantasy UI Borders Kit (CC0 1.0 Universal)
Dependencies
~60–92MB
~1.5M SLoC