CSS DSL

JWeb's CSS DSL provides type-safe Java methods for all CSS properties. Write styles with IDE autocomplete and compile-time validation.

Import Statements

// Core CSS DSL
import static com.osmig.Jweb.framework.styles.CSS.*;

// Units (px, rem, em, vh, vw, etc.)
import static com.osmig.Jweb.framework.styles.CSSUnits.*;

// Colors (named colors, rgb, hex, etc.)
import static com.osmig.Jweb.framework.styles.CSSColors.*;

Inline Styles

Apply styles directly to elements using the style builder.

// Lambda syntax (recommended)
div(attrs()
    .class_("card")
    .style(s -> s
        .padding(rem(1.5))
        .backgroundColor(white)
        .borderRadius(px(8))
        .boxShadow(px(0), px(2), px(8), rgba(0, 0, 0, 0.1))
    ),
    content
)

// Reusable Style object
Style cardStyle = style()
    .padding(rem(1.5))
    .backgroundColor(white)
    .borderRadius(px(8));

div(attrs().style(cardStyle), content)

CSS Rules

Generate CSS rules for stylesheets.

// Single rule
String buttonCss = rule(".btn")
    .display(inlineBlock)
    .padding(px(10), px(20))
    .backgroundColor(blue)
    .color(white)
    .borderRadius(px(4))
    .render();

// Multiple rules
String css = styles(
    rule("*").boxSizing(borderBox),
    rule("body")
        .margin(zero)
        .fontFamily("system-ui, -apple-system, sans-serif"),
    rule(".container")
        .maxWidth(px(1200))
        .margin(px(0), auto)
        .padding(px(0), rem(1))
);

CSS Units

Type-safe unit functions prevent invalid CSS values.

// Absolute units
px(10)              // 10px - pixels
px(15.5)            // 15.5px - decimal pixels

// Relative units (recommended)
rem(1)              // 1rem - relative to root font-size
rem(1.5)            // 1.5rem
em(1.2)             // 1.2em - relative to parent font-size
percent(50)         // 50%
percent(33.33)      // 33.33%

// Viewport units
vh(100)             // 100vh - viewport height
vw(50)              // 50vw - viewport width
vmin(10)            // 10vmin - smaller of vw/vh
vmax(20)            // 20vmax - larger of vw/vh

// Dynamic viewport (mobile-safe)
dvh(100)            // 100dvh - accounts for mobile browser chrome
dvw(100)            // 100dvw

// Grid units
fr(1)               // 1fr - fraction of available space
fr(2)               // 2fr - 2 fractions

// Time (for animations)
ms(300)             // 300ms - milliseconds
s(0.3)              // 0.3s - seconds

// Angles (for transforms)
deg(45)             // 45deg - degrees
turn(0.5)           // 0.5turn - half rotation

CSS Functions

Mathematical functions for dynamic values.

// calc() - calculations
.width(calc("100% - 200px"))
.height(calc("100vh - 60px"))

// min() - smallest value
.width(min(px(400), percent(100)))

// max() - largest value
.width(max(px(300), percent(50)))

// clamp() - value within range
.fontSize(clamp(rem(1), vw(4), rem(2)))
// Font scales between 1rem and 2rem based on viewport

// Example: responsive container
.maxWidth(min(px(1200), calc("100% - 2rem")))
.padding(clamp(rem(1), vw(5), rem(3)))

Common Constants

Pre-defined values for common CSS keywords.

zero                // 0
auto                // auto
inherit             // inherit
initial             // initial
unset               // unset
none                // none

// Usage
.margin(zero)
.width(auto)
.display(none)

Colors

Multiple color formats with full type safety.

// Hex colors
hex("#6366f1")           // 6-digit hex
hex("#f5f")              // 3-digit hex shorthand

// RGB/RGBA
rgb(99, 102, 241)        // RGB values 0-255
rgba(0, 0, 0, 0.5)       // RGBA with alpha 0-1

