Sticky banner with Tailwind

Sticky banner with Tailwind

Crysfel Villa Programming

A few days ago I had to implement a sticky banner at work, at first I thought it would be a simple task but it took me quite some time to figure everything out. On the bright side, I've learned a few new things about CSS in the process.

Here are the requirements:

  1. The component might be present sometimes depending on some custom logic on the backend.

  2. When present, it had to push all the content down and when closed by the user, it had to disappear with a slide up animation. Effectively animating all content up while going away.

  3. In addition to that, when the user scrolls down, the banner should stay on top at all times.

Position Fixed to the rescue

I started by making the banner sticky when scrolling down. My first approach was to set the position to fixed like this:

<div class="fixed py-3 text-center text-white bg-blue-600">
  Hi there, welcome to our site! Make sure to accept our new <a href="#" class="underline">terms of services</a>.
</div>

Sticky banner using position fixed

The banner sticks to the top successfully while the user scrolls down, but there are a couple problems with this approach.

The width of the banner is not right, it should be 100% of the container, I can easily fix this problem (I thought) by setting w-full to the banner, but that brings another issue:

Sticky banner using position fixed with full width

When setting the width:100% it doesn't consider the parent container, because the element is fixed and not part of the flow anymore, it takes the width of the screen and not the one for the parent. Given that I have a sidebar, the width is all wrong now and the text is not centered correctly anymore.

In addition to that, the text in the main content is under the banner. One of the requirements is to push the content down, but the position fixed won't do that for me.

I've seen this behavior on navigations and menus on some websites before, so I tried to find out how they built it. After some research I found out most people is using JavaScript to dynamically switch the position when the scrolls reaches certain value, definitely not ideal! Is there a way to do it with CSS only? This is 2020 after all, there must be something we can do with CSS only!

Behold! The new Sticky position

After more research I finally learned about the new sticky position (at least new to me 😂), turns out most browsers support this in 2020 so definitely this is the way to go! There are some bugs and things to consider, but for my use case this works absolutely fine!

Tailwind already comes with an utility for this css feature! So all I had to do is to set the position to sticky and the top where I want the banner to sticks, in this case at 0.

<div class="sticky top-0 py-3 text-center text-white bg-blue-600">
      Hi there, welcome to our site! Make sure to accept our new <a href="#" class="underline">terms of services</a>.
</div>

And here you have it! Everything is looking fine at this point, the banner is pushing the content down as required and when scrolling down it stays on top.

Sticky banner with css only

There are some things to consider, first of all the banner will only stick to the parent container, so if you add a wrapper to your banner, for example, let's pretend there's a header component with a couple other things inside.

If we place our banner inside the header, the banner will now stick to the header and it will go away with the header when scrolling down.

<header>
  <div class="sticky top-0 py-3 text-center text-white bg-blue-600">
      Hi there, welcome to our site! Make sure to accept our new <a href="#" class="underline">terms of services</a>.
  </div>
  <h1>User: John Doe</h1>
</header>

Keep that in mind when building your own. You can play around with the code of this tutorial in codepen.

Happy Coding!

Article by Crysfel Villa

Sr Software Engineer