Category: jQuery

Off-Canvas Menu with jQuery

offcanvas

In an age of modern websites built to resemble native smartphone applications, the rise of the off-canvas menu popularly has become hard to ignore. Although I must say, I don’t think they are effective when viewed/used on a desktop widescreen, I do see their clear advantage on a mobile handset where every space counts.

Here’s my version of an off-canvas menu with simple jQuery.

See the Pen Off Canvas Menu by Richard (@barkins) on CodePen.

HTML

I wanted to make this as modular as possible, therefore you’ll be able to grab only the off-canvas menu code and retrofit it onto your website right away without having to reinvent the wheel.

The Menu

<div id="off-canvas">
   <nav>
     <a href="#">Menu Item 1</a>
     <a href="#">Menu Item 2</a>
     <a href="#">Menu Item 3</a>
     <a href="#">Menu Item 4</a>
     <a href="#">Menu Item 5</a>  
   </nav>
</div><!--/off-canvas-->

Trigger

We’ll need a trigger for the menu and in this case I utilized a button giving an ID of “trigger” which will reveal and hide the menu for us.

<header class="header">
  <h1>Simple Off-Canvas Menu with jQuery</h1>  
  <button id="trigger"><i class="fa fa-bars"></i></button>
</header><!--/header-->

For the sake of the example, here’s the rest of the HTML code to give you some perspective on how an off-canvas menu would look and function like within a “real” website.

<section>
   <article>     
     <p>Lorem ipsum ...</p>
  </article>
</section>

CSS

Box-sizing

Before we focus on the CSS, I just want to mention that I’m using the box-sizing method for styling the site. Learn more about box-sizing here.

Here’s the box-sizing code I’m using:

*, *:before, *:after {
  -webkit-box-sizing: border-box; 
  -moz-box-sizing: border-box; 
  box-sizing: border-box;
}

Styling the Menu

As always you are free to style the layout anyway you choose, but the item you should pay close attention to is the actual menu. Here’s just the CSS for the menu.

#off-canvas{
  width:250px;
  height:100%;
  top:0;
  left:-250px;
  padding:25px;
  background:#a6032f;
  position:fixed; 
  z-index:5;
}

One thing to note, you’ll need to set the position to fixed and match the left property to the width of the menu.This way when you hide and reveal the menu it will hide the entire width of the menu.

Menu Trigger

The trigger can live anywhere on your website, as long as it’s outside of the menu so you can hit it whether the menu is revealed or hidden.

Here’s the styling I used, but you can choose to modify it anyway you wish.

#trigger{
  background:#a6032f;
  color:#FFF;
  padding:10px 15px;
  border:0;
  border-radius:5px;
  line-height:auto;
  font-size:1rem;
  margin:10px 0 0;
  text-transform:uppercase;
  cursor:pointer;
  position:absolute;
  top: 15px;
  right:25px;
  box-shadow:1px 1px 0px #000;
}

jQuery

Now onto the fun part, adding in the functionality for the menu.

Start by creating a variable we’re going to use in the functionality and set it to false.

var x = false;

I took advantage of an if else statement to help determine whether the menu should be revealed or hidden.

$('#trigger').on('click', function(){
  if(!x) {
    $('#off-canvas').animate({left:"0"},200);
    x = true;
  }else{
    $('#off-canvas').animate({left:"-250px"},200);
    x = false;
  } 
});

To review this code, whenever someone taps on the trigger, the functionality will check to see if x is set to false, if so, it will animate the left property and set it to 0. At the same time, it will change the variable x to true.

Now whenever someone taps on the trigger again, the functionality will see that x is now true and jump to the else statement and animate the left property to -250px in effect hiding the menu. Lastly, it will set the x variable back to false.

Wrap Up

The basic concept here is with the help of jQuery we are able to hide, or in other words, position the menu off the canvas and toggle it with a trigger.

Filed under: jQuery

Sticky Header with jQuery slideDown()

If your webpage gets long, you may have the desire to keep some form of branding on your website for readers to always see as they scroll through your content. This approach achieves that in a subtle yet effective way without being overly pushy.

Here it is in action.

See the Pen Sticky Header by Richard (@barkins) on CodePen.

You can apply these principles to other elements on your webpage, but I recommend using this technique judiciously and not over do it. Sticky elements on a page can oftentimes have unintended side effects, which I’ll cover briefly at the end.

