Tutorial

Oorian's Built-In Layout Components

Master Oorian's type-safe layout components for building responsive, well-structured user interfaces without writing CSS.

M. WarbleJanuary 21, 20265 min read
Oorian's Built-In Layout Components

Layout is fundamental to any user interface. Oorian provides a suite of layout components that leverage CSS Flexbox and Grid under the hood, but expose a simple, type-safe Java API. No CSS expertise required—just compose your layouts using intuitive Java objects.

HStack: Horizontal Layouts

The HStack component arranges children horizontally using Flexbox. It's perfect for toolbars, button groups, and horizontal navigation:

// Simple horizontal button group
HStack buttonGroup = new HStack(8);  // 8px gap between items
buttonGroup.addElement(new Button("Save"));
buttonGroup.addElement(new Button("Cancel"));
buttonGroup.addElement(new Button("Delete"));
body.addElement(buttonGroup);

// Toolbar with alignment
HStack toolbar = new HStack(16);
toolbar.setJustifyContent(JustifyContent.SPACE_BETWEEN);
toolbar.setAlignItems(AlignItems.CENTER);

HStack leftGroup = new HStack(8);
leftGroup.addElement(new Button("New"));
leftGroup.addElement(new Button("Open"));

HStack rightGroup = new HStack(8);
rightGroup.addElement(new Button("Settings"));

toolbar.addElement(leftGroup);
toolbar.addElement(rightGroup);
body.addElement(toolbar);

HStack supports all Flexbox alignment options through type-safe enums:

  • setJustifyContent(): Control horizontal distribution
  • setAlignItems(): Control vertical alignment
  • setFlexWrap(): Enable wrapping to multiple rows

VStack: Vertical Layouts

The VStack component arranges children vertically. Use it for forms, card content, and stacked elements:

// Form layout
VStack form = new VStack(16);  // 16px gap between fields

VStack nameField = new VStack(4);
nameField.addElement(new Label("Full Name"));
nameField.addElement(new TextInput().setPlaceholder("Enter your name"));
form.addElement(nameField);

VStack emailField = new VStack(4);
emailField.addElement(new Label("Email"));
emailField.addElement(new TextInput().setPlaceholder("Enter your email"));
form.addElement(emailField);

form.addElement(new Button("Submit"));
body.addElement(form);

// Card content
VStack cardContent = new VStack(12);
cardContent.setAlignItems(AlignItems.CENTER);
cardContent.addElement(new Image("/avatar.png"));
cardContent.addElement(new H3("John Doe"));
cardContent.addElement(new P("Software Engineer"));
card.addElement(cardContent);

Grid: CSS Grid Layouts

The Grid component provides full CSS Grid power with a simple API. It's ideal for card grids, dashboards, and complex layouts:

// Fixed column grid
Grid cardGrid = new Grid();
cardGrid.setColumns(3);  // Three equal columns
cardGrid.setGap(24);

for (Product product : products)
{
    cardGrid.addElement(createProductCard(product));
}
body.addElement(cardGrid);

// Auto-fit responsive grid (columns adjust to available space)
Grid autoGrid = Grid.autoFit(300);  // Minimum 300px per column
autoGrid.setGap(24);

for (Feature feature : features)
{
    autoGrid.addElement(createFeatureCard(feature));
}
body.addElement(autoGrid);

// Auto-fill grid (creates empty columns if space available)
Grid galleryGrid = Grid.autoFill(200);
galleryGrid.setGap(16);

for (Image image : gallery)
{
    galleryGrid.addElement(image);
}
body.addElement(galleryGrid);

The difference between autoFit() and autoFill():

  • autoFit: Columns stretch to fill available space when there's room
  • autoFill: Creates empty column tracks, columns stay at minimum width

For advanced layouts, use explicit templates:

// Dashboard layout with sidebar
Grid dashboard = new Grid();
dashboard.setColumnTemplate("250px 1fr");  // Fixed sidebar, fluid main
dashboard.setRowTemplate("60px 1fr 40px");  // Header, content, footer
dashboard.setGap(0);

dashboard.addElement(header);
dashboard.addElement(sidebar);
dashboard.addElement(mainContent);
dashboard.addElement(footer);
body.addElement(dashboard);

Container: Centered Content Wrapper

