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. WarbleMarch 20, 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.

Share this article

Related Articles

Tutorial

File Uploads in Oorian

March 20, 2026
Tutorial

Oorian's Built-In Accessibility Features

January 19, 2026
Tutorial

Getting Started with Oorian

December 31, 2025