// HSL/HSLA
hsl(239, 84, 67)         // hue, saturation%, lightness%
hsla(239, 84, 67, 0.8)   // with alpha

// Named colors
white, black, red, blue, green, yellow,
gray, transparent, currentColor, inherit

Using Colors

.color(hex("#1e293b"))
.backgroundColor(rgba(255, 255, 255, 0.9))
.borderColor(hex("#e2e8f0"))

// Gradients
.background(linearGradient(deg(135),
    hex("#667eea"), hex("#764ba2")))

.background(radialGradient(circle,
    hex("#fff"), hex("#f0f0f0")))

Creating a Color Palette

public final class Colors {
    public static final CSSValue PRIMARY = hex("#6366f1");
    public static final CSSValue PRIMARY_DARK = hex("#4f46e5");
    public static final CSSValue SECONDARY = hex("#ec4899");
    public static final CSSValue SUCCESS = hex("#10b981");
    public static final CSSValue WARNING = hex("#f59e0b");
    public static final CSSValue ERROR = hex("#ef4444");
    public static final CSSValue TEXT = hex("#1e293b");
    public static final CSSValue TEXT_LIGHT = hex("#64748b");
    public static final CSSValue BG = hex("#ffffff");
    public static final CSSValue BG_MUTED = hex("#f8fafc");
}

Box Model

Control dimensions, spacing, and borders.

// Dimensions
.width(px(300))
.height(px(200))
.minWidth(px(200))
.maxWidth(px(800))
.minHeight(px(100))
.maxHeight(px(600))

// Size shorthand
.size(px(100))                  // width & height
.size(px(200), px(100))         // width, height

Margin

External spacing around elements.

// All sides
.margin(rem(1))

// Vertical, horizontal
.margin(rem(1), rem(2))

// Top, horizontal, bottom
.margin(rem(1), rem(2), rem(1))

// Top, right, bottom, left
.margin(rem(1), rem(2), rem(1), rem(2))

// Individual sides
.marginTop(rem(1))
.marginRight(rem(2))
.marginBottom(rem(1))
.marginLeft(rem(2))

// Horizontal/vertical shortcuts
.marginX(rem(2))                // left & right
.marginY(rem(1))                // top & bottom

// Centering
.margin(zero, auto)             // Horizontal center

Padding

Internal spacing inside elements.

// All sides
.padding(rem(1))

// Vertical, horizontal
.padding(rem(1), rem(2))

// Individual sides
.paddingTop(rem(1))
.paddingRight(rem(2))
.paddingBottom(rem(1))
.paddingLeft(rem(2))

// Horizontal/vertical shortcuts
.paddingX(rem(2))               // left & right
.paddingY(rem(1))               // top & bottom

Border

Element borders with various styles.

// Full border
.border(px(1), solid, gray)

// Individual properties
.borderWidth(px(2))
.borderStyle(solid)
.borderColor(blue)

// Individual sides
.borderTop(px(1), solid, black)
.borderBottom(px(2), dashed, gray)
.borderLeft(px(1), solid, black)
.borderRight(px(1), solid, black)

// Border styles
solid, dashed, dotted, double, none

// Border radius
.borderRadius(px(8))
.borderRadius(px(8), px(4), px(8), px(4))  // corners
.borderTopLeftRadius(px(16))
.borderTopRightRadius(px(16))

// Presets
.roundedNone()      // 0
.roundedSm()        // 4px
.roundedMd()        // 6px
.roundedLg()        // 8px
.roundedXl()        // 12px
.roundedFull()      // 9999px (pill/circle)

Box Sizing

Control how dimensions are calculated.

// Include padding/border in width/height
.boxSizing(borderBox)

// Exclude padding/border (default)
.boxSizing(contentBox)

// Best practice: apply to all elements
rule("*").boxSizing(borderBox)

Display

Control element rendering.

.display(block)
.display(inline)
.display(inlineBlock)
.display(flex)
.display(grid)
.display(none)

// Visibility (keeps space)
.visibility(visible)
.visibility(hidden)

