From vaadin-development
Guides building responsive Vaadin 25 layouts that adapt to screen sizes using CSS media/container queries and built-in components like AppLayout and FormLayout. For mobile-first Vaadin Flow views.
npx claudepluginhub marcushellberg/vaadin-development-plugin --plugin vaadin-developmentThis skill uses the workspace's default tool permissions.
Use the Vaadin MCP tools (`search_vaadin_docs`, `get_component_java_api`) to look up the latest documentation whenever uncertain about a specific API detail. Always set `vaadin_version` to `"25"` and `ui_language` to `"java"`.
Implements responsive layouts with container queries, fluid typography, CSS Grid, Flexbox, and mobile-first breakpoints for adaptive web interfaces across devices.
Guides responsive web design with content-first breakpoints, mobile-first prioritization, progressive disclosure, and patterns like reflow and stack for layouts from 320px to 2560px.
Implements responsive web layouts using mobile-first strategies, min-width breakpoints, fluid CSS Grid, container queries, srcset/picture images, 44x44px touch targets, and mobile-adapted tables.
Share bugs, ideas, or general feedback.
Use the Vaadin MCP tools (search_vaadin_docs, get_component_java_api) to look up the latest documentation whenever uncertain about a specific API detail. Always set vaadin_version to "25" and ui_language to "java".
Responsiveness in Vaadin means adapting the UI to best use available screen space — not just squeezing or stretching elements. The goal is to present the right amount of information and interaction for each viewport size.
Three strategies, in order of increasing effort:
Start with strategy 2 unless you have a strong reason not to.
Leverage these before writing custom responsive logic — they handle adaptation automatically:
The primary tool for viewport-based responsiveness. Define styles that activate at specific viewport widths.
/* In your view's CSS file */
.filter-panel {
display: flex;
}
@media (max-width: 640px) {
.filter-panel {
display: none;
}
}
Apply CSS class names from Java and let the CSS handle the responsive logic. This keeps responsive behavior in CSS where it belongs, rather than trying to detect screen sizes server-side.
When responsiveness should be based on a component's container width rather than the viewport. Useful for resizable panels, reusable components that appear in different contexts, and dashboard widgets.
.sidepanel {
container-type: inline-size;
container-name: sidepanel;
}
.sidepanel .footer {
display: none;
}
@container sidepanel (min-width: 400px) {
.footer {
display: flex;
}
}
Container queries make components self-contained — they adapt to their own available space rather than assuming a specific viewport size.
Vaadin's Lumo utility classes provide a mobile-first responsive system similar to Tailwind CSS. They are the fastest way to add responsive behavior without writing custom CSS.
Note: These utility classes only work with the Lumo theme. If using Aura, use CSS media queries or container queries instead (see sections above).
Setup (required in Vaadin 25):
@StyleSheet(Lumo.STYLESHEET)
@StyleSheet(Lumo.UTILITY_STYLESHEET)
@StyleSheet("styles.css")
public class Application implements AppShellConfigurator {
}
Note: Loading Lumo Utility Classes through theme.json is no longer supported in Vaadin 25. Use @StyleSheet imports instead.
Breakpoints (mobile-first):
| Breakpoint | Min width | Java constant prefix |
|---|---|---|
| (default) | 0px | LumoUtility.Display.FLEX etc. |
| Small | 640px | Display.Breakpoint.Small.* |
| Medium | 768px | Display.Breakpoint.Medium.* |
| Large | 1024px | Display.Breakpoint.Large.* |
| XLarge | 1280px | Display.Breakpoint.XLarge.* |
| XXLarge | 1536px | Display.Breakpoint.XXLarge.* |
Example — show a mobile toolbar only on small screens:
mobileToolbar.addClassNames(
LumoUtility.Display.FLEX, // visible by default (mobile)
LumoUtility.Display.Breakpoint.Small.HIDDEN // hidden at 640px+
);
Example — switch from vertical to horizontal layout at a breakpoint:
container.addClassNames(
LumoUtility.Display.FLEX,
LumoUtility.FlexDirection.COLUMN, // stack vertically (mobile)
LumoUtility.FlexDirection.Breakpoint.Medium.ROW // row at 768px+
);
The utility classes follow a mobile-first pattern: define the mobile style as the default, then override at larger breakpoints. This matches the CSS convention and produces cleaner code.
On desktop, show a filter sidebar. On mobile, hide it behind a toggle button.
// Lumo theme only — uses LumoUtility classes
// Filter panel — hidden on mobile, shown on desktop
VerticalLayout filterPanel = new VerticalLayout();
filterPanel.addClassNames(
LumoUtility.Display.HIDDEN, // hidden by default
LumoUtility.Display.Breakpoint.Medium.FLEX // shown at 768px+
);
// Toggle button — shown on mobile, hidden on desktop
Button filterToggle = new Button("Filters");
filterToggle.addClassNames(
LumoUtility.Display.INLINE_FLEX, // shown by default
LumoUtility.Display.Breakpoint.Medium.HIDDEN // hidden at 768px+
);
Use CSS Grid for a card layout that adapts its column count.
.card-grid {
display: grid;
gap: 1rem; /* or use theme token: var(--lumo-space-m) for Lumo */
grid-template-columns: 1fr; /* 1 column on mobile */
}
@media (min-width: 640px) {
.card-grid {
grid-template-columns: repeat(2, 1fr); /* 2 columns */
}
}
@media (min-width: 1024px) {
.card-grid {
grid-template-columns: repeat(3, 1fr); /* 3 columns */
}
}
Div cardGrid = new Div();
cardGrid.addClassName("card-grid");
// Add Card components to cardGrid
Use AppLayout with drawer placement. On small viewports, AppLayout automatically converts the drawer to an overlay. For full customization, combine with media queries to move navigation to a bottom bar.
Page.retrieveExtendedClientDetails() or UI.getCurrent().getPage().addBrowserWindowResizeListener() for layout decisions. CSS media/container queries are more performant and don't require a server round-trip.setWrap(true) on HorizontalLayout or flex-wrap in CSS, verify that items wrap gracefully at intermediate sizes, not just at your target breakpoints.For the complete list of Lumo utility class breakpoints and responsive constants, see references/responsive-patterns.md.