Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

State And Responsive Layers

Twill keeps interactive and responsive styling at the Style layer instead of shipping UI components.

Stateful styling

#![allow(unused)]
fn main() {
use twill::prelude::core::*;

let style = Style::interactive()
    .bg(Color::slate(Scale::S100))
    .text_color(Color::slate(Scale::S900))
    .hover(|style| style.opacity(0.9))
    .selected(|style| style.bg(Color::blue(Scale::S500)))
    .checked(|style| {
        style.border(
            BorderWidth::S1,
            BorderStyle::Solid,
            Color::green(Scale::S500),
        )
    })
    .open(|style| style.shadow(Shadow::Lg))
    .data_attr(DataState::Open, |style| style.text_color(Color::white()))
    .aria_attr(AriaAttr::Selected, |style| style.font_weight(FontWeight::Bold));
}

Supported built-in state layers:

  • hover
  • focus
  • focus_visible
  • active
  • disabled
  • selected
  • checked
  • open
  • closed

Supported arbitrary hooks:

  • data_attr(DataState::..., ...)
  • aria_attr(AriaAttr::..., ...)

Responsive styling

#![allow(unused)]
fn main() {
use twill::prelude::core::*;

let style = Style::card()
    .w(Spacing::S12)
    .at_sm(|style| style.w(Spacing::S24))
    .at_lg(|style| style.h(Spacing::S32));

let resolved = style.at_breakpoint(Breakpoint::Lg);
assert_eq!(resolved.width_value(), Some(Width::from(Spacing::S24)));
assert_eq!(resolved.height_value(), Some(Height::from(Spacing::S32)));
}

Available breakpoint helpers:

  • sm
  • md
  • lg
  • xl
  • s2xl

You can also attach layers generically with responsive(Breakpoint::..., ...).