// Overflow
.overflow(hidden)
.overflow(auto)
.overflow(scroll)
.overflowX(auto)
.overflowY(scroll)

Flexbox

Flexible box layout for one-dimensional layouts.

// Basic flex container
.display(flex)
.flexDirection(row)      // row, column, rowReverse, columnReverse
.justifyContent(center)  // start, end, center, spaceBetween, spaceAround
.alignItems(center)      // start, end, center, stretch, baseline
.gap(rem(1))

Common Flex Patterns

// Center content horizontally and vertically
Style centered = style()
    .display(flex)
    .justifyContent(center)
    .alignItems(center)
    .minHeight(vh(100));

// Horizontal navigation
Style nav = style()
    .display(flex)
    .gap(rem(2))
    .alignItems(center);

// Space between (logo left, nav right)
Style header = style()
    .display(flex)
    .justifyContent(spaceBetween)
    .alignItems(center)
    .padding(rem(1), rem(2));

// Vertical stack
Style stack = style()
    .display(flex)
    .flexDirection(column)
    .gap(rem(1));

Flex Item Properties

// Flex item sizing
.flexGrow(1)       // grow to fill space
.flexShrink(0)     // don't shrink
.flexBasis(px(200)) // initial size
.flex(1)           // shorthand: grow shrink basis

// Self alignment
.alignSelf(flexEnd)

CSS Grid

Two-dimensional grid layout system.

// Basic grid
.display(grid)
.gridTemplateColumns(repeat(3, fr(1)))  // 3 equal columns
.gridTemplateRows(auto)
.gap(rem(2))

Grid Column Patterns

// Fixed columns
.gridTemplateColumns(px(200), px(200), px(200))

// Flexible columns
.gridTemplateColumns(fr(1), fr(2), fr(1))  // 1:2:1 ratio

// Auto-fit responsive grid
.gridTemplateColumns(repeat(autoFit, minmax(px(250), fr(1))))

// Mixed
.gridTemplateColumns(px(250), fr(1), px(300))  // sidebar, content, aside

Grid Areas

// Define areas
.gridTemplateAreas(
    "header header header",
    "sidebar content aside",
    "footer footer footer"
)
.gridTemplateRows(auto, fr(1), auto)
.gridTemplateColumns(px(200), fr(1), px(200))

// Place items in areas
.gridArea("header")
.gridArea("sidebar")
.gridArea("content")

Grid Item Placement

// Span columns/rows
.gridColumn("span 2")
.gridRow("span 3")

// Explicit placement
.gridColumnStart(1)
.gridColumnEnd(3)
.gridRowStart(1)
.gridRowEnd(2)

Typography

Font and text styling properties.

// Font family
.fontFamily("Inter, system-ui, sans-serif")
.fontFamily("'Fira Code', monospace")

// Font size
.fontSize(rem(1.125))
.fontSize(px(18))

// Font weight
.fontWeight(400)     // normal
.fontWeight(600)     // semi-bold
.fontWeight(700)     // bold

// Line height
.lineHeight(1.6)     // unitless multiplier
.lineHeight(px(24))  // explicit value

// Letter spacing
.letterSpacing(px(-0.5))
.letterSpacing(em(0.05))

Text Properties

// Text alignment
.textAlign(center)   // left, center, right, justify

// Text decoration
.textDecoration(none)
.textDecoration(underline)

// Text transform
.textTransform(uppercase)
.textTransform(capitalize)

// Text overflow
.overflow(hidden)
.textOverflow(ellipsis)
.whiteSpace(nowrap)

// Word wrapping
.wordBreak(breakWord)
.overflowWrap(breakWord)

Font Presets

public final class Typography {
    public static final CSSValue TEXT_XS = rem(0.75);
    public static final CSSValue TEXT_SM = rem(0.875);
    public static final CSSValue TEXT_BASE = rem(1);
    public static final CSSValue TEXT_LG = rem(1.125);
    public static final CSSValue TEXT_XL = rem(1.25);
    public static final CSSValue TEXT_2XL = rem(1.5);
    public static final CSSValue TEXT_3XL = rem(1.875);
}

