CSS3 Programmatic Styling

Apply CSS styles programmatically with fluent methods—build responsive designs entirely in Java.

Inline Styles

Apply CSS properties directly on elements with fluent setter methods like setBackgroundColor(), setPadding(), and setBorderRadius().

addStyleAttribute()

Fall back to addStyleAttribute() for any CSS property that doesn't have a dedicated method—grid layouts, transitions, filters, and more.

CSS Class Management

Dynamically add and remove CSS classes on StyledElement subclasses. Toggle styles in event handlers without touching inline styles.

CssStyleSheet & CssRule

Build complete stylesheets in Java with selectors, pseudo-classes, and hover states. The same type-safe methods available on elements.

Media Queries

Create responsive designs with CssMediaQuery. Define breakpoints and conditional rules entirely in Java—desktop, tablet, and mobile.

CssFile

Extend CssFile to serve stylesheets as cacheable or dynamic resources. Build user-specific themes from database settings, or share static styles across pages.

Inline Style Methods

Every element has type-safe methods for the most common CSS properties. These methods translate directly to inline style attributes on the rendered HTML. Your IDE provides autocomplete for every property, and the compiler catches typos at build time.

Java
Div card = new Div();

// Layout
card.setDisplay(Display.FLEX);
card.setFlexDirection(FlexDirection.COLUMN);
card.setAlignItems(AlignItems.CENTER);
card.setGap("16px");

// Sizing
card.setWidth("300px");
card.setMaxWidth("100%");
card.setPadding("24px");
card.setMargin("0 auto");

// Appearance
card.setBackgroundColor("#ffffff");
card.setColor("#1f2937");
card.setBorderRadius("12px");
card.setBoxShadow("0 2px 8px rgba(0, 0, 0, 0.1)");

// Position
card.setPosition(Position.RELATIVE);
card.setOverflow(Overflow.HIDDEN);

The addStyleAttribute() Fallback

For CSS properties that don't have a dedicated setter method, use addStyleAttribute(). This covers CSS Grid layouts, transitions, transforms, backdrop filters, and any other CSS3 property—giving you full access to the entire CSS specification.

Java
// CSS Grid layout
card.addStyleAttribute("grid-template-columns", "repeat(3, 1fr)");
card.addStyleAttribute("grid-template-rows", "auto 1fr auto");

// Transitions and transforms
card.addStyleAttribute("transition", "all 0.3s ease");
card.addStyleAttribute("transform", "translateY(-2px)");

// Visual effects
card.addStyleAttribute("backdrop-filter", "blur(10px)");
card.addStyleAttribute("filter", "drop-shadow(0 4px 8px rgba(0, 0, 0, 0.1))");

// Modern CSS features
card.addStyleAttribute("aspect-ratio", "16 / 9");
card.addStyleAttribute("scroll-behavior", "smooth");

Prefer built-in style methods

Always use dedicated methods like setDisplay(), setPosition(), and setBackgroundColor() when available. Only fall back to addStyleAttribute() for CSS properties that don't have a dedicated method. Built-in methods provide type safety through enums and prevent property name typos.

CSS Class Management

Elements that extend StyledElement can dynamically add and remove CSS classes. This is particularly useful in event handlers where you need to change an element's appearance in response to user actions.

Java
Div alert = new Div();

// Add one or more classes (space-separated)
alert.addClass("alert alert-success");

// Remove a class
alert.removeClass("alert-success");

// Add a different class
alert.addClass("alert-error");

Dynamic Styling in Event Handlers

Java
@Override
public void onEvent(MouseClickedEvent event)
{
    // Toggle active state
    if (isActive)
    {
        panel.removeClass("panel-active");
        panel.addClass("panel-inactive");
    }
    else
    {
        panel.removeClass("panel-inactive");
        panel.addClass("panel-active");
    }

    isActive = !isActive;
}

Programmatic Stylesheets

For page-level styles, use CssStyleSheet and CssRule to build CSS programmatically. This gives you the same type-safe methods available on elements, but applied to CSS selectors—including pseudo-classes like :hover and :focus.

Java
CssStyleSheet css = new CssStyleSheet();

// Base card style
CssRule cardRule = new CssRule(".card");
cardRule.setBackgroundColor("#ffffff");
cardRule.setPadding("24px");
cardRule.setBorderRadius("12px");
cardRule.setBoxShadow("0 2px 8px rgba(0, 0, 0, 0.1)");
cardRule.addStyleAttribute("transition", "box-shadow 0.2s ease");
css.addRule(cardRule);

// Hover state
CssRule cardHover = new CssRule(".card:hover");
cardHover.setBoxShadow("0 4px 16px rgba(0, 0, 0, 0.15)");
css.addRule(cardHover);

// Focus state
CssRule inputFocus = new CssRule("input:focus");
inputFocus.addStyleAttribute("outline", "2px solid #2563eb");
inputFocus.addStyleAttribute("outline-offset", "2px");
css.addRule(inputFocus);

