日本語

Overview

hypersig::style is typed atomic CSS. A misspelled property name or keyword, or a value of the wrong type, is a compile error. Each declaration becomes one class.

A style is a Rust value

Style has one method per standard CSS property, and per anchor positioning property. The property list, each property's keywords, the pseudo-classes, the pseudo-elements, and the named colors are generated from MDN's CSS data (mdn-data 2.37.2). El::css adds a style to an element.

use hypersig::html::button;
use hypersig::style::Style;
use hypersig::style::value::{Color, Cursor, FontWeight, px, rem};
use hypersig::{Page, Signals};
use serde::{Deserialize, Serialize};

#[derive(Signals, Serialize, Deserialize)]
struct Shop {
    count: i32,
}

let buy = button::<Shop>()
    .css(
        Style::new()
            .padding_block(rem(0.5))
            .padding_inline(rem(1))
            .border_radius(px(6))
            .background_color(Color::hex(0x0018_181b))
            .color(Color::WHITE)
            .font_weight(FontWeight::Number(500.0))
            .cursor(Cursor::Pointer),
    )
    .text("Buy");

let html = Page::new("Shop", Shop { count: 0 }).child(buy).render();
// One class per declaration, named after it, and one rule per class in <head>.
assert!(html.contains("cursor_pointer"));
assert!(html.contains(".cursor_pointer{cursor:pointer}"));

A second call to the same property's method under the same conditions replaces the earlier value, as a later declaration does in a CSS rule. merge adds the declarations of another style, and the added declarations override the original ones.

One class per declaration

Each declaration becomes one class, whose name comes from the declaration, such as cursor_pointer or hover:color_crimson. Panda CSS and Tailwind CSS do the same in their atomic CSS. For a value with characters other than letters, digits, ., #, %, and -, the class name uses a hash of the value. Two elements with the same declaration use the same class, so the stylesheet grows with the number of distinct declarations rather than the number of elements.

The page collects the styles its elements use and writes each rule once into <head>. A patch that contains new elements also contains their rules, inserted where a breakpoint value still overrides the base value.

Styles switched by a signal

css_when(style, cond) adds a style while a signal condition holds, and css_match(value, cases) picks one style per value of a signal, like the variants of a Panda CSS recipe. Their rules are in a later cascade layer than those of css, so while switched on they override the element's own declarations for the same property.

Cascade layerHolds
hypersig-tokensThe values a Theme sets on :root
hypersig-baseThe rules of a Global, such as the reset
hypersig-atomsThe classes of El::css
hypersig-toggledThe classes of El::css_when and El::css_match

The layers come in that order, so an element's classes override the global rules, and a switched-on style overrides both. A stylesheet added with Page::style is in no layer and overrides all four layers.