Visual Effects

Shadows, filters, transforms, and transitions.

Box Shadow

// Basic shadow
.boxShadow(px(0), px(4), px(6), rgba(0, 0, 0, 0.1))
//         x-offset, y-offset, blur, color

// With spread
.boxShadow(px(0), px(4), px(6), px(2), rgba(0, 0, 0, 0.1))
//         x, y, blur, spread, color

// String syntax
.boxShadow("0 4px 6px rgba(0,0,0,0.1)")

// Presets
.shadowXs()         // Subtle shadow
.shadowSm()         // Small shadow
.shadow()           // Default shadow
.shadowMd()         // Medium shadow
.shadowLg()         // Large shadow
.shadowXl()         // Extra large shadow
.shadowInner()      // Inset shadow
.shadowNone()       // No shadow

Transforms

2D and 3D transformations.

// Translate (move)
.transform(translateX(px(10)))
.transform(translateY(px(20)))
.transform(translate(px(10), px(20)))

// Rotate
.transform(rotate(deg(45)))
.transform(rotate(turn(0.25)))  // Quarter turn

// Scale
.transform(scale(1.2))          // Uniform
.transform(scale(2, 0.5))       // Non-uniform
.transform(scaleX(1.5))
.transform(scaleY(0.8))

// Skew
.transform(skewX(deg(10)))
.transform(skewY(deg(10)))

// Multiple transforms
.transform(translateY(px(-4)), scale(1.05))

// Transform origin
.transformOrigin("center center")
.transformOrigin("top left")

Transitions

Animate property changes.

// Simple transition
.transition(propAll, s(0.3), ease)
//          property, duration, timing

// Specific property
.transition(propColor, s(0.2))
.transition(propBackground, s(0.3), easeInOut)
.transition(propTransform, s(0.2), easeOut)

// Multiple properties
.transition("color 0.2s, background 0.3s, transform 0.2s")

// Individual settings
.transitionProperty(propAll)
.transitionDuration(s(0.3))
.transitionTimingFunction(easeInOut)
.transitionDelay(ms(100))

// Timing functions
ease, linear, easeIn, easeOut, easeInOut

// Custom bezier
.transitionTimingFunction(cubicBezier(0.4, 0, 0.2, 1))

Filters

Image and element filters.

// Blur
.filter(blur(px(5)))

// Brightness (1 = normal)
.filter(brightness(1.2))

// Contrast
.filter(contrast(1.5))

// Grayscale
.filter(grayscale(percent(100)))

// Opacity filter
.filter(opacity(percent(50)))

// Saturate
.filter(saturate(percent(200)))

// Sepia
.filter(sepia(percent(100)))

// Drop shadow (for transparent images)
.filter(dropShadow(px(2), px(4), px(6), rgba(0, 0, 0, 0.3)))

// Multiple filters
.filter("blur(5px) brightness(1.1)")

Backdrop Filter

Filter the area behind an element (for glass effects).

// Frosted glass effect
.backgroundColor(rgba(255, 255, 255, 0.7))
.backdropFilter(blur(px(10)))

// Glass card
style()
    .backgroundColor(rgba(255, 255, 255, 0.2))
    .backdropFilter(blur(px(20)))
    .borderRadius(px(16))
    .border(px(1), solid, rgba(255, 255, 255, 0.3))

Opacity

.opacity(1)         // Fully visible
.opacity(0.5)       // Half transparent
.opacity(0)         // Invisible

Cursor & Interaction

// Cursor styles
.cursor(pointer)    // Hand cursor (clickable)
.cursor(notAllowed) // Disabled cursor
.cursor(grab)       // Grab cursor
.cursor(text)       // Text selection cursor

// Disable interactions
.pointerEvents(none)  // Click-through
.userSelect(none)     // No text selection

Media Queries

Create responsive designs that adapt to screen sizes.

