I think we’ve all been there before. You’re trying to code a menu for your webpage, and you don’t want to use some bloated battery-eating JS framework for your project. So naturally, you decide to use Bootstrap. Now, you need to make an expand and collapse effect using CSS. And Bootstrap 5 in particular, as that is what almost everyone is using when they choose Bootstrap.
But you face a problem, a weird glitch. Sometimes, the bootstrap menu does not animate the collapsing part. Or instead, it doesn’t animate the expanding part. Even worse, maybe it doesn’t animate at all, and that’s if the menu even appears, on top of that. So let’s see what can be done about glitches in the Bootstrap expand and collapse effect and how we can fix them.
Problem 1: The menu is not appearing
This is a very common issue that new developers are facing, if they have read an old tutorial, and especially if they have changed their Bootstrap 4 code to Bootstrap 5. That is because of a change the Bootstrap developers made in Bootstrap 5, that has changed the names of all Bootstrap properties.
Now, all property names start with data-bs-
instead of just data-
.
For example, now the Bootstrap target property is called data-bs-target
and not data-target
. You want to toggle something? Now you use data-bs-toggle
instead of data-toggle
. And so on.
Problem 2: The animations are not working
First of all, Bootstrap is not using animations for things like collapse, it’s using CSS transitions and Javascript. You heard me right, Bootstrap is using JS to make a large part of its dynamic features work. So the first thing you have to do is make sure you are including Bootstrap’s Javascript file inside your HTML. Some people think they can get away with only including the CSS file, but that is a mistake! It will cause the transitions to stop working.
So once you have ensured that you have included both the Boostrap JS and CSS, the second thing you need to check for is conflicts with the CSS transition
property, because Bootstrap assigns this property. Maybe you assigned some other class to your menu, and in some rule of higher specificity, there is another transition. So make sure there are no unwanted classes interfering with Bootstrap’s default transition, and if so, remove them.
Problem 3: You want both expand and collapse animations
Now, let’s look at how you’d go about making both an expand and collapse animation, using only Bootstrap’s CSS and JS files. And importantly, without making any Javascript of your own. (Because let’s be honest, who wants to write long and boring jQuery for that anymore). I’ll assume that you want the expand animation to pull the navbar down, and for collapse to pull it up.
Unfortunately, it doesn’t look like it’s going to be straightforward to implement in Bootstrap, because:
As you can see, there are only one class for animating both the expand and collapse animations (.collapsing
). On first glance, this would make it possible to animate one of the expand or contract animations. But certainly not both, because you do not know which way it will be animating with just this class, right? That is what I thought too.
However, I have found a trick that utilizes all three of these selectors to create two different animations that go in opposite directions, which I will detail here.
Our plan of attack
You see, what if instead of trying to animate both the collapse and expand of the transitioning .collapsing
selector by setting it to 0 and 100% at the same time, we animate to an intermediate value?
This is going to be roughly our plan of attack. But first of all, some important notes to be made here:
- We cannot animate the height property, or any other property, to a percentage – it must be a known static value. To get around it, we can animate the
max-height
property instead. This puts a constraint on the height of the element without actually adjusting the height. - We will be making two separate transitions, but play around with the duration to try to make the illusion of one continuous animation. So we need to set the height property of the
.collapsing
transition to be an intermediate value. I chose 300px, but depending on the height of your menu and how long you want the animation to last altogether, you might need to choose a different value.
Solution to expand and collapse Bootstrap 5 menus using pure CSS
First, we need to make the three CSS selectors above. We will assume the element we want to collapse has a class called .navbar
, for the purposes of this demo. Here is for the .collapse
selector:
First, we must set the max-height
to zero so that the element disappears completely. Note: Bootstrap usually does this for you but there should also be display: none
on your element when it is in the collapsed state.
In this case we have the transition for max-height set to 300 milliseconds, but do note that this is only the length of the second collapsing animation. There is an intermediate transition that occurs before this that I will show you below.
So as you can see, we have our intermediate transition that is applied before an element expands or contracts. In other words, it reaches the max-height of 500px (for the purposes of this example) first, in 150 milliseconds. The purpose of this animation is to get rid of the majority of the menu very quickly so we can fake an “ease-out” transition of the height. Remember – we are using two different transitions in succession to fake it, so that’s why all these transitions are using ease
.
The expanding part of the animation
This is the last transition, and it only appears when the element is in the expand state, not during the collapse state in Bootstrap. In this case, we set max-height to a ridiculously high value that the menu will never reach, so that the animation can ease out quickly, not too slowly. But at the same in order to make the second part of the expand animation visible to the eye – which is how we intend to make it smooth in the first place – we must make the animation last for a long time. In this case, we use 1.6 seconds. But the fact at this animation is very long does not matter, as most screens have 5x or 4x shorter heights than 5000px. Even 1080p screens are a bit less than 5x shorter than 5000 pixels.
In this selector, I am using height: 100% !important
because otherwise, the height will be automatically the total height of the menu elements, which will make my mobile sidebar look cut off. For my personal purposes, my mobile sidebar menu must cover the entire height. If you’re making an ordinary dropdown menu, then you should not include this property.
Here is a demo showing a menu I made using these transitions in action: