Custom menu on mobile

AI-generated summary

The discussion revolves around creating a custom mobile menu for a forum. Francois_Douville shared the code and images of the desired menu, but it wasn’t working properly. Mittineague suggested that the issue might be due to relying on Bootstrap magic, which is not available in Discourse.

Johani proposed a solution by wrapping the code in a $( document ).ready() function, which made it work for him. He also shared the updated code.

Additionally, Johani provided tips on how to position the menu on the bottom right, make it transparent, and adjust its appearance for different screen sizes using CSS media queries.

I am trying to make a custom menu on mobile for my forum. In fact, this is a menu that someone else has on his forum and I asked for his codes but something is missing, don’t know what! Probably in JS…

This is what it supposed to be :

Before :

After :

Code in </head> :

<script>
function click_outside(selector){
  $(selector).on('click', function(e) {
    e.stopPropagation();
  });
  console.log("Click Outside initialized for "+selector);
  $('html').click(function(event) {

    if($(selector).hasClass("active")){
      console.log("clicked outside");
     $(selector).fadeOut(200, function() {
              $(selector).removeClass("active");
          });
      }
  });
}

  $('#mobile-menu').addClass("visible");
  $('html').click(function(event) {
    if ($('.background').hasClass("active")){
      $("#mobile-menu").toggleClass("active");
      $('.background').toggleClass("active");
      $('.dropdown').toggleClass("active");
      $('body').toggleClass("overflowMobile");
    }
  });

  $('.background').click(function(event){
      event.stopPropagation();
  });

  $('#mobile-menu').click(function(event){
    $(this).toggleClass("active");
    $('.background').toggleClass("active");
    $('body').toggleClass("overflowMobile");
    event.stopPropagation();
  });

  $(function() {
    $('#menu a[href^="/' + location.pathname.split("/")[1] + '"]').addClass("active");
  });
</script>

CSS :

#mobile-menu{
	z-index: 5000;
	border: 1px #f9f9f9 solid;
	position: fixed;
	width: 50px;
	height: 50px;
	bottom:20px;
	left:20px;
	border-radius: 150px;
	background-color: #fff;
	box-shadow: 0px 5px 5px #888;
	box-shadow: 0px 5px 5px rgba(0,0,0,0.4);
	cursor: pointer;
	-webkit-transition: .25s ease-out;
	-moz-transition: .25s ease-out;
	-o-transition: .25s ease-out;
	transition: .25s ease-out;
}
#mobile-menu.visible{
	visibility: visible;
	opacity:1;
}
#mobile-menu:hover{
	box-shadow: 0px 3px 3px #666;
	box-shadow: 0px 3px 3px rgba(0,0,0,0.6);
	bottom:15px;
	left:15px;
	width: 60px;
	height: 60px;
}
#mobile-menu:hover:after{
	top: 15px;
	font-size: 21px;
	color:#888;
}
#mobile-menu:after{
	content: "\f0c9";
	font-family: 'FontAwesome';
	color: #4a5659;
	position: relative;
	top: 11px;
	font-size: 19px;
	text-align: center;
	display: block;
	-webkit-transition: .25s ease-out;
	-moz-transition: .25s ease-out;
	-o-transition: .25s ease-out;
	transition: .25s ease-out;
}

#mobile-menu.active{
	box-shadow: none;
	border-radius: 0px;
}
#mobile-menu.active:after{
	content:"\f00d";
}


.background{
	z-index: 10;
	position: fixed;
	width:100%;
	height:100%;
	background-color: #fff;
	border-radius: 0px;
	box-shadow: none;
	bottom:0px;
	left:0px;
	visibility: hidden;
	opacity: 0;
	overflow: auto;
	transition: visibility 0s, opacity 0.5s linear;
	-webkit-transition: .25s ease-out;
	-moz-transition: .25s ease-out;
	-o-transition: .25s ease-out;
	transition: .25s ease-out;
}

.background.active{
	visibility:visible;
	opacity: 1;
	bottom:0px;
}

.background a, .background a i{
	transition: visibility 0s, opacity 0.5s linear;
	-webkit-transition: .25s ease-out;
	-moz-transition: .25s ease-out;
	-o-transition: .25s ease-out;
	transition: .25s ease-out;
}

.background a i{
	visibility: hidden;
	opacity: 0;
}

.background a{
	display: block;
	padding:10px 0;
	color:#444;
	font-size: 22px;
	font-family: "Open Sans";
	font-weight: 300;
}

.background a:hover{
	color: #111;
}

.background a:hover i{
	visibility:visible;
	opacity: 1;
}

