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 distributionsetAlignItems(): Control vertical alignmentsetFlexWrap(): 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.