The short version if you’re in a hurry: Add this to Bricks → Settings → Custom CSS and you’re done. Everything below explains why this works and why nothing else you’ve tried has.
#smooth-content {
min-height: 100dvh;
display: flex;
flex-direction: column;
}
.brx-content {
flex: 1 0 auto;
}
Skill level: Beginner to Intermediate
Applies to: Bricks Builder + Bricksforge with Scroll Smoother (GSAP provider) enabled
Round 1: The Floating Footer Problem
As I’m writing this post, I’m still building the SpeedbuildWP website. After I built the footer, I noticed the typical issue with the footer not staying at the bottom of the page when a page is short on content (like a contact page, thank you page, 404, etc.). The footer is floating halfway up the screen with a sea of white space below it and it’s annoying

The modern, correct way to make a footer stick to the bottom of the page on short-content pages is flexbox. The old position: absolute “sticky footer” hack causes content overlap the moment your page grows taller than the viewport. Flexbox handles both short and long pages automatically with no overlap, ever.
The logic: make the page wrapper at least as tall as the viewport, set it as a vertical column, and tell the content area above the footer to grow and absorb any empty space. The footer gets pushed down by that growing content area on short pages, and everything flows normally on long ones.
In a standard HTML/CSS setup this looks like:
body {
min-height: 100dvh;
display: flex;
flex-direction: column;
}
main {
flex: 1 0 auto;
}
Since I’ve dealt with this issue plenty of times, I applied the fix and it worked perfectly.
A little while later, it broke again.
Round 2: What Did I Do to Break it Again?!
After making a bunch of modifications to this site after applying the original fix, I noticed the footer was floating again. Ugh. I didn’t have a cache plugin enabled so I knew that wasn’t the issue. I cleared my browser cache and yet, the problem persisted.
I figured the next logical troubleshooting step is deactivating all plugins. Low and behold, the footer was back to the bottom. Never ignore this troubleshooting step!
After spending a few minutes enabling plugins one at a time and rechecking the footer each time, I found the culprit: Bricksforge.
This is one of the most annoying layout issues in a Bricks + Bricksforge WordPress stack, and the reason it’s so hard to solve is that the actual cause has nothing to do with your CSS being wrong (well, sort of).
I enabled all Bricksforge elements and extensions to test them out, including the Scroll Smoother extension. That’s when I realized the problem is structural, something Bricksforge’s Scroll Smoother extension is doing behind the scenes that silently invalidates every standard CSS approach.
First: Two Settings Worth Clarifying
Before getting into the fix, it’s worth clearing up a common point of confusion, because there are two separate smooth scroll mechanisms in a Bricks + Bricksforge setup, and they’re easy to mix up.
1. Bricks’ built-in “Smooth Scroll” setting (found under Bricks → Settings → General) simply adds scroll-behavior: smooth globally via CSS. That’s the entire scope of it. It’s primary purpose is to have same-page anchor links glide smoothly instead of jumping. It does not inject any DOM elements, does not interact with Bricksforge, and has no effect on the footer layout problem described in this post.

IMPORTANT: if you’re running Bricksforge’s Scroll Smoother, you should leave Bricks’ own Smooth scroll (CSS) setting disabled. The Bricks forum has documented known conflicts between the two, specifically inconsistent scrolling behavior with the Table of Contents element and Tabs (nestable) when both are active simultaneously. Bricksforge handles smooth scrolling for you; there’s no need for Bricks’ setting to be on as well.
2. Bricksforge’s Scroll Smoother extension (found under Bricksforge → Extensions) is a completely different beast. When enabled with the GSAP provider, it physically restructures your page’s DOM at runtime (during initial page load) and that restructuring is what causes the footer problem covered in this post.