HTML

Nothing out of the ordinary in the HTML, just straightforward HTML5 tags for the header and article areas.

<header id="header">
  <h1>Sticky Header</h1>
</header>

<article>
  
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam tempus dui nisi, a tincidunt nisi consequat id. Donec auctor tortor rhoncus hendrerit.......</p>

<p>....</p>
<p>....</p>
<p>....</p>
  
</article>

CSS

For styling, the only element you’ll really need is a sticky class with the following properties.

.sticky {
  position:fixed;
  display:none;
}

Additionally, the header should be styled so that its width is 100%, or you will need to add that width size to the sticky class. I’ll leave it up to you to see what happens if you don’t set a width to 100%.

Here’s all the CSS put together.

* {
  box-sizing:border-box;
  font-family:sans-serif;
}

body {
  margin:0;
  background:#c6c6c6;
}

#header {
  background:rgba(47,85,131,.9);
  padding:25px;
  text-align:center;
  color:#FFF;
  width:100%;
}

.sticky {
  position:fixed;
  display:none;
}

article {
  padding:25px;
}

jQuery

We start with creating a function that will store some position values, along with the element we want to be sticky.

var stickyHeader = function(){
  //THE POSITION OF TOP OF PAGE IN BROWSER WINDOW
  var windowTopPosition = $(window).scrollTop();
  
  //THE POSITION OF ARTICLE TOP
  var triggerContainer = $('article').offset().top;

  //THE THING THATS STICKS
  var stickyContainer = $('#header');
}

Next up, we’ll need to test if the position of windowTopPosition is greater than triggerContainer and if it is, go ahead and add the sticky class to the container we want to be sticky.

  if (windowTopPosition > triggerContainer) {    
    stickyContainer.addClass('sticky');
    stickyContainer.slideDown('fast');
    
  }else{
    stickyContainer.removeClass('sticky');
    stickyContainer.css("display","");
  }

If you noticed in the CSS previously, I included display:none in the sticky class styling, it’s because I also wanted it to slide down when the container became sticky. Otherwise the transition from non-sticky to sticky header can be a bit jarring.

This occurs when the if/else statement is true, I also included a stickyContainer.slideDown('fast'); which in effect brings the container out of hiding with a nice animation.

One key thing here is, if the user goes back to the top, although the sticky class will be removed, the display:block portion left behind by slideDown() will remain, destroying the slideDown() effect.

This is why I included the following jQuery function to fix it.

stickyContainer.css("display","");

Of course none of this function will work unless we trigger it somehow and we do that whenever the user scrolls on the page, like so.

$(window).scroll(stickyHeader);

Here’s the whole jQuery code put together.

var stickyHeader = function(){
 
  //THE POSITION OF TOP OF PAGE IN BROWSER WINDOW
  var windowTopPosition = $(window).scrollTop();
  
  //THE POSITION OF ARTICLE TOP
  var triggerContainer = $('article').offset().top;

  //THE THING THATS STICKS
  var stickyContainer = $('#header');
  
  if (windowTopPosition > triggerContainer) {    
    stickyContainer.addClass('sticky');
    stickyContainer.slideDown('fast');
    
  }else{
    stickyContainer.removeClass('sticky');
    stickyContainer.css("display","");
  }
  
  
};

$(window).scroll(stickyHeader);

You may now think you can apply this technique to other elements on your page, but be warned, whenever you apply a fixed styling to an element, the element gets moved out of its container and may end up covering up portions of content on your site. You have been warned.

Filed under: CSS3, HTML5, jQuery

Sketchbook with HTML5 Canvas and jQuery

Here’s how to build a drawing space on your website using the HTML5 canvas tag. This article will cover the very basics of getting started with canvas, but you’ll soon see how you’ll be able to take it even further.

Here’s a demo of this project.

See the Pen Sketchbook with the Canvas Tag by Richard (@barkins) on CodePen.

HTML

The only key tag in the HTML to take notice of is, you guessed it, canvas. You will need to include the width and height directly inside the tag, like so:

<canvas width="450" height="500" id="canvas"></canvas>

I included an id with the tag to reference later.

Here’s the rest of the HTML that houses the canvas tag.

<section>
<header>
  <h1>Sketchbook with the Canvas Tag</h1>