// Add to page
head.addElement(new Style(css));

Responsive Design with Media Queries

Use CssMediaQuery to add responsive styles. Define breakpoints for desktop, tablet, and mobile layouts—all in Java with the same fluent API used for regular rules.

Java
CssStyleSheet css = new CssStyleSheet();

// Default: 3-column grid
CssRule grid = new CssRule(".product-grid");
grid.setDisplay(Display.GRID);
grid.addStyleAttribute("grid-template-columns", "repeat(3, 1fr)");
grid.setGap("24px");
css.addRule(grid);

// Tablet: 2-column grid
CssMediaQuery tablet = new CssMediaQuery("(max-width: 1024px)");
CssRule tabletGrid = new CssRule(".product-grid");
tabletGrid.addStyleAttribute("grid-template-columns", "repeat(2, 1fr)");
tablet.addRule(tabletGrid);
css.addMediaQuery(tablet);

// Mobile: 1-column
CssMediaQuery mobile = new CssMediaQuery("(max-width: 768px)");
CssRule mobileGrid = new CssRule(".product-grid");
mobileGrid.addStyleAttribute("grid-template-columns", "1fr");
mobile.addRule(mobileGrid);
css.addMediaQuery(mobile);

Reusable Stylesheets with CssFile

For styles shared across multiple pages, extend CssFile to serve CSS as a proper file with browser caching support. The stylesheet is built once and served as a cacheable resource—just like a traditional CSS file, but built entirely in Java.

Java
@Page("/css/common.css")
public class CommonStyles extends CssFile
{
    public static final String PATH = "/css/common.css";

    public CommonStyles()
    {
        super("common-styles");  // Cache key
    }

    @Override
    protected CssStyleSheet createStyleSheet()
    {
        CssStyleSheet css = new CssStyleSheet();

        CssRule body = new CssRule("body");
        body.setFontFamily("'Inter', sans-serif");
        body.setColor("#1f2937");
        body.setMargin("0");
        css.addRule(body);

        // Add more shared rules...

        return css;
    }

    public static void addStyleSheet(Head head)
    {
        head.addCssLink(PATH);
    }
}

Referencing from Any Page

Java
@Override
protected void createHead(Head head)
{
    CommonStyles.addStyleSheet(head);  // Links to /css/common.css
}

Dynamic Stylesheets

Because CssFile builds CSS programmatically in Java, it can generate stylesheets dynamically based on any data source—database records, user preferences, configuration files, or session state. This is a powerful capability that static CSS files cannot match.

Java
@Page("/css/user-theme.css")
public class UserThemeStyles extends CssFile
{
    public static final String PATH = "/css/user-theme.css";

    public UserThemeStyles()
    {
        super();  // Dynamic mode - no caching (content varies per user)
    }

    @Override
    protected CssStyleSheet createStyleSheet()
    {
        // Load the current user's theme settings from the database
        UserPreferences prefs = UserPreferences.loadForCurrentUser();

        CssStyleSheet css = new CssStyleSheet();

        // Apply user's chosen colors
        CssRule root = new CssRule(":root");
        root.addStyleAttribute("--primary-color", prefs.getPrimaryColor());
        root.addStyleAttribute("--accent-color", prefs.getAccentColor());
        root.addStyleAttribute("--font-family", prefs.getFontFamily());
        css.addRule(root);

        // Apply user's font size preference
        CssRule body = new CssRule("body");
        body.setFontSize(prefs.getFontSize() + "px");
        css.addRule(body);

        // Dark mode if user has it enabled
        if (prefs.isDarkMode())
        {
            CssRule darkBody = new CssRule("body");
            darkBody.setBackgroundColor("#1a1a2e");
            darkBody.setColor("#e0e0e0");
            css.addRule(darkBody);
        }

        return css;
    }
}

Cached vs. Dynamic CssFile

Use the cached constructor (super("name")) for shared styles that are the same for all users—these are built once and served from memory. Use the dynamic constructor (super()) for user-specific styles that need to be rebuilt on each request, such as themes driven by database settings.

Developer Benefits

No External CSS Files Required

Define all styles in Java. No separate CSS files to manage, no broken references, and no context switching between languages.

Type-Safe Properties

Every CSS property has a dedicated setter method or can be set with addStyleAttribute(). Your IDE provides autocomplete, and the compiler catches typos at build time.

Full Responsive Design

Build responsive layouts with CssMediaQuery. Define breakpoints, conditional rules, and adaptive designs for desktop, tablet, and mobile—all in Java.

Static or Dynamic CssFile

Extend CssFile to serve shared styles as cached resources, or generate user-specific stylesheets dynamically from database settings, preferences, or session state.

Dynamic Class Management

Add and remove CSS classes at runtime with addClass() and removeClass(). Toggle styles in event handlers for interactive, responsive UIs.

Keyframe Animations

Create CSS animations with the KeyFrames class. Define animation steps, timing functions, and durations programmatically—no raw CSS strings needed.