Why the Standard Flexbox Approach Fails
Before getting into what goes wrong, it’s worth establishing why the correct approach works in a standard setup, because you need to know what “right” is before you can diagnose why it’s not working.
In a plain Bricks setup without Bricksforge Scroll Smoother, the equivalent structural targets are body and .brx-content. This is what most tutorials suggest focusing on, and it’s technically correct for that scenario. The problem is that when Bricksforge’s GSAP Scroll Smoother is active, the DOM structure the usual fix is tied to isn’t the new DOM structure that Bricksforge Scroll Smoother applies on your page. Flexbox only works on direct children of the flex container, which is the whole crux of the issue.
The Real Problem: What GSAP Scroll Smoother Does to Your DOM
When Bricksforge’s Scroll Smoother is enabled with the GSAP provider, it injects two wrapper elements that surround your entire page content at runtime.

Bricksforge’s own documentation acknowledges this directly, noting that GSAP Scroll Smoother “alters the scroll context” but it focuses on the implications for fixed-position elements, not footer layout. The footer layout problem is a separate, undocumented consequence of the same structural change.
Here’s why it breaks your CSS: as I mentioned, flexbox only affects direct children of the flex container. When you set display: flex on body, and thanks to Bricksforge, body’s only direct child is #smooth-wrapper now instead of .brx-content.
Your header, content area, and footer are buried two levels deep inside #smooth-content, completely untouched by the flex layout on body.
Setting flex: 1 0 auto on .brx-content has no effect either, because .brx-content isn’t in the flex container. It’s inside #smooth-content, which is inside #smooth-wrapper, which is the only child body actually has.
Your CSS is loading correctly. It’s targeting real elements. And it’s doing precisely nothing useful, because the elements it’s targeting aren’t where flexbox can act on them.
This is why the issue is so difficult to debug without knowing what to look for: there’s no error, no visible feedback, just a footer that refuses to move no matter what you try.
A Brief History of Wrong Answers: The 2021 Bricks Forum Thread
The Bricks Builder support forum has a thread from 2021 titled “How to make footer stay at the bottom” that has been found by thousands of people searching for this fix. It contains several distinct solutions, all of which were proposed before Bricksforge’s GSAP Scroll Smoother existed, and none of which work reliably in a Bricks + Bricksforge stack. Here’s each one and why it fails.
1. The calc(100vh – 220px) Approach
The most recent suggestion in the thread proposes targeting body with:
body {
min-height: calc(100vh - 220px);
}
The 220px is a hardcoded guess at the combined height of the header and footer. In 2021, on a simple Bricks layout with no smooth scrolling and a fixed-height header, this probably worked. The problem is that it’s fragile by design. The moment your header height changes with different viewport sizes, a mobile menu that stacks, or a notification bar added later, that magic number is wrong and your footer either overlaps content or floats. There’s also no flex logic to manage how that extra space gets distributed, so even when body is the “right” height, the footer doesn’t know where to go.
This approach (or a variation of it) sometimes ends up as a default or legacy rule in Bricks installations. If you inspect your body element in DevTools and find a calc(100vh - ...) rule sitting there, remove it entirely before applying the fix in this post, otherwise the two rules will conflict.
2. The #bricks-content and #bricks-site-wrapper Selectors
Two other suggestions target #bricks-content or #bricks-site-wrapper with min-height: 100vh. These were valid selectors in early versions of Bricks but were removed around version 1.4. If you copy these from the forum and paste them into your custom CSS, you’re targeting elements that no longer exist. No errors, no effect, no feedback. Just the same floating footer with no indication why.
3. The jQuery Solution
One forum member contributed a JavaScript function using jQuery that calculates the viewport height on every page load and window resize, then programmatically adds a margin-top to the footer. He flagged it himself as a stopgap, and that was accurate. It fires after the page renders, which can produce a visible layout flash before the margin is applied. It adds a resize listener that fires repeatedly. And it becomes unreliable the moment anything restructures the DOM after load, which is exactly what Bricksforge’s Scroll Smoother does. JavaScript doing layout work that CSS should handle is always the wrong tool for this job.
4. The Fixed Footer Link
One reply pointed to a tutorial on position: fixed footers. This is a completely different thing. A fixed footer is pinned to the bottom of the viewport and stays visible as you scroll (like a persistent navigation bar). What you want is a footer that sits at the bottom of the document on short pages but scrolls out of view normally on long ones. Following this advice would put your footer permanently on top of your content. It’s the wrong solution to a different problem.
5. The .brx-body { min-height: 100dvh } Approach
A more recent suggestion targets .brx-body with min-height: 100dvh. This is better than the calc approach because dvh is the correct modern unit, and .brx-body is a current, valid Bricks class. But min-height alone without display: flex and a grow rule doesn’t solve the problem. It tells the element to be at least viewport height but gives no instruction about what to do with that extra space. What you often get is a container that’s the right height but with empty whitespace sitting below the footer rather than above it.
And again…none of this matters anyway in a Bricksforge GSAP Scroll Smoother setup, because the actual flex container needs to be #smooth-content, not body or .brx-body.
6. The CSS Grid Approach
The most sophisticated forum suggestion uses display: grid on .brx-body with named grid rows for header, content, and footer. Grid is actually a valid approach for document-level layout in theory. In practice it introduces a new layout context that can interact unexpectedly with Bricks’ own layout system, it’s harder to debug when something goes wrong, and it still targets the wrong element in a Bricksforge Scroll Smoother setup.
The Actual Fix
Now that you understand why everything else fails, here’s what actually works. Paste this into Bricks → Settings → Custom CSS:
#smooth-content {
min-height: 100dvh;
display: flex;
flex-direction: column;
}
.brx-content {
flex: 1 0 auto;
}

Save, purge your cache, and check a short page. The footer should be pinned to the bottom.

Why This Works
Instead of targeting the body element which only has #smooth-wrapper as a direct child when Bricksforge Scroll Smoother is active, this targets #smooth-content, which is the element that actually contains your page content and footer. By making #smooth-content the flex container, the layout logic applies to the right level of the DOM tree. flex: 1 0 auto on .brx-content tells the content area to grow and fill any empty space, which pushes the footer down on short pages. On long pages, the content already exceeds the viewport height, so min-height never kicks in and everything flows normally.
The key insight: in a Bricksforge GSAP Scroll Smoother setup, #smooth-content is the real page wrapper and not body. Any CSS rule you’d normally apply to body for document-level layout purposes almost certainly belongs on #smooth-content instead.
*A Note on the dvh Unit
This uses 100dvh rather than the older 100vh. The difference matters on mobile. vh is calculated once based on the full browser viewport height, but on mobile browsers the address bar and toolbar expand and collapse as you scroll, changing the actual available height. dvh (dynamic viewport height) recalculates based on the current viewport, so your layout stays correct as browser chrome moves. Always prefer dvh for viewport-based sizing. You can add vh as a fallback for older browser support:
#smooth-content {
min-height: 100vh; /* fallback for older browsers */
min-height: 100dvh; /* modern browsers use this */
display: flex;
flex-direction: column;
}
.brx-content {
flex: 1 0 auto;
}
The browser uses the last valid line it understands, so modern browsers get dvh and older ones fall back to vh gracefully.
Want to Learn More About Viewport? Check Out This Video
What If You’re Using Bricksforge’s Lenis Provider Instead?
If you’ve set Bricksforge’s Scroll Smoother to use Lenis instead of GSAP, the fix in this post may not apply to you. Bricksforge themselves recommend Lenis as the lighter-weight option and unlike GSAP ScrollSmoother, Lenis does not inject the #smooth-wrapper/#smooth-content wrapper elements into the DOM.