</header>

<article>
  
  <canvas width="575" height="300" id="canvas"></canvas>
  
  <div id="marker-container">
  
    <h2>Change Marker Width</h2>
  
    <input id="marker" type="range" max="10" min="1" value="1">
    
    <div id="shape"></div>   
    
  </div>  
  <button id="clear">Clear Sketchbook</button>
  
</article>
</section>

CSS/SCSS

I took advantage of a bit of SCSS here, just for time saving purposes. The only unusual item in the CSS is how I styled the ‘gradual increase symbol’ with border styling. Anytime you can substitute an image with some CSS, do it. It’s just good practice.

#shape {
  width: 0;
  height: 0;
  border-left: 125px solid transparent;
  border-right: 0px solid transparent;
  border-bottom: 15px solid #999;
  margin:5px auto;
}

Here’s all the CSS/SCSS.

Note: Check back soon on an article about getting up to speed with SASS (SCSS).

* {
  box-sizing:border-box;
  font-family:sans-serif;
}

h1 {
  color:#cc3300;
  margin:0 0 25px;
  font-size:2rem;
}

section {
  max-width:650px;
  margin:25px auto;
  background:#CCC;
  padding:25px;
  border-radius:10px;
  text-align:center;
  canvas {
    background:#FFF;
    border-radius:10px;
    box-shadow:0 0 15px #999;
    cursor:crosshair;
  }

  #marker-container {
    max-width:300px;
    background:#333;
    margin:25px auto;
    padding:15px;
    border-radius:10px;
    h2 {
      color:#FFF;
      margin:0 0 15px;
      font-weight:normal;
      font-size:1.2rem;
    }
  }
}

#clear {
  font-size:1rem;
  background:#cc3300;
  color:#FFF;
  border:0;
  padding:10px;
  border-radius:5px;
  cursor:pointer;
  &:hover {
    background:#FFF;
    color:#cc3300;
  }
}

#shape {
  width: 0;
  height: 0;
  border-left: 125px solid transparent;
  border-right: 0px solid transparent;
  border-bottom: 15px solid #999;
  margin:5px auto;
}

jQuery

Now the interesting part, some jQuery to help us interact with the canvas tag.

We’ll start off by creating some variables we’ll use throughout the program. The first one, marker will be used to store the color of the, well marker. The second variable, markerWidth will store the default width of the marker.

The last two variables I’ll cover in a bit, just include them for now.

var marker = "rgb(0,0,0)";
var markerWidth = 1;

var lastEvent;
var mouseDown = false;

Next up, we’ll need a function to setup the width of the marker working in tandem with the new HTML5 input type of range. Whenever $("#marker") is changed, like when a user moves the slider, the function changeWidth initiates and sets the current value to markerWidth.

var changeWidth =  function(){  
  markerWidth = $("#marker").val();
  console.log(markerWidth);
};

$("#marker").change(changeWidth);

Now we’ll need to set up the context of the canvas so that we can interact with it. This is fairly boilerplate stuff, you’ll need to include it in order to interact with the canvas tag.

var context = $('canvas')[0].getContext('2d');
var $canvas = $('#canvas');

Here’s a series of function that will activate whenever a user mouses down, moves the mouse and mouses up.

We’ll need to capture the canvas’ event in the DOM so that we can interact with properties of the canvas, which is why we passed an argument, e, through the function like so.

Next, set the mouseDown to true so that the following function will only work if it’s true. In the last function, we’ll set it back to false when the user mouses up so your cursor will stop drawing on the canvas then.

$canvas.mousedown(function(e){
    lastEvent = e;
    mouseDown = true;
    console.log(lastEvent);
})

If you look at the console now, after mousing down over the canvas tag, you’ll see the following properties you can use. That’s why the console.log(lastEvent) is there.

It should look something like this:

mouseevent

Notice, offsetX and offsetY?

We’ll use that information in the second function that initiates whenever a user mouses over the canvas tag.

mousemove(function(e){
  if(mouseDown){
    context.beginPath();
    
    context.moveTo(lastEvent.offsetX,lastEvent.offsetY);
    context.lineTo(e.offsetX,e.offsetY);
    context.lineWidth=markerWidth;
    context.strokeStyle = marker;
    context.lineCap='round';
    context.stroke();
    
    lastEvent = e;
  }
  
})