// Basic breakpoint
media().minWidth(px(768)).rules(
    rule(".container").maxWidth(px(720))
)

// Combined conditions
media().screen().minWidth(px(1024)).maxWidth(px(1280)).rules(
    rule(".sidebar").display(none)
)

// Common breakpoints (presets)
xs()        // max-width: 575px
sm()        // min-width: 576px
md()        // min-width: 768px
lg()        // min-width: 992px
xl()        // min-width: 1200px
xxl()       // min-width: 1400px

// Device presets
mobile()    // max-width: 767px
tablet()    // 768px - 1023px
desktop()   // min-width: 1024px

Responsive Example

String css = styles(
    // Base styles (mobile-first)
    rule(".grid")
        .display(grid)
        .gridTemplateColumns(fr(1))
        .gap(rem(1)),

    // Tablet and up
    media().minWidth(px(768)).rules(
        rule(".grid").gridTemplateColumns(fr(1), fr(1))
    ),

    // Desktop
    media().minWidth(px(1024)).rules(
        rule(".grid").gridTemplateColumns(fr(1), fr(1), fr(1))
    )
);

Dark Mode

Support dark color scheme.

// Detect system preference
media().prefersDark().rules(
    rule(":root")
        .set("--bg-color", "#1a1a1a")
        .set("--text-color", "#f5f5f5"),
    rule("body")
        .backgroundColor(var("bg-color"))
        .color(var("text-color"))
)

// lightDark() function
.backgroundColor(lightDark(white, hex("#1a1a1a")))
.color(lightDark(black, white))

Accessibility Queries

// Reduced motion (accessibility)
media().prefersReducedMotion().rules(
    rule("*")
        .animationDuration(ms(0))
        .transitionDuration(ms(0))
)

// High contrast
media().prefersContrast("more").rules(
    rule("*").borderWidth(px(2))
)

Orientation & Features

// Portrait/landscape
media().portrait().rules(...)
media().landscape().rules(...)

// Hover capability
media().hover().rules(
    rule(".card:hover").transform(translateY(px(-4)))
)

media().noHover().rules(
    // Styles for touch devices without hover
)

// Retina displays
media().retina().rules(
    rule(".logo").backgroundImage(url("/logo@2x.png"))
)

// Print styles
media().print().rules(
    rule(".no-print").display(none),
    rule("body").fontSize(pt(12))
)

Container Queries

Style based on container size, not viewport.

// Define container
rule(".card-container")
    .containerType(inlineSize)
    .containerName("card")

// Query the container
container("card").minWidth(px(400)).rules(
    rule(".card")
        .display(grid)
        .gridTemplateColumns(fr(1), fr(2))
)

// Inline container query in style
style()
    .containerType(inlineSize)
    // Children can use @container queries

Keyframe Animations

Create custom CSS animations.

import static com.osmig.Jweb.framework.styles.CSSAnimations.*;

// Define keyframes
String fadeInKeyframes = keyframes("fadeIn")
    .from(style().opacity(0))
    .to(style().opacity(1))
    .build();

// Multi-step animation
String bounceKeyframes = keyframes("bounce")
    .at(0, style().transform(translateY(zero)))
    .at(50, style().transform(translateY(px(-20))))
    .at(100, style().transform(translateY(zero)))
    .build();

Using Animations

// Apply animation to element
.animation(animName("fadeIn"), s(1), ease)
//          name, duration, timing

// With all options
.animationName(animName("bounce"))
.animationDuration(s(2))
.animationTimingFunction(easeInOut)
.animationDelay(ms(500))
.animationIterationCount(iterationInfinite)
.animationDirection(directionAlternate)
.animationFillMode(fillModeForwards)

// Shorthand
.animation("fadeIn 0.5s ease-out forwards")

Pre-built Animations

40+ ready-to-use animations.

// Fade animations
fadeIn(s(0.5))
fadeOut(s(0.3))
fadeInUp(s(0.6))
fadeInDown(s(0.6))
fadeInLeft(s(0.6))
fadeInRight(s(0.6))