If you’re on Lenis and experiencing a floating footer, inspect your DOM (see the diagnostic section below) and check what body‘s direct children actually are. I checked on this site and there were no smooth scroll wrappers present. That simply means you’re back to the standard approach: apply the flex layout to body and the grow rule to .brx-content.
For Lenis users, the standard fix looks like:
body {
min-height: 100dvh;
display: flex;
flex-direction: column;
}
.brx-content {
flex: 1 0 auto;
}
Diagnosing the Problem Yourself: The DevTools Method
If you’re ever unsure what’s happening with a layout issue in Bricks, this two-minute diagnostic process will unblock you and applies far beyond footers.
Step 1: Load your site, right-click anywhere, and choose Inspect (or press F12).
Step 2: In the Elements panel, click on <body> and expand it to see its direct children.
Step 3: If you see #smooth-wrapper as body’s only direct child, you’re in a GSAP Scroll Smoother layout. Every body-level flex rule is landing on the wrong element. Target #smooth-content instead, using the fix above.
Step 4: To confirm the fix before touching any files, test it live in DevTools. Click #smooth-content in the Elements panel, then in the Styles panel on the right, add display: flex, flex-direction: column, and min-height: 100dvh. Then click .brx-content and add flex: 1 0 auto. If the footer drops to the bottom immediately, your fix is confirmed, copy and paste the CSS into Bricks Custom CSS with confidence.
This live-testing step is the single most time-saving thing you can do before writing any CSS. “My CSS does nothing” is almost always a targeting problem, and the DOM tree shows you the correct target in seconds.
Potential Side Effects to Watch For
This fix is stable and safe for most Bricks + Bricksforge builds, but it does change the layout context of #smooth-content. Here’s what to check after implementing it.
Short pages. Visit every page with minimal content like contact, thank you, 404, and coming soon. Scroll all the way to the bottom. You should stop cleanly at the footer with no empty scrollable space below it. If you can scroll past the footer into white space, GSAP’s internal scroll-distance calculations are including the expanded min-height. This is subtle and most visitors won’t notice, but if it bothers you it can be addressed by adjusting how ScrollSmoother calculates the scroll height.
Stretched elements on short pages. Any child element of #smooth-content with height: 100% now resolves against a potentially taller parent. Check short pages for anything that looks unexpectedly stretched such as hero sections, full-height divs, images set to fill their container.
Flex context on direct children. Making #smooth-content a flex column means everything directly inside it is now a flex item. In most Bricks builds this is invisible because Bricks sections behave as block-level elements anyway. But if you ever notice a section collapsing in width, ignoring margins, or stretching unexpectedly after this change, the new flex context is the first thing to investigate.
Quick Troubleshooting Guide
First confirm the CSS is actually loading. Open DevTools, click #smooth-content in the Elements panel, and look in the Styles panel for display: flex. If it’s not listed, your CSS isn’t reaching the page. Most common causes: you pasted raw CSS into the Custom Code box instead of Custom CSS (Custom Code requires <style> tags); or a caching layer is serving stale CSS. Purge everything, including Bricks cache, any caching plugin, and your host’s server-level cache.
Either Bricksforge’s Scroll Smoother isn’t active, or you’re using the Lenis provider instead of GSAP. In either case, use the standard body-targeting approach described in the Lenis section above.
You’ve accidentally applied position: fixed or position: sticky to the footer element or its wrapper. Check the layout settings on your footer template’s outermost element in Bricks and remove any position values.
This is separate from the sticky footer problem. The issue is inside the footer template itself, not the page layout. Check the footer section’s height settings in Bricks. If a height or min-height is set on the footer’s outermost section, clear it. The footer’s grow should be 0, shrink 1, basis auto, so it collapses to only the height of its content.
Confirm #smooth-content exists on mobile by checking DevTools with device simulation enabled. Also verify you’re using dvh on mobile, vh can produce incorrect heights due to the collapsing browser toolbar. The vh + dvh fallback pair handles this correctly.
This is a caching issue, not a settings issue. Your hosting provider may have server-level caching, so purge from the control panel. If you use Cloudflare, purge from the Cloudflare dashboard too. Then do a hard browser refresh with Ctrl+Shift+R (Linux/Windows) or Cmd+Shift+R (Mac) to bypass the browser cache.
Tools Referenced in This Post
All links below are affiliate links. They cost you nothing extra and help keep this site running.
Bricksforge — the plugin that adds Scroll Smoother to Bricks. [Get Bricksforge →]
FAQ
No, or rather, you probably don’t need it. The #smooth-wrapper/#smooth-content wrapper elements are specific to the GSAP ScrollSmoother provider. Lenis doesn’t inject the same structure, so the GSAP fix doesn’t apply. If you’re on Lenis and have a floating footer, inspect your DOM and use the body-targeting approach described in the Lenis section of this post.
It adds scroll-behavior: smooth globally via CSS, which makes anchor link navigation animate smoothly instead of jumping. It does not inject any DOM elements and has nothing to do with Bricksforge. If you’re running Bricksforge Scroll Smoother, leave this Bricks setting disabled. Enabling both has documented conflicts with Bricks’ Table of Contents element and Tabs (nestable).
No. Adding it to Bricks → Settings → Custom CSS applies it globally across your entire site.
Possibly, but unlikely. The #smooth-content ID comes from GSAP ScrollSmoother’s own API, which Bricksforge uses as a dependency. Unless Bricksforge changes its Scroll Smoother implementation or swaps to a different library, the fix will continue to work. It’s worth quickly checking a short page after major Bricksforge updates.
No. This is a small CSS addition with no JavaScript, no additional HTTP requests, and no render-blocking behavior. It should have no measurable impact on performance.
vh (viewport height) is calculated once based on the full browser viewport. On mobile, the browser toolbar collapses and expands as you scroll, changing the actual visible height but vh doesn’t update, causing layout issues. dvh (dynamic viewport height) recalculates continuously based on the current viewport size, accounting for the collapsing toolbar. Always prefer dvh for modern builds with a vh fallback for older browsers.
No. Sticky headers use position: sticky or position: fixed and aren’t related to the flexbox document-flow technique described here. A sticky header stays visible as you scroll; a bottom-anchored footer (as covered here) sits at the bottom of the page on short pages but scrolls away normally on long ones. Different layout goals, different solutions.
Two likely causes: dvh isn’t being applied (check DevTools on mobile simulation to confirm the CSS is loading), or your mobile layout has additional wrapper elements. Check DevTools on mobile view and confirm #smooth-content is still the correct parent of .brx-content at that viewport size.
No. If you’re using plain Bricks without Bricksforge’s Scroll Smoother extension, the #smooth-wrapper/#smooth-content wrapper elements won’t exist. Use the standard approach: display: flex, flex-direction: column, min-height: 100dvh on body, and flex: 1 0 auto on .brx-content.
Wrapping Up
The floating footer in a Bricks + Bricksforge stack is one of those problems that feels impossible until you understand the underlying cause and then it’s completely obvious. GSAP Scroll Smoother restructures your DOM at runtime, burying your content inside #smooth-content and making every body-level CSS rule irrelevant. Once you know to look for that wrapper, diagnosing the issue takes thirty seconds and the fix takes thirty more.
The broader lesson: when CSS is confirmed correct and confirmed loading but doing nothing visible, stop tweaking values and inspect the DOM. Page builders and animation libraries inject wrapper elements that silently break the parent-child relationships your selectors depend on. The DOM tree tells you more in thirty seconds than an hour of trial and error.
If this post saved you an afternoon of frustrated cache-clearing, share it with someone who’s been Googling the same thing. And if you’re running into other Bricks workflow issues, that’s exactly what SpeedBuildWP is for. Bookmark the site or drop your email below.
Found an error or have a question not covered in the FAQ? Leave a comment below and I’ll update the post.

