Hey Lukas, welcome to Meta
There’s isn’t a lot of CSS involved in this. The animation is handled with CSS, but the values for the offset are set in JavaScript to handle the case where the user scrolls/pans to the right or left to close the menus.
Most of that logic is here - that’s just one method; there’s a few others involved in that file
discourse/site-header.js at 8a250a1eac9032485e7d367f93e6ac418014e2ff · discourse/discourse · GitHub
There’s also some logic that handles the case when the user clicks on the dimmed background to close the menus.
for the user menu
discourse/user-menu.js at 1472e47aae5bfdfb6fd9abfe89beb186c751f514 · discourse/discourse · GitHub
For the hamburger menu
discourse/hamburger-menu.js at 1472e47aae5bfdfb6fd9abfe89beb186c751f514 · discourse/discourse · GitHub
Changing those to make the hamburger menu open and close on the right will involve two things.
-
modify the site-header
component with ModifyClass so that it opens all the menus from the right side. It currently checks for a class on the menu, so we simply override that like so
api.modifyClass("component:site-header", {
pluginId: "right-side-mobile-hamburger",
_leftMenuClass() {
// we don't want any left menus, so return false
return false;
}
});
-
when closing the menu, we also want it to close to the right side. For the scroll/pan event, this is already handled by the snippet above. Now we need to fix the case where the user clicks on the dimmed background. Discourse decides that based on whether or not the site uses an RTL language. To modify this, we need a different plugin-api method since the hamburger panel is a widget.
The method we’re going to use is reopenWidget like so
api.reopenWidget("hamburger-menu", {
clickOutsideMobile() {
// apply the code from core
this._super(...arguments);
// then make your change so that it closes to the right side
const panel = document.querySelector(".menu-panel");
const windowWidth = document.body.offsetWidth;
panel.style.setProperty("--offset", `${windowWidth}px`);
}
});
Then all you need to do is add a couple of lines of CSS to override the default styles for that menu like so
.hamburger-panel,
.user-menu {
.menu-panel.slide-in {
left: unset;
right: 0;
}
}
Now let’s put all of that together. This goes in the mobile > header
tab of your theme
<script type="text/discourse-plugin" version="0.8">
api.modifyClass("component:site-header", {
pluginId: "right-side-mobile-hamburger",
_leftMenuClass() {
// we don't want any left menus, so return false
return false;
}
});
api.reopenWidget("hamburger-menu", {
clickOutsideMobile() {
// apply the code from core
this._super(...arguments);
// then make your change so that it closes to the right side
const panel = document.querySelector(".menu-panel");
const windowWidth = document.body.offsetWidth;
panel.style.setProperty("--offset", `${windowWidth}px`);
}
});
</script>
and this goes in mobile > CSS
tab.
.hamburger-panel,
.user-menu {
.menu-panel.slide-in {
left: unset;
right: 0;
}
}
Once you save the theme and refresh the page, the hamburger menu will open and close on the right side on mobile - just like the user menu.