From 349068403f031f90ae2e2c6bec735026dfaf9073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petter=20Holmstr=C3=B6m?= Date: Wed, 10 Jun 2026 15:12:01 +0300 Subject: [PATCH 1/2] Add Responsive Layouts article under building-apps/ui-basics/layouts Move the layouts overview into layouts/index.adoc and add a sibling responsive.adoc migrated from the responsive-layouts agent skill: three strategies, built-in responsive components, CSS media and container queries, and Lumo utility classes, written as an overview for humans and agents. Fix the now-relative Write HTML cross-reference broken by the move and link the overview to the new responsive article. Co-Authored-By: Claude Opus 4.8 --- .../{layouts.adoc => layouts/index.adoc} | 4 +- .../ui-basics/layouts/responsive.adoc | 189 ++++++++++++++++++ 2 files changed, 192 insertions(+), 1 deletion(-) rename articles/building-apps/ui-basics/{layouts.adoc => layouts/index.adoc} (97%) create mode 100644 articles/building-apps/ui-basics/layouts/responsive.adoc diff --git a/articles/building-apps/ui-basics/layouts.adoc b/articles/building-apps/ui-basics/layouts/index.adoc similarity index 97% rename from articles/building-apps/ui-basics/layouts.adoc rename to articles/building-apps/ui-basics/layouts/index.adoc index 66dd4234be..3ab4c0396b 100644 --- a/articles/building-apps/ui-basics/layouts.adoc +++ b/articles/building-apps/ui-basics/layouts/index.adoc @@ -260,4 +260,6 @@ Extra whitespace around content:: Disable padding and spacing on inner layouts ( A `setFlexGrow()` or alignment call does nothing:: Confirm it was called on the *parent* with the child passed as an argument, and that the layout is larger than its content along the relevant axis. -For text, headings, and semantic structure, see <>. If you're comfortable with HTML and CSS, you can also use `Div` with CSS flexbox or grid for layouts beyond what these components offer. +To adapt these layouts to different screen sizes, see <>. + +For text, headings, and semantic structure, see <<../write-html#,Write HTML>>. If you're comfortable with HTML and CSS, you can also use `Div` with CSS flexbox or grid for layouts beyond what these components offer. diff --git a/articles/building-apps/ui-basics/layouts/responsive.adoc b/articles/building-apps/ui-basics/layouts/responsive.adoc new file mode 100644 index 0000000000..00afff850b --- /dev/null +++ b/articles/building-apps/ui-basics/layouts/responsive.adoc @@ -0,0 +1,189 @@ +--- +title: Responsive Layouts +page-title: How to build responsive layouts in Vaadin +description: Learn how to adapt Vaadin layouts to different screen sizes with built-in components, CSS media and container queries, and Lumo utility classes. +meta-description: Build Vaadin views that adapt to phones, tablets, and desktops using built-in responsive components, CSS media and container queries, and Lumo utility classes. +order: 10 +--- + += Responsive Layouts +:toclevels: 2 + +A _responsive_ layout adapts to the size of the screen it's shown on, presenting the right amount of information and interaction for each device. This article covers how to make a Vaadin view work well on phones, tablets, and desktops. For the layout components themselves -- rows, columns, sizing, and alignment -- see the <> overview. + +Responsiveness is mostly a styling concern, so it's handled with CSS rather than by detecting the screen size on the server. The sections below go from the least to the most effort. + + +== Three Strategies + +There are three ways to support different screen sizes. Pick the lightest one that meets your needs: + +. *Reduce features on small screens* -- hide secondary filters, collapse panels, show fewer columns. Good when mobile is an occasional access mode. +. *Build one responsive UI* -- the same features, laid out differently per screen size. This is the recommended approach for most applications, and what the rest of this article describes. +. *Build separate UIs* -- independent mobile and desktop views. Only worth the effort when the interaction patterns differ fundamentally, such as a swipe-based mobile experience versus a data-grid desktop one. + +Start with strategy 2 unless you have a strong reason not to. + + +== Use Built-In Responsive Components First + +Several Vaadin components already adapt themselves, so check whether one fits before writing any responsive CSS: + +[cols="1,2",options="header"] +|=== +| Component | How it adapts +| <> | The navigation drawer collapses to a hamburger menu on small screens. +| <> | The widget grid adjusts its column count to the available width. +| <> | The number of columns and the label positions adjust to the width. +| <> | Items that don't fit move into an overflow menu. +| <> | Scroll buttons appear when the tabs don't fit. +| <> | Docks to the bottom of the screen on mobile. +| <> | The button row switches to vertical on narrow screens. +| <> | The editor becomes an overlay on small screens. +| <> / <> | The overlay docks to the bottom of the screen on mobile. +|=== + + +== CSS Media Queries + +A _media query_ applies a block of CSS only when the screen matches a condition, such as a maximum width. This is the primary tool for adapting to the viewport size. + +Add a class name to the component from Java, then write the responsive rules in your view's stylesheet: + +[source,java] +---- +filterPanel.addClassName("filter-panel"); +---- + +[source,css] +---- +.filter-panel { + display: flex; +} + +/* Hide the panel on screens 640px wide or narrower */ +@media (max-width: 640px) { + .filter-panel { + display: none; + } +} +---- + +For how to attach a stylesheet and apply class names from Java, see <<../add-styling#,Add Styling>>. + +To keep behavior predictable, use a consistent set of breakpoints rather than targeting specific device widths. These match Vaadin's Lumo utility classes (see below): + +[cols="1,1,1,1",options="header"] +|=== +| Breakpoint | Min width | CSS prefix | Lumo Java constant +| (default) | 0px | (none) | `LumoUtility.Display.*` +| Small | 640px | `sm:` | `*.Breakpoint.Small.*` +| Medium | 768px | `md:` | `*.Breakpoint.Medium.*` +| Large | 1024px | `lg:` | `*.Breakpoint.Large.*` +| XLarge | 1280px | `xl:` | `*.Breakpoint.XLarge.*` +| XXLarge | 1536px | `xxl:` | `*.Breakpoint.XXLarge.*` +|=== + +=== Pattern: Responsive Card Grid + +A common need is a grid of cards that shows more columns as the screen widens. CSS Grid handles this with a few media queries, and it works with any theme: + +[source,css] +---- +.card-grid { + display: grid; + gap: 1rem; + grid-template-columns: 1fr; /* one column on mobile */ +} + +@media (min-width: 640px) { + .card-grid { grid-template-columns: repeat(2, 1fr); } +} + +@media (min-width: 1024px) { + .card-grid { grid-template-columns: repeat(3, 1fr); } +} +---- + + +== CSS Container Queries + +A _container query_ adapts a component to the width of its own container rather than the whole screen. Use it for resizable panels, dashboard widgets, and reusable components that may appear in different places -- anywhere the component shouldn't assume how much space it has. + +Mark an element as a container, then query its width: + +[source,css] +---- +.side-panel { + container-type: inline-size; + container-name: side-panel; +} + +/* Show the footer only when the panel itself is at least 400px wide */ +.side-panel .footer { + display: none; +} + +@container side-panel (min-width: 400px) { + .side-panel .footer { + display: flex; + } +} +---- + +This makes a component self-contained: it adapts to the space it's given, no matter where it's placed. + + +== Lumo Utility Classes + +[NOTE] +Utility classes require the *Lumo theme*. If you use Aura, use CSS media or container queries instead, as shown above. + +If you use Lumo, its utility classes are the fastest way to add responsive behavior without writing custom CSS. They follow a _mobile-first_ pattern: the plain class sets the default (mobile) style, and a breakpoint-prefixed class overrides it on larger screens. + +Load the utility classes with `@StyleSheet` imports on your application shell: + +[source,java] +---- +@StyleSheet(Lumo.STYLESHEET) +@StyleSheet(Lumo.UTILITY_STYLESHEET) +public class Application implements AppShellConfigurator { +} +---- + +[NOTE] +If you're migrating from an older Vaadin version, note that loading utility classes through `theme.json` is no longer supported -- use the `@StyleSheet` imports shown above. + +Apply the classes from Java with `addClassNames()`. For example, to show a toolbar only on small screens: + +[source,java] +---- +mobileToolbar.addClassNames( + LumoUtility.Display.FLEX, // visible by default (mobile) + LumoUtility.Display.Breakpoint.Medium.HIDDEN); // hidden at 768px and up +---- + +Or to stack a container vertically on mobile and switch to a row on wider screens: + +[source,java] +---- +container.addClassNames( + LumoUtility.Display.FLEX, + LumoUtility.FlexDirection.COLUMN, // stacked by default (mobile) + LumoUtility.FlexDirection.Breakpoint.Medium.ROW); // side by side at 768px and up +---- + +For the full list of utility classes and their breakpoint variants, see the <> reference. + + +== Best Practices + +. *Use CSS for responsiveness, not server-side detection.* Avoid making layout decisions from `Page.retrieveExtendedClientDetails()` or a browser-resize listener -- CSS media and container queries are faster and need no server round-trip. +. *Design mobile-first.* Make the mobile layout the default and add complexity for larger screens. This matches how the Lumo breakpoints work. +. *Lean on the built-in responsive components* -- App Layout, Form Layout, Dashboard, and Menu Bar already adapt. Don't rebuild what they provide. +. *Prefer container queries for reusable components.* If a component might appear in containers of different widths, container queries make it self-adapting. +. *Design for fluid sizes, not specific devices.* Users resize windows, split screens, and zoom. Test at many widths, not just "phone" and "desktop." +. *Check wrapping at in-between sizes.* When you rely on `setWrap(true)` or CSS `flex-wrap`, verify that items wrap gracefully between your breakpoints, not only at them. + +[WARNING] +Don't add a server-side browser-resize listener to switch layouts -- it sends a request to the server on every resize. And avoid building separate mobile and desktop view classes unless the interaction patterns are genuinely different; one view with responsive CSS is far easier to maintain. From 04e03d97ec4a7276c93f262ca4a1f101b9d6bbf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petter=20Holmstr=C3=B6m?= Date: Wed, 10 Jun 2026 15:59:36 +0300 Subject: [PATCH 2/2] Make responsive-layout docs coherent and add CSS Grid Layouts article Split the why/how between designing-apps/responsiveness (design strategies and the responsive-component catalog) and the building-apps responsive layouts how-to (implementation for both Lumo and Aura), removing duplicated media/container-query and Lumo code from the design article and cross-linking the two. Add a CSS Grid Layouts article as a sibling to Responsive Layouts and link to it from the layouts overview, the responsive guide, and the design article. Fix the Lumo utility classes reference path. Co-Authored-By: Claude Opus 4.8 --- .../ui-basics/layouts/css-grid.adoc | 114 ++++++++++++++++++ .../ui-basics/layouts/index.adoc | 6 +- .../ui-basics/layouts/responsive.adoc | 37 ++---- articles/designing-apps/responsiveness.adoc | 80 ++---------- 4 files changed, 133 insertions(+), 104 deletions(-) create mode 100644 articles/building-apps/ui-basics/layouts/css-grid.adoc diff --git a/articles/building-apps/ui-basics/layouts/css-grid.adoc b/articles/building-apps/ui-basics/layouts/css-grid.adoc new file mode 100644 index 0000000000..56e707bbb5 --- /dev/null +++ b/articles/building-apps/ui-basics/layouts/css-grid.adoc @@ -0,0 +1,114 @@ +--- +title: CSS Grid Layouts +page-title: How to use CSS Grid in a Vaadin application +description: Learn how to arrange Vaadin components in two-dimensional grids using CSS Grid, including fluid card grids that wrap automatically. +meta-description: Arrange Vaadin components into rows and columns with CSS Grid, including fluid card grids that wrap automatically without media queries. +order: 20 +--- + += CSS Grid Layouts +:toclevels: 2 + +CSS Grid is a _two-dimensional_ layout system: it arranges children into rows *and* columns at the same time. Use it when the one-dimensional layouts -- `HorizontalLayout` and `VerticalLayout`, which arrange a single row or column -- aren't enough, such as for card grids or fixed page grids. For those one-dimensional layouts, see the <> overview. + +CSS Grid is plain CSS, so it works with any theme. Vaadin has no dedicated grid layout component; instead you apply grid styling to an ordinary container. + +.CSS Grid is not the Vaadin Grid component +[IMPORTANT] +This article is about _CSS Grid_, the browser layout system. It is unrelated to the Vaadin <> component, which is a data table for displaying rows of items. + + +== When to Use CSS Grid + +[cols="2,1",options="header"] +|=== +| Need | Use +| A single row or column of components | <> +| Form fields with labels | <> +| User-rearrangeable dashboard widgets | <> +| A fixed two-dimensional grid, or a card grid | CSS Grid (this article) +|=== + + +== Applying CSS Grid + +Because there's no grid layout component, add `display: grid` to a container through a CSS class, then add the components as its children -- each child becomes a cell: + +[source,java] +---- +Div productGrid = new Div(); +productGrid.addClassName("product-grid"); +productGrid.add(card1, card2, card3, card4, card5, card6); +---- + +[source,css] +---- +.product-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); /* three equal-width columns */ + gap: 1rem; /* space between cells */ +} +---- + +`1fr` is a _fraction_ of the available space, so `repeat(3, 1fr)` makes three columns that share the width equally. Rows are created automatically as items fill the columns. Use `gap` for spacing between cells rather than margins on the children. + +For how to attach a stylesheet and apply class names from Java, see <<../add-styling#,Add Styling>>. + + +[#fluid-grids-that-wrap-automatically] +== Fluid Grids That Wrap Automatically + +For a card grid that should fit as many columns as the screen allows, combine `repeat()` with `auto-fill` and `minmax()`. This adapts to the available width *without any media queries*: + +[source,css] +---- +.card-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); + gap: 1rem; +} +---- + +Each column is at least `220px` wide and grows to fill leftover space; the browser packs in as many columns as fit and wraps the rest to new rows. For most card grids this is simpler and smoother than defining breakpoints by hand. When you do need breakpoint-based changes, see <>. + + +== Spanning Multiple Cells + +A child can span several columns or rows. Add a class to the component and set `grid-column` or `grid-row`: + +[source,java] +---- +featuredCard.addClassName("featured"); +---- + +[source,css] +---- +.featured { + grid-column: span 2; /* take up two columns */ +} +---- + + +== Lumo Utility Classes + +[NOTE] +Utility classes require the *Lumo theme*. With the Aura theme, write the CSS shown above. + +If you use Lumo, you can build a grid without a separate stylesheet by applying utility classes from Java -- `LumoUtility.Display.GRID` together with the grid-column and `LumoUtility.Gap` utilities: + +[source,java] +---- +productGrid.addClassNames( + LumoUtility.Display.GRID, + LumoUtility.Gap.MEDIUM); +---- + +For the full list of grid and gap utility classes, see the <> reference. + + +== Best Practices + +. *Use CSS Grid for two-dimensional layouts only.* For a single row or column, `HorizontalLayout` or `VerticalLayout` is simpler -- see <>. +. *Prefer `auto-fill` with `minmax()` for card grids.* It wraps fluidly without media queries; reach for breakpoints only when the layout must change in a way `minmax()` can't express. +. *Use `gap` for spacing,* not margins on the children. +. *Don't confuse CSS Grid with the Vaadin `Grid` component* -- one is a layout system, the other a data table. diff --git a/articles/building-apps/ui-basics/layouts/index.adoc b/articles/building-apps/ui-basics/layouts/index.adoc index 3ab4c0396b..b2b796ee3e 100644 --- a/articles/building-apps/ui-basics/layouts/index.adoc +++ b/articles/building-apps/ui-basics/layouts/index.adoc @@ -83,14 +83,14 @@ The main area scrolls because it's wrapped in a `Scroller`. For that to work in | Single row, side by side | `HorizontalLayout` | — | Form fields with labels | `FormLayout` | A `VerticalLayout` of fields | Application shell: drawer, header, content | <> | Nested `HorizontalLayout`/`VerticalLayout` -| Grid of cards or dashboard widgets | <> or CSS Grid | Wrapped `HorizontalLayout` rows -| True two-dimensional grid (rows *and* columns) | CSS Grid | Multiple rows in a `VerticalLayout` +| Grid of cards or dashboard widgets | <> or <> | Wrapped `HorizontalLayout` rows +| True two-dimensional grid (rows *and* columns) | <> | Multiple rows in a `VerticalLayout` | Toggle horizontal/vertical at runtime | <> | Swapping between the two layouts |=== .Don't rebuild specialized components by hand [IMPORTANT] -Building an app shell out of nested layouts, or a card grid out of wrapping rows, is a common mistake that produces worse results with more code. `AppLayout` handles responsive drawers and navbar placement; `Dashboard` and CSS Grid give proper two-dimensional control and reflow. Reach for them instead. +Building an app shell out of nested layouts, or a card grid out of wrapping rows, is a common mistake that produces worse results with more code. `AppLayout` handles responsive drawers and navbar placement; `Dashboard` and <> give proper two-dimensional control and reflow. Reach for them instead. == The Two Layouts diff --git a/articles/building-apps/ui-basics/layouts/responsive.adoc b/articles/building-apps/ui-basics/layouts/responsive.adoc index 00afff850b..93462091e6 100644 --- a/articles/building-apps/ui-basics/layouts/responsive.adoc +++ b/articles/building-apps/ui-basics/layouts/responsive.adoc @@ -9,39 +9,14 @@ order: 10 = Responsive Layouts :toclevels: 2 -A _responsive_ layout adapts to the size of the screen it's shown on, presenting the right amount of information and interaction for each device. This article covers how to make a Vaadin view work well on phones, tablets, and desktops. For the layout components themselves -- rows, columns, sizing, and alignment -- see the <> overview. +A _responsive_ layout adapts to the size of the screen it's shown on, presenting the right amount of information and interaction for each device. This guide covers how to *implement* a responsive Vaadin view. For the design decisions behind responsiveness -- when to reduce features, go mobile-first, or build a separate mobile UI -- see <>. For the layout components themselves -- rows, columns, sizing, and alignment -- see the <> overview. -Responsiveness is mostly a styling concern, so it's handled with CSS rather than by detecting the screen size on the server. The sections below go from the least to the most effort. - - -== Three Strategies - -There are three ways to support different screen sizes. Pick the lightest one that meets your needs: - -. *Reduce features on small screens* -- hide secondary filters, collapse panels, show fewer columns. Good when mobile is an occasional access mode. -. *Build one responsive UI* -- the same features, laid out differently per screen size. This is the recommended approach for most applications, and what the rest of this article describes. -. *Build separate UIs* -- independent mobile and desktop views. Only worth the effort when the interaction patterns differ fundamentally, such as a swipe-based mobile experience versus a data-grid desktop one. - -Start with strategy 2 unless you have a strong reason not to. +Responsiveness is a styling concern, handled with CSS rather than by detecting the screen size on the server. The core techniques -- CSS media queries and container queries -- work with *any theme*. The Lumo theme adds utility classes as a shortcut; with the Aura theme, which has no utility classes, you use the CSS techniques directly. == Use Built-In Responsive Components First -Several Vaadin components already adapt themselves, so check whether one fits before writing any responsive CSS: - -[cols="1,2",options="header"] -|=== -| Component | How it adapts -| <> | The navigation drawer collapses to a hamburger menu on small screens. -| <> | The widget grid adjusts its column count to the available width. -| <> | The number of columns and the label positions adjust to the width. -| <> | Items that don't fit move into an overflow menu. -| <> | Scroll buttons appear when the tabs don't fit. -| <> | Docks to the bottom of the screen on mobile. -| <> | The button row switches to vertical on narrow screens. -| <> | The editor becomes an overlay on small screens. -| <> / <> | The overlay docks to the bottom of the screen on mobile. -|=== +Many Vaadin components already adapt themselves, so check whether one fits before writing any responsive CSS. For example, <> collapses its drawer to a hamburger menu, <> adjusts its column count, <> reflows its widgets, and <> moves overflowing items into a sub-menu. For the full catalog of components with built-in responsive behavior, see <>. == CSS Media Queries @@ -86,7 +61,7 @@ To keep behavior predictable, use a consistent set of breakpoints rather than ta === Pattern: Responsive Card Grid -A common need is a grid of cards that shows more columns as the screen widens. CSS Grid handles this with a few media queries, and it works with any theme: +A common need is a grid of cards that shows more columns as the screen widens. <> handles this with a few media queries, and it works with any theme: [source,css] ---- @@ -105,6 +80,8 @@ A common need is a grid of cards that shows more columns as the screen widens. C } ---- +For a card grid that wraps automatically without media queries, see <>. + == CSS Container Queries @@ -173,7 +150,7 @@ container.addClassNames( LumoUtility.FlexDirection.Breakpoint.Medium.ROW); // side by side at 768px and up ---- -For the full list of utility classes and their breakpoint variants, see the <> reference. +For the full list of utility classes and their breakpoint variants, see the <> reference. == Best Practices diff --git a/articles/designing-apps/responsiveness.adoc b/articles/designing-apps/responsiveness.adoc index ff2212dd95..d0e19b89ea 100644 --- a/articles/designing-apps/responsiveness.adoc +++ b/articles/designing-apps/responsiveness.adoc @@ -75,6 +75,7 @@ The following image demonstrates that only 75% of the height is actually availab image::images/responsiveness-browser-size.png[Height of browser content area is 697px while screen height is 900px] +[#responsive-features-in-vaadin] == Responsive Features in Vaadin Some <> have responsive features built into them. For example, the position of the <> overlay is changed to optimize for touchscreen devices. This is demonstrated in the following image, with the desktop version on the left, and the mobile version on the right. On the desktop version, the overlay shows up below the field itself. On the mobile version, the overlay is fixed to the bottom of the screen: @@ -115,7 +116,7 @@ image::images/responsiveness-native-inputs.png[Time Picker components in Vaadin, == Developing Responsive User Interfaces -The Vaadin components use standard web technologies to implement responsiveness: flexbox, grid, media queries, and container queries. You use the same technologies to make your user interfaces responsive. If you are unfamiliar with CSS, Vaadin also provides some utilities for using them. +The Vaadin components use standard web technologies to implement responsiveness: flexbox, grid, media queries, and container queries. You use the same technologies to make your user interfaces responsive, and if you are unfamiliar with CSS, the Lumo theme also provides utility classes for them. This section introduces these techniques from a design standpoint. For how to apply them in a Vaadin view -- with code for both the Lumo and Aura themes -- see <> in the Building Apps guide. === Flexbox and Grid @@ -131,83 +132,20 @@ Don't confuse the CSS grid layout system with the Vaadin <> already use flexbox and grid under the hood. This makes them easier to use even if you are not familiar with how the CSS works. If the Vaadin layout components don't fit your specific needs, you can write your own CSS or use the <>. +In Vaadin, the <> already use flexbox and grid under the hood. This makes them easier to use even if you are not familiar with how the CSS works. If the Vaadin layout components don't fit your specific needs, you can write your own CSS or use the <>. For how to build two-dimensional grids with CSS Grid in a Vaadin view, see <>. === CSS Media Query and Container Query -Media queries allow you to apply CSS styles based on the characteristics of the device that is used to access the application. When building responsive user interfaces, the most common characteristics you'll use are the width and height of the viewport. +Media queries apply CSS styles based on characteristics of the device, most commonly the width of the viewport. You use them to adapt the UI to the screen size -- for example, hiding a desktop-only toolbar on narrow screens or revealing a mobile-only one. For more information, see the https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries/Using_media_queries[MDN web docs for media queries]. -In the following example, the mobile toolbar is invisible by default. The media query overrides the styles and makes the toolbar visible when the viewport width is equal to or narrower than 640px. In practice, this means that the toolbar is hidden on non-mobile devices and visible on mobile devices: - -[source,css] ----- -.mobile-toolbar { - display: none; -} - -@media (max-width: 640px) { - .mobile-toolbar { - display: flex; - } -} ----- - -For more information, see the https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries/Using_media_queries[MDN web docs for media queries]. - -Sometimes, styling based on the viewport width isn't enough. For instance, if an application has resizable content areas, it's desirable to style the content based on the width of the content area rather than the width of the screen. Container queries allow you to do this. - -In the following example, the side panel is resizable. It has a footer that is hidden by default. The container query overrides the styles and makes the footer visible when the side panel width is equal to or wider than 400px. - -[source,css] ----- -.sidepanel { - container-type: inline-size; - container-name: sidepanel; /* Optional */ -} - -.sidepanel .footer { - display: none; -} - -@container sidepanel (min-width: 400px) { - .footer { - display: flex; - } -} ----- - -For more information, see the https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries[MDN web docs for container queries]. +Sometimes styling based on the viewport width isn't enough. If an application has resizable content areas, it's often better to style the content based on the width of the content area rather than the whole screen. Container queries allow this, so a component adapts to its own container no matter where it's placed. For more information, see the https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries[MDN web docs for container queries]. === Lumo Utility Classes -The <> are small, single-purpose CSS classes that can be applied directly to a component or HTML element to style it in a specific way. Unlike traditional CSS approaches, which often involve writing custom styles for each element, utility classes offer a more modular and reusable way to style your content. - -The responsive Lumo utility classes follow a mobile-first approach. This means that the default styles should optimize for mobile viewports. You then add extra styles for larger viewports through something called _breakpoints_. Breakpoints target various minimum screen widths. For instance, the `Small` breakpoint applies to screens that are 640px or wider, whereas the `Medium` breakpoint applies to screens that are 768px or wider. - -In the following example, the mobile toolbar is visible by default. The `Small` breakpoint makes it hidden when the viewport width is equal to or wider than 640px: - -[.example] --- -[source,html] ----- - -
----- - -[source,java] ----- - -mobileToolbar.addClassNames(Display.FLEX, Display.Breakpoint.Small.HIDDEN); ----- -.TSX -[source,html] ----- - -
----- --- +The <> are small, single-purpose CSS classes that you apply directly to a component or HTML element, offering a modular, reusable alternative to writing custom styles. The responsive utility classes follow a mobile-first approach: the default styles optimize for mobile viewports, and _breakpoints_ add styles for larger screens. For instance, the `Small` breakpoint applies to screens 640px or wider, and `Medium` to screens 768px or wider. -For more information and examples, see the blog post https://vaadin.com/blog/building-responsive-layouts-with-vaadin-utility-classes[Building responsive layouts with Vaadin utility classes]. +[NOTE] +Utility classes are specific to the Lumo theme. With the Aura theme, use CSS media and container queries instead. -// TODO The blog post contents should be incorporated into the Desiging Apps guide, maybe as a deep dive. +For the code to apply these techniques in a Vaadin view, see <>.