The Container component creates a centered, max-width wrapper. It's essential for readable content layouts:

// Standard container (default max-width)
Container page = new Container();
page.addElement(header);
page.addElement(content);
page.addElement(footer);
body.addElement(page);

// Size variants
Container narrow = Container.small();    // 640px max
Container medium = Container.medium();   // 768px max
Container large = Container.large();     // 1024px max
Container wide = Container.xl();         // 1280px max
Container extraWide = Container.xxl();   // 1536px max
Container full = Container.fluid();      // No max width

// Custom padding
Container article = Container.medium();
article.setPadding("0 24px");
article.addElement(blogPost);
body.addElement(article);

Container automatically centers itself horizontally and applies responsive padding, creating the familiar centered-content layout used by most websites.

Center: Centering Content

The Center component centers its children both horizontally and vertically. Perfect for login pages, splash screens, and centered dialogs:

// Full-page centered login
Center loginPage = new Center();
loginPage.fillViewport();  // 100vw x 100vh

VStack loginForm = new VStack(16);
loginForm.addElement(new H1("Welcome Back"));
loginForm.addElement(new TextInput().setPlaceholder("Email"));
loginForm.addElement(new PasswordInput().setPlaceholder("Password"));
loginForm.addElement(new Button("Sign In"));

loginPage.addElement(loginForm);
body.addElement(loginPage);

// Center with gap between items
Center iconAndText = new Center(8);
iconAndText.addElement(new FontAwesomeIcon("check"));
iconAndText.addElement(new Span("Success!"));

// Horizontal-only centering
Center horizontalCenter = Center.horizontal();
horizontalCenter.addElement(button);

// Vertical-only centering
Center verticalCenter = Center.vertical();
verticalCenter.addElement(content);

Spacer: Flexible Spacing

The Spacer component creates flexible or fixed space in flex layouts:

// Push items apart in a toolbar
HStack toolbar = new HStack();
toolbar.addElement(logo);
toolbar.addElement(new Spacer());  // Flexible space pushes nav to right
toolbar.addElement(navigation);

// Fixed spacing
VStack form = new VStack();
form.addElement(inputSection);
form.addElement(new Spacer(32));  // Fixed 32px space
form.addElement(buttonSection);

// Multiple spacers for even distribution
HStack tabs = new HStack();
tabs.addElement(tab1);
tabs.addElement(new Spacer());
tabs.addElement(tab2);
tabs.addElement(new Spacer());
tabs.addElement(tab3);

A flexible Spacer (no argument) expands to fill available space, while a fixed Spacer (with pixel value) creates exact spacing.

Combining Layout Components

The real power comes from combining these components:

// Complete page layout
Container page = Container.large();

// Header with logo and navigation
HStack header = new HStack();
header.setJustifyContent(JustifyContent.SPACE_BETWEEN);
header.setAlignItems(AlignItems.CENTER);
header.setPadding("16px 0");

header.addElement(new Image("/logo.png"));
HStack nav = new HStack(24);
nav.addElement(new Anchor("/features", "Features"));
nav.addElement(new Anchor("/docs", "Documentation"));
nav.addElement(new Anchor("/pricing", "Pricing"));
header.addElement(nav);
page.addElement(header);

// Hero section
Center hero = new Center();
hero.asColumn();
hero.setGap(16);
hero.setPadding("80px 0");
hero.addElement(new H1("Build Better Web Apps"));
hero.addElement(new P("The Java framework for modern web development"));
page.addElement(hero);

// Feature grid
Grid features = Grid.autoFit(280);
features.setGap(24);
for (Feature f : featureList)
{
    features.addElement(createFeatureCard(f));
}
page.addElement(features);

body.addElement(page);

Conclusion

Oorian's layout components bring the power of CSS Flexbox and Grid to Java with a clean, type-safe API. By composing HStack, VStack, Grid, Container, Center, and Spacer, you can build sophisticated responsive layouts without writing a single line of CSS. The components handle the complexity while you focus on structuring your content logically.

Related Articles

Tutorial

Oorian's Built-In Accessibility Features

January 19, 2026
Tutorial

Getting Started with Oorian: Your First Java Web Application

December 31, 2025
Deep Dive

Understanding Oorian's Flexible Communication Model

January 14, 2026