.background a i{
	margin-left: 15px;
}
.background a{
	font-size:16px;
}
.background h2{
	font-size: 22px;
	font-family: "Open Sans";
	color:#444;
}
.background h1{
	font-size: 28px;
}
.background a i{
	visibility: visible;
	opacity: 0.7;
	left: 0px;
	position: relative;
	float: left;
	margin-right: 15px;
	top:3px;
	width: 20px;
	text-align: center;
}

@media (max-width: 768px) {
	.background{
		padding-bottom: 85px;
	}
	#mobile-menu{
		bottom: 25px;
		left:calc(50% - 25px);
	}
	#mobile-menu:hover{
		left:calc(50% - 30px);
		bottom: 20px;

	}
	#mobile-menu:hover:after{
		top: 16px;
		font-size: 21px;
		color:#888;
	}
	.overflowMobile{
		overflow-x: hidden; 
		overflow-y: hidden;
	}
}
@media (min-width: 769px) {
	.background{
		height: 550px;
		width: 350px;
		overflow: hidden;
		bottom: 0px;
		left: 0px;  
		box-shadow: 0px 0px 0px #999;
		box-shadow: 0px 0px 0px rgba(0,0,0,0);
	}
	.background.active{
		overflow: hidden;
		bottom: 15px;
		left: 15px;
		box-shadow: 0px 5px 5px #666;
		box-shadow: 0px 5px 5px rgba(0,0,0,0.3);
	}
}

HTML :

<div id="mobile-menu"></div>
<div class="background">
  <div class="row" style="margin-top:5%; padding:10px;">
    <div class="col-md-12" style="border-bottom:1px #ccc solid;">
      <h1 style="margin:12px 0 15px 0;">Qu'aimerais-tu faire?</h1>
    </div>
  </div>
  <div class="row">
    <div class="col-md-12">
      <a href="https://forum.lepeuplier.com">Aller sur la communauté<i class="fa fa-users"></i></a>
      <a href="https://lepeuplier.ca">Voir nos formations<i class="fa fa-graduation-cap"></i></a>
      <a href="https://lepeuplier.ca">S'inscrire au webinaire<i class="fa fa-video-camera" aria-hidden="true"></i></a>
      <a href="https://lepeuplier.ca">Lire le blogue<i class="fa fa-book"></i></a>
      <a href="https://lepeuplier.memberful.com/account">Voir vos factures<i class="fa fa-credit-card"></i></a> 

    </div>
  </div>
</div>

Are you relying on Bootstrap magic? i.e.
<div class="col-md-12">

AFAIK, Discourse does not have Bootstrap so those class attribute values are superfluous and if you are expecting them to get a particular style applied they won’t.

Focusing on the </head> section here:

Wrapping the code in a $( document ).ready() function made it work for me:

Here’s what </head> code for that looks like:

<script type="text/discourse-plugin" version="0.8.18">

$(document).ready(function() {
	function click_outside(selector) {
		$(selector).on("click", function(e) {
			e.stopPropagation();
		});
		console.log("Click Outside initialized for " + selector);
		$("html").click(function(event) {
			if ($(selector).hasClass("active")) {
				console.log("clicked outside");
				$(selector).fadeOut(200, function() {
					$(selector).removeClass("active");
				});
			}
		});
	}

	$("#mobile-menu").addClass("visible");
	$("html").click(function(event) {
		if ($(".background").hasClass("active")) {
			$("#mobile-menu").toggleClass("active");
			$(".background").toggleClass("active");
			$(".dropdown").toggleClass("active");
			$("body").toggleClass("overflowMobile");
		}
	});

	$(".background").click(function(event) {
		event.stopPropagation();
	});

	$("#mobile-menu").click(function(event) {
		$(this).toggleClass("active");
		$(".background").toggleClass("active");
		$("body").toggleClass("overflowMobile");
		event.stopPropagation();
	});

	$(function() {
		$('#menu a[href^="/' + location.pathname.split("/")[1] + '"]').addClass(
			"active"
		);
	});
});

</script>

You have to figure out what selector actually is to make the click outside function work as well.

On small screens, there wouldn’t be much difference because the button / menu is centered,

On tablets you would use the stuff from above but just flip the left properties to right

If you are not sure what I mean, you can also just add this at the bottom of the code above:

#mobile-menu {
	left: unset;
	right: 20px;

	&:hover {
		left: unset;
		right: 15px;
	}
}
@media (min-width: 769px) {
	.background {
		left: unset;
		right: 0;

		&.active {
			left: unset;
			right: 15px;

		}
	}
}

To get this:

You can use an RGBA color as the background for the class background like so:

.background {
    background-color: rgba(255,255,255, .7);
}