How do I make a sticky footer?

Dear fellow Bubblers,

I need your help with something that’s been driving me nuts for a few hours straight now: creating a sticky footer.

So, not a floating group anchored to the bottom of the browser viewport that sticks there all the time regardless of the scroll position. I need a regular old group that doesn’t scroll into view until the user scrolls through all the content above it if the page is long, but I also need it to stay put at the bottom of the page even if the content of the said page is shorter than what the user’s browser viewport height is (such as in the screenshot below).

I added the red viewport outline so you can clearly see the big gap between the bottom of the viewport and the bottom of the footer when I maximize the browser window on my MacBook Pro. (Debugging mode is turned off, so the extra space is not due to that.)

Many thanks in advance.

Alright, here’s how to do this. :hammer_and_wrench:

But first off, a huge shoutout to @Taiheta for helping me out! :raised_hands:

Let’s get started…


  1. Click the Plugins tab and install Elements in View.

  2. Click the Settings tab, go to General, and make sure “Expose the option to add an ID attribute to HTML elements” is checked. (If not, click the checkbox.)

  3. Click the Design tab, grab the Elements in View element from Visual Elements and drop it onto your page.

  4. Drag a new shape onto the page. First, make it really small (like, 1 x 1 pixels), then make it invisible by changing its Background Style to None. Position it at the very bottom of your page, then give it a unique ID attribute (e.g. sensorElement).

  5. Click the Elements in View element, replace the content of the Elements field with the unique ID attribute you’ve given to the element from previous step. Change the Interval to something low, like 10.

  6. Design the footer you want. (A reusable element works best here - you’ll soon find out why.) When finished, copy and paste it so you’ve got two copies.

  7. Create two new groups: a floating group and a regular group. Position them both at the bottom of your page. (You will need to turn their visibility on and off to successfully make them overlap without getting unintended new groupings.) Make sure the floating group is set to vertically float relative to bottom.

  8. Place one copy of the footer in each of the new groups. (This is where the footer being a reusable element helps - if you decide to update something later, you won’t have to do it in two different places.)

  9. Make sure “This element is visible on page load” is turned off for both groups.

  10. Go to Conditionals for the floating group and set it up like this: when Elementsinview’s values contain sensorElement (or whatever unique ID attribute you picked in Step 4), make the floating group visible.

  11. Go to Conditionals for the regular group and set it up like this: when Elementsinview’s values don’t contain sensorElement (or whatever unique ID attribute you picked in Step 4), make the group visible.

  12. Congratulations! :tada: You’ve got the footer which sticks to the bottom of the page when the content is shorter than the browser viewport and scrolls normally when it’s not.


That’s quite creative! Nice job figuring it out :slight_smile:

1 Like

Hi, I do not get it to work. I did exactly what you described. See screenshots. Can you explain what that elementsinview exactly does? Then I understand the logic and figure out what I am doing wrong.

@j.poolman Looks like you skipped last few steps which define the conditionals. Those are crucial because they provide the logic this entire setup needs to work properly.

What Elements In View does is it builds a list of elements that are currently in view (i.e. inside the user’s browser viewport) based on the list of all the elements you entered into its “Elements” text field. So, in this particular case, it just checks whether sensorElement is in view or not, since it’s the only thing in the “Elements” field. Elements in View then keeps on re-checking for any changes in the viewport every 10 milliseconds, as defined in the “Interval” field. Once the sensor element comes into view during one of these 10 ms checks, Elements In View will add it to its list; if it’s not in view, the list will stay empty.

That’s where the conditionals come in. Once you know if the sensor at the bottom of the page is in the viewport at any given moment, you tell Bubble which group you want it to display:

The Page Scrolled All the Way to the Bottom:
sensorElement visible :arrow_right: Elements In View has it in the list :arrow_right: Show floating group

The Page Hasn’t Been Scrolled to the Bottom Yet:
sensorElement not visible :arrow_right: Elements In View doesn’t have it in the list :arrow_right: Show regular group

Hope that helps!


Thanks @chaostorm. Clear now for me.

@j.poolman You are welcome!

Working supersmooth now. I am thinking: Shape A Is on the last pixel of the page. When I scroll down, shape A will be in the viewport. How come “Elements in view element” does not see that? It checks every 10 miliseconds. So in my imagination you scroll down see the footer in the normal group. And it will be replaced after 10 miliseconds to the normal footer. Or am I missing something.

I don’t think I am missing something. I see the footers change. (colored them differently). So I think a flickering is unevitable?

@j.poolman I’d love to help you out, but I’m not sure what you mean. How about posting an animated gif of the issue or a live link to the page you are building?

Thanks. See page. Click the button more text and then scroll up and down.

Funny, I do not see a flickering now.

1 Like

@j.poolman One thing to keep in mind: there’s no need to take the sticky footer approach when building long pages with a lot of content, such as the one in your example.

The principal use case for a sticky footer is when you’ve got a short page containing little or no content that ends up placing the footer significantly higher in the layout than where you want it to be — which is at the visual bottom of the page — unless you use this trick.

If you want to dive deeper into this topic and understand why things work the way they do — and drive nuts a lot of web devs not used to the joys of CSS :slight_smile: — I’d recommend googling “CSS normal flow”.

This topic was automatically closed after 70 days. New replies are no longer allowed.