// Slide animations
slideInLeft(s(0.5))
slideInRight(s(0.5))
slideInUp(s(0.5))
slideInDown(s(0.5))
slideOutLeft(s(0.3))
slideOutRight(s(0.3))

// Scale animations
zoomIn(s(0.5))
zoomOut(s(0.5))
scaleIn(s(0.5))
pulse(s(1.5))
heartbeat(s(1))

// Bounce animations
bounce(s(1))
bounceIn(s(0.8))
bounceOut(s(0.8))

// Rotate animations
rotate360(s(2))
rotateIn(s(1))
flipX(s(1))
flipY(s(1))

// Attention seekers
shake(s(0.5))
wobble(s(1))
jello(s(1))
swing(s(1))
rubberBand(s(1))
flash(s(0.5))
tada(s(1))

Animation Usage

// Style with pre-built animation
style()
    .animation(fadeIn(s(0.5)))

// With modifiers
style()
    .animation(
        slideInUp(s(0.6))
            .delay(ms(200))
            .timing(easeOut)
    )

// Infinite animation
style()
    .animation(
        pulse(s(1.5))
            .iterations(infinite)
    )

// Chained animation
style()
    .animation(
        fadeInUp(s(0.5))
            .then(bounce(s(0.3)))  // After first completes
    )

Timing Functions

// Standard easing
timingEase           // Default easing
timingLinear         // Constant speed
timingEaseIn         // Slow start
timingEaseOut        // Slow end
timingEaseInOut      // Slow start and end

// Custom bezier curve
timingCubicBezier(0.4, 0, 0.2, 1)

// Steps (frame-by-frame)
timingSteps(5, "end")
timingStepStart
timingStepEnd

Animation State

// Pause/play
.animationPlayState(playStatePaused)
.animationPlayState(playStateRunning)

// Fill mode (final state)
.animationFillMode(fillModeForwards)  // Keep end state
.animationFillMode(fillModeBackwards) // Apply start before delay
.animationFillMode(fillModeBoth)      // Both

// Direction
.animationDirection(directionNormal)
.animationDirection(directionReverse)
.animationDirection(directionAlternate)
Use prefers-reduced-motion media query to disable animations for users who prefer reduced motion.

CSS Variables

Use CSS custom properties for theming and design tokens.

import static com.osmig.Jweb.framework.styles.CSSVariables.*;

// Define variables in :root
rule(":root")
    .var("primary-color", hex("#6366f1"))
    .var("secondary-color", hex("#8b5cf6"))
    .var("text-color", hex("#1f2937"))
    .var("bg-color", white)
    .var("spacing-sm", rem(0.5))
    .var("spacing-md", rem(1))
    .var("spacing-lg", rem(2))
    .var("radius", px(8))

Using Variables

// Reference variable
.color(var("primary-color"))
.padding(var("spacing-md"))
.borderRadius(var("radius"))

// With fallback value
.color(var("accent-color", blue))

// Chained fallback
.color(varChain("custom-color", "primary-color", blue))

Component Example

// Button using variables
rule(".btn")
    .padding(var("spacing-sm"), var("spacing-md"))
    .backgroundColor(var("primary-color"))
    .color(white)
    .borderRadius(var("radius"))
    .transition(propBackground, s(0.2))

rule(".btn:hover")
    .backgroundColor(var("secondary-color"))

// Card using variables
rule(".card")
    .padding(var("spacing-lg"))
    .backgroundColor(var("bg-color"))
    .color(var("text-color"))
    .borderRadius(var("radius"))

Dark Mode with Variables

// Light theme (default)
rule(":root")
    .var("bg-color", white)
    .var("text-color", hex("#1f2937"))
    .var("border-color", hex("#e5e7eb"))

// Dark theme
media().prefersDark().rules(
    rule(":root")
        .var("bg-color", hex("#1f2937"))
        .var("text-color", hex("#f9fafb"))
        .var("border-color", hex("#374151"))
)

