The hierarchy
Parent-child relationships
Every page or view you build in Bubble is made up of a hierarchy of parent-child relationships. The page (or view, if you're building for native mobile) is the parent of every element on it. Inside that page, you can place containers, elements that hold other elements and become the parent of whatever's inside them.
For example, if you group a set of input fields and a button together, that group is the parent, and the input fields and button are its children.
Containers can also contain other containers, which makes the outer one the parent of the inner one. You can nest as many levels of this parent-child relationship as your design needs. This structure is the foundation of responsive design in Bubble: how a page or view rearranges itself as the screen size changes.
We explain the element hierarchy in general and in more detail in the article below:
Article:The element hierarchy
How parent and child settings work together
Setting up responsive behavior means combining two sets of settings: the ones on the parent container, and the ones on the element itself.
If an element sits directly on the page, the page is its parent container. If it sits inside a group or other container, that container's settings apply to it instead.
The settings on the parent container decide how its children are positioned relative to the container and to each other. This includes whether children stack vertically or line up horizontally, how the overall layout is aligned within the container, and how much space sits between children.
The settings on the child element decide how that specific element behaves: how tall or wide it should be, and how much space it keeps around itself (margin) or inside itself (padding).
Together, these two layers of settings give you precise control over how a design adapts to any screen.
Container layout modes
Every container, including the page itself, has a layout setting in the Layout tab of the property editor. This setting acts like a set of instructions, telling every element inside the container how to position itself.
Where an element ends up depends on three things:
The layout mode of the parent container
The settings on the element itself
The settings and position of its sibling elements (the other elements inside the same container)
There are four layout modes available on container elements:
Layout mode | What it does |
Column | Stacks children vertically. |
Row | Arranges children horizontally, side by side. |
Align to parent | Positions children in one of nine fixed positions within the container. |
Fixed | Places each child at a specific position, without automatic layout logic. |
Column
Column layout stacks child elements on top of each other, regardless of how wide each one is.
If a container's height is set to fit its content, that height adjusts automatically as elements are added or made visible. For this to work as expected, you'll need to set a minimum and maximum height on the container.
New child elements are added to the bottom of the column by default, but you can reorder them using the Order controls in the element property editor's Layout section or by dragging and dropping on the canvas directly or in the element tree.
When column layout is useful
Column layouts are useful when you need to stack elements vertically (on top of or underneath each other).
Sidebar menus. Navigation menus that run down the left or right side of a page (like the one in this documentation).
Social media feeds. Scrolling timelines of posts, like LinkedIn, Facebook and Instagram.
Forms. Input fields, labels, and buttons stacked vertically so users can fill them out top to bottom.
Product listings. A vertical list of items, each with an image, title, and description.
Chat messages. Conversation threads where messages stack chronologically.
Inboxes. A list of incoming messages or tasks.
Row
Row layout lines up child elements horizontally, one after another. As the screen resizes or the total width of the elements exceeds the container's width, the elements wrap onto the next line.
New child elements are added to the end of the row by default, but you can reorder them using the Order controls in the element property editor's Layout section or by dragging and dropping on the canvas directly or in the element tree..
When row layout is useful
Row layouts are useful when you need to arrange elements horizontally (side by side).
Top/bottom navigation bars. Menu items and buttons lined up across the top or bottom of a page.
Product grids. Items arranged in columns that wrap to multiple rows as the screen gets narrower.
Button groups. Multiple buttons or actions sitting next to each other.
Card layouts. A horizontal row of cards that users can scroll through.
Header information. An icon, title, and metadata aligned horizontally at the top of a card or section.
Tabbed interfaces. Tab labels lined up horizontally so users can switch between sections.
Align to parent
Align to parent divides the parent container into a nine-cell grid and lets you align child elements to any of those cells: upper-left, upper-middle, upper-right, and so on.
When you create a new child element or drag one in, it automatically snaps to the nearest cell.
You can also set its position directly from the property editor, where each of nine arrows represents one of the cells.
Overlapping
If you place multiple elements in the same cell, such as the top-left, they may overlap. To position them relative to each other, place them inside a second container and set a different layout mode for that container.
When align to parent is useful
Align to parent is useful whenever you need an element to stick to a specific side or part of its parent, including its corner and center.
Flexible rows. Such as a list of users, where the left side of each row contains information about the user, and the right side contains actions like edit and delete.
Positioned badges/labels. A small element (like a notification count) anchored to a specific corner of another element.
Action buttons. Buttons anchored to the bottom right corner of a popup.
Watermarks/logos. A logo or watermark positioned in a fixed corner, regardless of content size.
Positioned tooltips. A small info box anchored to a corner of another element.
Image overlays. Text, buttons, or icons layered on top of an image in specific positions (like a "play" button centered over a video thumbnail).
Fixed
Fixed layout gives you pixel-perfect control, but it's difficult to manage across different screen sizes since elements won't reposition themselves automatically. Use it only when you have a specific reason and know how it will behave on all your target screens.
Fixed layout lets you move and place an element freely within its parent container. You set its position using an absolute X and Y pixel value, and its size using a width and height value. That position is relative to the parent: the element sits exactly X and Y pixels from the top-left corner of the parent container.
Fixed layout can come in handy for specific design needs, but it's harder to manage across different screen sizes and resolutions.
When a fixed layout is useful
Fixed layout is useful in a few specific scenarios:
Precise pixel-level control. When you need an element to sit at an exact pixel position and you're designing for a single, known screen size (like a kiosk or display).
Overlaying custom designs. When you're building a highly visual, non-standard layout that doesn't fit into row or column logic — for example, a complex infographic or a custom game interface where elements need to be scattered freely.
Prototyping quickly. When you're sketching out an idea and don't want to think about responsive behavior yet.
Container alignment
In row and column layouts, you can also set alignment: where should the row or column start? In a column layout, for example, elements stack on top of each other. Should that stack start from the top of the container, or the bottom?
Alignment controls both where a group of elements starts and how they're spread out across the parent container.
In the illustration below we have two groups, both with a row layout. The top one is aligned to the left, and the bottom one is aligned to the right. Adding more elements will grow in a left-to-right direction or right-to-left direction.
For a full technical breakdown of every container layout property, see the core reference article on row and column layouts.
Core reference:Containers (web)
Core reference:Containers (mobile)
Element layout settings
These settings apply to child elements of a container (or page/view). Keep in mind that containers can be child elements too, so the properties can apply to them as well.
The settings covered so far live on the parent container and affect every child inside it. But each individual element also has its own layout settings, which only affect that element.
On any element, you can control:
Width. No restriction, fixed width, minimum and maximum width, or stretch with content.
Height. No restriction, fixed height, minimum and maximum height, or stretch with content.
Alignment, relative to the layout mode set on its parent container.
Collapse behavior, whether the element's width or height collapses to zero when it's hidden.
Margin and padding.
These settings give you the freedom to fine-tune how an individual element behaves within the boundaries its parent container sets. For example, a container's layout mode might be set to column, making its children stack vertically, while each child's own width setting still controls how wide it is.
Common methods for controlling responsive behavior
The basic definition of responsive behavior is that the content on a page or view adapts to changes in screen size. This can happen once, when the app loads on a given screen size, or dynamically, as the size changes, such as when a user resizes a browser window.
A broader, more useful definition for you as the developer is this: responsive behavior means making an app easy to use on any given screen size, not just adaptable to it. This distinction matters. Think about an app you've used that has both a desktop version and a mobile web version or native app. The experience can differ quite a bit. A common example is a left-hand navigation menu: it works well on a desktop browser, where the screen is wide, but poorly on a mobile device, where the screen is narrow and the menu might cover everything else.
In this section, we'll cover some common scenarios and methods you can use to optimize your app for both. These aren't strict best practices, more useful starting points, so stay open to finding your own creative solutions for whatever challenge you run into.
Resizing elements
The obvious, and frequently used, solution is to resize elements so they shrink and grow along with the browser window or screen. Depending on their configuration, most elements will do this automatically.
What you may need to adjust is their minimum and maximum width. Say you have a form in the center of the viewport that shrinks just fine, but stops shrinking once it hits a certain point. That's its minimum width at work. The same idea applies to maximum width: some elements fill the whole viewport, while others are deliberately kept at a much smaller size.
The same principle applies to height, in theory. But unlike the horizontal axis, the vertical axis is often scrollable, which removes most of the need for resizing.
Resizing can be set as a pixel value, or as a percentage of the parent's width.
Fixed width
Some elements you'll want to retain a fixed width no matter what the size of the viewport is. For example, you maye have a specific design that only "works" when the container has an exact pixel value as width. In that case, you can choose to set the width of that specific element or container to fixed.
1. Select the element
Select the element or container so that the element property editor opens. Go to the Visual tab and scroll to the Size section.
2. Set the width (and optionally height) to Fixed
In the Size section, find set the Width type to Fixed and then set the value you want.
Hiding elements
Another common method to preserve a responsive design is to hide and show element based on the page width. Below, you can see a common design pattern: a two-column layout
Many desktop apps divide their UI into two or three columns. The first column, and the third if there is one, tends to be narrow, while the remaining column holds the actual content of the page. A common pattern when the page/view width is below a specific breakpoint, is to hide the left bar altogether.
Hiding is done by using conditionals.
1. Select the left bar container
Make sure you select the container that holds all the elements in the left bar.
2. Create and name a conditional
In the element property editor, go to the Conditional tab and click the + symbol to create a new condition. Give it a suitable name, such as Hide on small screen.
3. Set up the condition
Set up the dynamic expression that checks the width of the page. It's common to use the ≤ symbol, which means "less than or equal to". This makes sure that the conditional triggers exactly at the breakpoint.
In a web app:
Current page's width ≤ Mobile Landscape (768 px)
In a mobile app:
Current view's width ≤ Mobile Landscape (768 px)
4. Change the visibility property
Click + Select a property to change to add a property, and select This element is visible. Disable it, since we want the bar to be hidden when this conditional is true.
5. Set the element to collapse when hidden
In the element property editor, go to the Interaction tab and ensure Collapse when hidden is enabled. This ensures the element's width and height is reduce to 0 when hidden, leaving room for other elements. In this example, it makes more room for the right column, which holds the page's content.
6. Replace the menu (optional)
Optionally, you can replace the menu with an option more suitable for a small screen, For example, you can use the Bubble-made Slidebar menu plugin.
Sometimes, you'll have a three-column layout, as illustrated below:
Typically, this will be menu on the left side, and some sort of information, metadata or for the right one. It may be enough in this case to hide the left menu, and perhaps some resizing of the right drawer. However, on mobile screens, you may need to hide it altogether, and find another way to display the info to the use. For example, you can:
Display the info in a group in the center column instead
Display the info in a popup (web) or sheet (mobile)
Wrapping elements
When you have elements in a row (container layout set to row), their total width can sometimes exceed the available width as the viewport shrinks. When that happens, the elements automatically wrap onto a new row.
It can be useful to control the gap between elements once they wrap, so they don't end up crammed together vertically. To do this, use the Gap property.
1. Select the container
Select the container that holds the element (not the element itself), to open the element property editor.
Make sure you are selecting the container, not any the elements themselves.
2. Navigate to alignment
Navigate to alignment, and you'll see the spacing section. The Gap property automatically applies a vertical gap to all elements within the container. Optionally, you can add a horizontal gap between the elements too.
Note: The gap property is not only applied to elements that wrap. They are applied to all elements within that container.
Conditional margins and padding
When you have a wide viewport, margin and padding are useful ways to add whitespace. As the viewport shrinks, though, it can help to reduce or remove those properties, so you make better use of the space you have.
For example, say you have a group containing your app's main content, with a 50PX margin to give it some airy, comfortable whitespace on a desktop screen. On a narrow mobile screen, that same margin eats into space you can't spare, so you'd want to shrink or remove it at that breakpoint.
1. Select the group
Click the group in the element tree or on the canvas to select it. Its properties will appear in the element property editor.
2. Go to the conditionals tab
In the element property editor, click the Conditional tab. This is where you'll define rules that change the group's properties based on screen size or other conditions.
3. Set up the condition
Click Add new conditional. In the When field, set the condition to check the current page/view width against a breakpoint;
In a web app:
Current page's width ≤ Mobile Landscape (768 px)
In a mobile app:
Current view's width ≤ Mobile Landscape (768 px)
4. Set the property
With the conditional selected, find the Margin or Padding property and enter a smaller value, such as 10 px. This value only applies when the conditional's condition is true, so the group keeps its original margin on wider screens and switches to the smaller one on narrower ones.
Allow vertical scrolling
If you have a group element where you want to control the height, you can let the content inside it scroll instead. The group gets a scrollbar of its own, which only appears when it's actually needed.
1. Select the container
Click the container in the element tree or on the canvas to select it. Its properties will appear in the element property editor.
2. Go to the interaction tab
In the element property editor, click the Interaction tab.
3. Enable vertical scrolling
In the Visibility section, enable Allow vertical scrolling. Content that exceeds the container's height will now scroll instead of overflowing or getting cut off.
Only groups support vertical scrolling. If you need this behavior in another type of container, place a group inside it and enable the property on that group instead.
Repeating groups allow it by default.
Using the Responsive Viewer
Above the element tree, you'll find a tab that switches between the UI Builder, where you build and edit your page or view, and the responsive viewer, where you can test how it behaves across different screen widths, known as breakpoints.
In the responsive Viewer, drag the ruler at the top of the page area to resize it and watch your layout adjust in real time. You can also use the preset width icons to preview your page in mobile portrait, mobile landscape, tablet, and desktop sizes.
When you click on an element while in this view, the Layout tab in the property editor shows you the settings available to adjust its behavior at that breakpoint.
Managing breakpoints
Every app comes with a default breakpoint plus four presets, and you can add custom breakpoints of your own. The default breakpoint matches the Default builder width value set for that page.
The four presets are:
You can use any breakpoint to test your layout in the Responsive Viewer, and as a data source for Current page width conditionals on any element.
Viewing breakpoints
All preset breakpoints appear on the page's toolbar by default. Any custom breakpoint gets added to the toolbar the first time it's used as a data source in a conditional on that page.
The breakpoints dropdown lists every preset and custom breakpoint available in your app.
Creating a custom breakpoint
Click the + symbol next to the existing breakpoints and select Add custom to create a new one.
Editing breakpoints
You can edit any breakpoint from the toolbar or the breakpoints dropdown.
Editing a custom breakpoint updates its value everywhere it's referenced in your app. Editing a preset breakpoint, on the other hand, creates a new custom breakpoint and updates every reference to point to it instead.
If you change the preset breakpoint Mobile from 320PX to 325PX, Bubble creates a new breakpoint called Mobile (Custom) (325PX). Every element that referenced Mobile now references Mobile (Custom) (325PX) instead.
Removing and deleting breakpoints
You can remove a breakpoint from the toolbar without deleting it. It stays available as a data source elsewhere in your app, but is hidden from the toolbar. Click the dotted contextual icon next to the breakpoint and select Remove. To re-add it, click on the + icon and click on the breakpoint in the list.
Deleting a breakpoint from the dropdown removes it from your project. Any conditional referencing that breakpoint becomes unlinked, and the issue checker flags it so you can fix it. To delete a breakpoint, click the + icon to list all breakpoints. Hover the one you want to delete, and click on the trashcan.
Bubble's built-in breakpoints can be edited and hidden from the toolbar, but they can't be deleted.
Referencing breakpoints
Breakpoints become a data source, which means you can refer to it in dynamic expressions. The most common use case is in element conditionals. By comparing the data source Current page width with a breakpoint, you can apply a property to the element, such as hiding it or changing its padding.
This is more flexible than hardcoding pixel values to control responsive conditionals. For example:
⛔ Current page width < 1200
✅ Current page width < Desktop (1200 px)
In the first example, you will have to change the hardcoded pixel value in every dynamic expression that relies on it, and in the second you can simply edit the breakpoint and it applies everywhere.
Other ways to learn
Video lessons
Video lessons
Several video lessons can help you get more comfortable with responsive design in Bubble:
You'll find the full playlist about the responsive editor here.
FAQ: Responsive design
What's the difference between a page/view and a container?
What's the difference between a page/view and a container?
The page or view is the outermost parent element on your app. Every other element, including containers, sits inside it. A container, like a group, is any element that can hold other elements and become their parent. You can nest containers inside each other as many levels deep as your design needs.
Which layout mode should I use?
Which layout mode should I use?
It depends on what you're building. As a general guide:
Use column when you need elements to stack vertically, like a sidebar menu or a scrolling feed.
Use row when you need elements arranged horizontally, like a navigation bar or a button group.
Use align to parent when you need to position elements in fixed spots within a container..
Use fixed only when you need pixel-perfect placement and understand how it will behave across screen sizes, since it doesn't reposition elements automatically.
Why isn't my element resizing the way I expect?
Why isn't my element resizing the way I expect?
This usually comes down to the width or height property on the element itself, combined with the layout mode of its parent container. Check whether the element is set to fixed, fit, or fill, and confirm the parent's layout mode supports the behavior you're expecting.
Minimum and maximum width or height values can also stop an element from shrinking or growing past a certain point.
How do I stop a hidden element from leaving an empty gap?
How do I stop a hidden element from leaving an empty gap?
Most elements can collapse when they are hidden, to make room for other elements. Their height and width is then reduced to 0.
If an element leaves an empty gap, you may have missed the property that controls collapse behavior.
Select the element to see the property editor
Navigate to the Interaction tab and Visibility section
Enable Collapse when hidden
What's the difference between margin and padding?
What's the difference between margin and padding?
Margin is space outside an element, between it and its neighbors or the edge of its parent container. Padding is space inside an element, between its edge and its content. Both can be set independently on all four sides.
How do I change a property based on screen size?
How do I change a property based on screen size?
Use a conditional. Select the element, go to the Conditional tab in the element property editor, and create a new conditional with a condition based on Current page/view width, using one of your app's breakpoints (or a custom hardcoded number). You can then set a different value for properties like margin, padding, width or visibility that only applies when that condition is true.
Can I let content scroll instead of resizing everything?
Can I let content scroll instead of resizing everything?
Yes. On a group element, you can enable Allow vertical scrolling in the Interaction tab. This gives the group its own scrollbar, which only appears when the content inside exceeds the group's height. Only groups support this property. If you need the same behavior in another type of container, place a group inside it and enable the property there instead.
Do I need to design differently for native mobile apps?
Do I need to design differently for native mobile apps?
Most of the same responsive principles apply to native mobile apps as they do to web apps: layout modes, sizing, alignment, and conditionals all work the same way. The main difference is that the range between the largest and smallest screen you're designing for is usually smaller on mobile devices than it is on the web.
Why does my row layout wrap unexpectedly?
Why does my row layout wrap unexpectedly?
Elements in a row layout wrap onto a new line automatically once their total width exceeds the available width of the container. If wrapping happens sooner than you'd like, check whether individual elements have a fixed or minimum width that's taking up more space than expected.
Should I use fixed layout for my whole page?
Should I use fixed layout for my whole page?
Generally, no. Fixed layout doesn't reposition elements automatically, which makes it hard to manage across different screen sizes. It's best reserved for specific cases, like a design that targets a single known screen size, or a highly custom visual layout that doesn't fit into row, column, or align to parent logic.
Fixed layout can also be useful to quickly "draw" a mockup, but we recommend you re-build it to be responsive later.