Since earlier we stored the context of the canvas in the context variable, we can access its properties. Such as setting the color of the stroke, context.strokeStyle = marker;, and then width of the stroke, context.lineWidth=markerWidth;.

Note: Here’s a full list of properties available for the canvas tag.

To finish this off, our last function disables drawing on the canvas after the user mouses up, like so:

.mouseup(function(){
  mouseDown = false; 
});

Here’s all the jQuery put together:

var marker = "rgb(0,0,0)";
var markerWidth = 1;

var lastEvent;var mouseDown = false;

var changeWidth =  function(){  
  markerWidth = $("#marker").val();
  console.log(markerWidth);
};

$("#marker").change(changeWidth);

var context = $('canvas')[0].getContext('2d');
var $canvas = $('#canvas');

$canvas.mousedown(function(e){
    lastEvent = e;
    mouseDown = true;
    console.log(lastEvent);
}).mousemove(function(e){
  if(mouseDown){
    context.beginPath();
    
    context.moveTo(lastEvent.offsetX,lastEvent.offsetY);
    context.lineTo(e.offsetX,e.offsetY);
    context.lineWidth=markerWidth;
    context.strokeStyle = marker;
    context.lineCap='round';
    context.stroke();
    
    lastEvent = e;
  }
  
}).mouseup(function(){
  mouseDown = false; 
});

The key takeaway here is how we assigned the markerWidth variable to context.lineWidth. You can also do the same with context.strokeStyle = marker; and I’ll leave you to figure how to evolve this project even further.

Filed under: CSS3, HTML5, jQuery, Sass

Horizontal Responsive Menu

It’s easier than you think to create a simple horizontal responsive menu with just some CSS3 media queries and jQuery. This example doesn’t include any multi-tier drop downs, but for the sake of keeping things simple, here’s a great solution. No plugin required.

The Completed Product

See the Pen Simple Responsive Horitzontal Menu by Richard (@barkins) on CodePen.

In the above embed, you’re looking at the mobile version of the menu. Check out the full screen demo and resize the browser window to see it in action.

HTML

The HTML for this simple menu is relatively straightforward. Wrapped in a NAV tag, you’ll need to include the actual menu wrapped in a DIV so that you can targeted it later. Additionally, you’ll need to include the trigger link.

<nav>
  <a href="/" id="trigger">Menu</a>
  
  <div id="menu">
  <a href="/">Home</a><a href="/">About</a><a href="/">Information</a><a href="/">Contact</a></div>
</nav>

CSS

The only key item in the CSS is the media query section, otherwise you’re free to style the list of menu links however you like. Here’s my example.

* {
  box-sizing: border-box;
}

#trigger {
  background:#cc3300;
  padding:15px;
  color:#FFF;
  text-decoration:none;
  text-transform:uppercase;
  display:inline-block;
  width:100%;
  
  display:none;
}

nav {
  background:#CCC;
  text-align:center;
  padding:5px;
  font-family:sans-serif;
}

#menu {
  background:#999
}

#menu a{
  display:inline-block;
  background:#999;
  padding:15px;
  color:#FFF;
  text-decoration:none;
  text-transform:uppercase;
}

#menu a:hover {
  background:#666;
}

@media screen and (max-width:760px){
  #trigger {
    display:block;
  }
  #menu {
    display:none;
  }
  #menu a {
    display:block;
  }
}

@media screen and (min-width:760px){
  #menu {
    display:block !important;
  }
}

jQuery

I find it’s best to utilize the “slideToggle” function in jQuery to determine the height of the menu links container. I recall seeing examples of this where the jQuery had to find out the height of all the links once revealed, but that’s not very good future proofing. If you add more links, it will cause issues.

You first start by creating the trigger by selecting the “trigger” ID and add an ON function to toggle the menu to show and hide whenever a user clicks on the trigger.

Note: Include the “preventDefault” function inside the click event so that the browser doesn’t try to following the href inside the trigger link. Alternatively, you can create a button instead of a link, but that’s up to you and your browser support (HTML5 compatibility) needs.

$('#trigger').on("click", function(e){
  e.preventDefault();
  $('#menu').slideToggle('fast');
});

And that’s all folks!

Filed under: CSS3, HTML5, jQuery