// Components automatically adapt
rule("body")
    .backgroundColor(var("bg-color"))
    .color(var("text-color"))

rule(".card")
    .border(px(1), solid, var("border-color"))

Design System Builder

// Generate design tokens
String tokens = designSystem()
    .spacing(rem(0.25), rem(0.5), rem(1), rem(1.5), rem(2), rem(3))
    .colors(
        "primary", hex("#6366f1"),
        "secondary", hex("#8b5cf6"),
        "success", hex("#10b981"),
        "warning", hex("#f59e0b"),
        "error", hex("#ef4444")
    )
    .fontSize(
        rem(0.75),   // xs
        rem(0.875),  // sm
        rem(1),      // base
        rem(1.125),  // lg
        rem(1.25),   // xl
        rem(1.5)     // 2xl
    )
    .build();

// Generates:
// --spacing-1: 0.25rem;
// --spacing-2: 0.5rem;
// --color-primary: #6366f1;
// --font-size-1: 0.75rem;
// etc.

Theme Builder

// Build light and dark themes together
String themes = theme()
    .light(
        "background", white,
        "surface", hex("#f9fafb"),
        "text", hex("#1f2937"),
        "text-muted", hex("#6b7280")
    )
    .dark(
        "background", hex("#111827"),
        "surface", hex("#1f2937"),
        "text", hex("#f9fafb"),
        "text-muted", hex("#9ca3af")
    )
    .buildBoth();

// Generates :root styles and @media (prefers-color-scheme: dark)
CSS variables cascade and can be overridden at any level. Define global variables in :root and override in component classes as needed.

Modern CSS Features

Cutting-edge CSS features for positioning, scrolling, text, grids, masking, and logical layout.

Anchor Positioning

Position elements relative to an anchor element without JavaScript.

import static com.osmig.Jweb.framework.styles.CSSAnchorPositioning.*;

// Define an anchor
rule(".trigger").prop(anchorName("--tooltip-anchor"))

// Position relative to anchor using position-area
rule(".tooltip")
    .prop(positionAnchor("--tooltip-anchor"))
    .prop(positionArea("top"))
    .position(absolute)

// Using anchor() function for fine-grained control
rule(".popup")
    .prop(top(anchor("--btn", "bottom")))
    .prop(left(anchor("--btn", "left")))

// Fallback positioning (try top, then bottom)
rule(".dropdown")
    .prop(positionAnchor("--menu"))
    .prop(positionTryFallbacks("flip-block", "flip-inline"))

// Convenience: position above/below/left/right
rule(".tip")
    .prop(positionAnchor("--target"))
    .prop(positionAbove())    // shorthand for positionArea("top")
rule(".sub")
    .prop(positionAnchor("--target"))
    .prop(positionBelow())    // shorthand for positionArea("bottom")

Scroll Snap

Control scroll behavior to snap to specific elements.

import static com.osmig.Jweb.framework.styles.CSSScrollSnap.*;

// Horizontal carousel
rule(".carousel")
    .prop(snapTypeX("mandatory"))    // snap on X axis
    .prop(snapPadding("0 20px"))     // padding at snap edges
    .overflowX(auto)

rule(".carousel-item")
    .prop(snapAlignCenter())         // snap to center
    .prop(snapStopAlways())          // always stop at each item

// Vertical page snap
rule(".page-container")
    .prop(snapTypeY("proximity"))    // snap when close
    .overflowY(scroll)
    .height("100vh")

rule(".page-section")
    .prop(snapAlignStart())
    .height("100vh")

// Overscroll behavior
rule(".panel")
    .prop(overscrollBehaviorY("contain"))  // prevent parent scroll

Text Wrapping

Modern text wrapping and truncation controls.

import static com.osmig.Jweb.framework.styles.CSSTextWrap.*;

// Balanced line lengths (great for headings)
rule("h1, h2").prop(textWrapBalance())

// Better orphan/widow handling (for body text)
rule("p").prop(textWrapPretty())

// Truncate to N lines with ellipsis
rule(".preview").prop(lineClamp(3))
// Shows max 3 lines, then "..."

// Prevent wrapping
rule(".nowrap").prop(textWrapNowrap())

// Word breaking
rule(".long-urls").prop(wordBreakAll())        // break anywhere
rule(".cjk").prop(wordBreakKeepAll())          // keep CJK together
rule(".overflow").prop(overflowWrapBreakWord()) // break on overflow

// Hyphenation
rule(".article").prop(hyphensAuto())

// Text overflow
rule(".ellipsis").prop(textOverflowEllipsis())

Subgrid

Inherit parent grid tracks in nested grids.

import static com.osmig.Jweb.framework.styles.CSSSubgrid.*;

// Parent grid
rule(".card-grid")
    .display("grid")
    .prop(gridTemplateColumns("repeat(3, 1fr)"))
    .gap(rem(1))

// Child inherits parent columns
rule(".card")
    .display("grid")
    .prop(subgridColumns())    // grid-template-columns: subgrid

// Inherit both axes
rule(".full-child")
    .display("grid")
    .prop(subgridBoth())       // columns and rows from parent

// Named line references
rule(".named-child")
    .display("grid")
    .prop(subgridColumnsNamed("[start] [end]"))

// Grid placement helpers
rule(".span-all")
    .prop(gridColumnFull())    // grid-column: 1 / -1

Masking and Clipping

Apply masks and clip paths for creative shapes.

import static com.osmig.Jweb.framework.styles.CSSMasking.*;

// Mask with image
rule(".masked").prop(maskImage("url(mask.svg)"))
               .prop(maskMode("alpha"))

// Clip to circle
rule(".avatar").prop(clipCircle("50%"))

// Clip to ellipse
rule(".oval").prop(clipEllipse("50%", "40%"))

// Clip to polygon
rule(".arrow").prop(clipPolygon(
    "50% 0%", "100% 100%", "0% 100%"))

// Preset shapes
rule(".diamond").prop(clipDiamond())
rule(".pentagon").prop(clipPentagon())
rule(".hexagon").prop(clipHexagon())
rule(".star").prop(clipStar())
rule(".tri-up").prop(clipTriangleUp())
rule(".tri-down").prop(clipTriangleDown())

// SVG path clipping
rule(".custom").prop(clipSvgPath("M0,0 L100,0 L50,100 Z"))

Logical Properties

Direction-aware properties that adapt to RTL/LTR and writing modes.

import static com.osmig.Jweb.framework.styles.CSSLogicalProperties.*;

// Sizing (replaces width/height)
rule(".box")
    .prop(inlineSize("300px"))       // width in LTR
    .prop(blockSize("200px"))        // height in LTR
    .prop(maxInlineSize("100%"))

// Margin (replaces margin-left/right/top/bottom)
rule(".centered")
    .prop(marginInline("auto"))       // horizontal center
    .prop(marginBlock("1rem"))        // vertical margin

// Start/end for asymmetric spacing
rule(".indent")
    .prop(marginInlineStart("2rem"))  // left in LTR, right in RTL
    .prop(paddingInlineEnd("1rem"))

// Padding
rule(".card")
    .prop(paddingInline("1.5rem"))    // horizontal padding
    .prop(paddingBlock("1rem"))       // vertical padding

// Borders
rule(".highlighted")
    .prop(borderInlineStart("3px solid blue"))  // left border in LTR
    .prop(borderBlock("1px solid gray"))

// Inset (replaces top/right/bottom/left)
rule(".overlay")
    .prop(insetInline("0"))           // left: 0; right: 0
    .prop(insetBlock("0"))            // top: 0; bottom: 0

// Text alignment
rule(".start-aligned").prop(textAlignStart())  // left in LTR
rule(".end-aligned").prop(textAlignEnd())      // right in LTR
Anchor Positioning and Subgrid are newer CSS features. Check browser support on caniuse.com. Logical properties are well-supported and recommended for all new projects to enable RTL support.