Tips for creating a vertical drawer using jQuery and CSS

Hello, I am currently working on developing a drawer component using Ember.js. If you want to view the progress so far, feel free to check out this jsbin http://jsbin.com/wulija/8/edit

My goal is to have the drawer look like the following initially:

+---------------------------+
|    A      B        C      |
+---------------------------+
  ... other page content ...

When an option is selected, the corresponding component will be displayed. The drawer should slide down to reveal content A and overlap the following page content.

+---------------------------+
|    _A_    B        C      |
+---------------------------+
|                           |  |  Clicking on A slides down to show content A
|    content A              |  V  Following page content is covered by the drawer
+---------------------------+

If option B is clicked, content A will slide left and content B will slide in from the right. The height of the drawer will adjust according to the size of content B.

+---------------------------+
|    A    _B_        C      |
+---------------------------+
|                           |  |  If content B has more content
|                           |  |  It will slide further down
|nt A <--     <-- Content B |  V  
|                           |
+---------------------------+

If the currently selected option is clicked again, the drawer will close.

+---------------------------+
|    A    _B_        C      |
+---------------------------+   ^
                                |  Close drawer

I have encountered a few challenges along the way:

  • One issue is with the sliding drawer adjusting its height based on the content size. Since all content-X elements are set to position: absolute; and moved using jQuery's transform: translate, the drawer does not extend properly because these elements do not occupy any space. Additionally, position: absolute; elements cannot be hidden with overflow-y: hidden;.

  • Another challenge is that each content-X has a different size and its data is fetched via AJAX requests, making the size unknown beforehand. Therefore, having a fixed length drawer is not feasible. Ideally, I would like the browser layout engine to allocate space dynamically as needed. This would require setting content-X elements to position: static;, resulting in the three contents stacking together vertically.

Answer №1

When it comes to completing tasks, there are numerous things on your to-do list. I have provided the first option below.

$(document).ready(function () {
  var show1 = false,
      show2 = false,
      show3 = false,
      
      content1 = $('.btn-1'),
      content2 = $('.btn-2'),
      content3 = $('.btn-3');
  
  $('.content-placeholder').css("width", $(window).width());
  
  var w = $(window).width() + 30;
  
  $(window).resize(function () {
    w = $(window).width() + 30;
  });
  
  function checkDrawer (shouldOpen) {
    if (shouldOpen) {
      $('.drawer-content').addClass('show');
    } else {
      $('.drawer-content').removeClass('show');
    }
  }
  
  $('.btn-1').on('click', function () {
    show1 = !show1;
    show2 = false;
    show3 = false;
    checkDrawer(show1 || show2 || show3);
    if($('.btn-1').hasClass( "current" ))
      {
        $('.main_content').slideUp(1000);
        content1.removeClass('current');
      }
    else
      {
        $('.main_content').slideDown(1000);
        content1.addClass('current');
      }
    $('.drawer-content').css('transform', 'translate(0, 0)');
    
    
    content2.removeClass('current');
    content3.removeClass('current');
  });
  
  $('.btn-2').on('click', function () {
    show1 = false;
    show2 = !show2;
    show3 = false;
    checkDrawer(show1 || show2 || show3);
    
    
    
    $('.drawer-content').css('transform', 'translate(-' + w + 'px, 0)');
    
    
    content1.removeClass('current');
    
    content3.removeClass('current');
    
  });
  
  $('.btn-3').on('click', function () {
    show1 = false;
    show2 = false;
    show3 = !show3;
    checkDrawer(show1 || show2 || show3);
 
    $('.drawer-content').css('transform', 'translate(-' + 2 * w + 'px, 0)');
    

    content1.removeClass('current');
    content2.removeClass('current');
    content3.addClass('current');
  });
});
.main_content{
  position:relative;
  z-index:1;
  display:none;
}

.drawer {
    border: 1px solid green;
    height: 100px;
    position: fixed;
    width: 100%;
}
.drawer-navbar {
    width: 100%;
}
.drawer-content {
    overflow-x: hidden;
    transition: all 0.3s ease 0s;
    width: 5000px;
  position:relative;
}
.drawer-content.show {
    max-height: 700px;
}
.content-placeholder {
    border: 1px solid yellow;
    float: left;
    top: 90px;
    
}
.content-placeholder > div {
    transition: all 0.5s ease 0s;
}
.content-placeholder.current {
    border: 5px solid yellow;
}
.content-1 {
    background-color: red;
    height: 300px;
}
.content-2 {
    background-color: green;
    height: 200px;
}
.content-3 {
    background-color: blue;
    height: 100px;
}
.other-content {
    position: relative;
    top: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>

  <div class="drawer">
    <div class="drawer-navbar">
      <ul>
        <li class="btn-1">1</li>
        <li class="btn-2">2</li>
        <li class="btn-3">3</li>
      </ul>
    </div>
    
    <div class="main_content">
    <div class="drawer-content">
      <div class="content-placeholder">
        <div class="content-1"></div>
      </div>
      <div class="content-placeholder">
        <div class="content-2"></div>
      </div>
      <div class="content-placeholder">
        <div class="content-3"></div>
      </div>     
    </div>
    </div>
  </div>
  <div class="other-content">
    additional web content......sadfa
    sdfj
    asdjf
    sadjf
    sadjf
    jsad
    fjklxzcjlkzxcjv;lkjslkdjfl;kjaskdljflksd
    f
    asdf
    asd
    f
    adsf
    asd
    f
    ads
    fasd
    f
    asd
    fasd
    f
    asd
    fsad
    f
    adsf
    asd
    f
    asdfasd
    fasd
    f
    asdf
    asd
    fa
    sdfa
    sdjf
    asdjf
    aksdjfalskdjflkasdjflkjadslkjflkasf
    
  </div>

Hopefully this helps you progress towards your goal. Good luck!

For reference, you can view the Fiddle Here.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"Stuck: CSS Div Transition Effect Refuses to Cooper

I am looking to incorporate a transition on my div when it is clicked. I've tried using jQuery with this example: http://jsfiddle.net/nKtC6/698/, but it seems to not be working as expected. So, I want to explore another example using CSS: http://jsfid ...

Is the space-between property not delivering the desired spacing?

I am trying to achieve equal spacing between list items, and I attempted the following code. ul { list-style-type: none; display: flex; justify-content: space-between; } However, it seems that this approach is not working as expected. I am confused ...

I'm receiving a TypeError in Nodejs indicating that the hashPassword function is not recognized as a function. Can anyone offer advice on how to

How's everything going? I could really use your assistance! I'm currently working on developing an API for registering authenticated users, with data storage in the MongoDB Atlas database (cloud). Unfortunately, I've run into a troubling er ...

HTML text/code ratio display tool

I need help finding a firefox/firebug plugin (or any OFFLINE tool is fine) that can show me the real text/markup ratio. While there are some online options available like and a Firefox plugin at (which is also online), I am specifically looking for an o ...

Determining the type of index to use for an interface

Imagine having an interface called Animal, with some general properties, and then either be a cat or a dog with corresponding properties. interface Dog { dog: { sound: string; } } interface Cat { cat: { lives: number; } } type CatOrDog = Cat | D ...

How to set the element in the render method in Backbone?

Currently, I am in the process of developing a web page utilizing BackboneJS. The structure of the HTML page consists of two divs acting as columns where each item is supposed to be displayed in either the first or second column. However, I am facing an is ...

The index on ref in MongoDB does not seem to be yielding any improvements

I've encountered a performance issue with my model: const PostSchema = new mongoose.Schema( { _id: mongoose.Schema.Types.ObjectId, workSpace: { type: mongoose.Schema.Types.ObjectId, ref: 'Workspace&apos ...

Highcharts: Show tooltip above all elements

Is there a way to configure tooltip display above all elements? I want to define specific coordinates so that the tooltip remains open even if it is covering the chart, and only closes when interacting with the top block. Screenshot 1 Screenshot 2 For e ...

Connecting event listeners to offspring elements, the main element, and the entire document

My request is as follows: I have multiple boxes displayed on a webpage, each containing clickable divs and text. When a user clicks on a clickable div, an alert should appear confirming the click. Clicking on the text itself should not trigger any action. ...

Is there an advantage to pre-rendering a circle on an HTML5 canvas for improved performance?

Is it more efficient to pre-render graphics for a basic shape like a circle on an off-screen canvas? Would there be noticeable improvements in rendering performance when dealing with 100 circles at game-like framerates? What about 50 circles or just 25? ...

Enable the duplication of strings within an array

Below is the HTML code snippet I am working with: <div class="col-sm-8"> <div class="row col-sm-12 pull-right paddingDiv"> <div class="col-sm-12"> <div class="marginBottom pull-right"> <bu ...

My website using Dynamic Ajax technology is currently experiencing heavy traffic due to the number of getScript

I am facing an issue with my dynamic website where all links fetch new sections via ajax requests from other pages and replace the current section. The problem I encounter has two main aspects. When loading a new div from an Ajax get request, some sections ...

The function form.parse() in node.js is always overlooked

I'm having an issue where form.parse() is never called. When I delete bodyparser, my session variable throws an error. How can I resolve this and make it work? logcat The write(string, encoding, offset, length) method is deprecated. Use write(st ...

Utilize AngularJS to refine and sort through data retrieved from an API

I have an Angular application that is fetching hotel data from an API. I want to filter the results based on the minimum price of the hotels being less than $50. $http.get($rootScope.baseurl + 'api/hotels/', { params: { page_ ...

Having trouble uploading images from my personal computer onto Phaser 3

Currently in the process of coding a game for a school project using Phaser. I am quite new to Phaser and have very little knowledge of JavaScript. Despite searching online for potential solutions, none seem to be effective for me. I have included my cod ...

What is the best way to adjust the widths of a two-row header table using the table-layout: fixed property?

Here is the table header setup I am aiming for: <table class="tabel_op_panou" style="margin: 0px 2px 0px 2px; width: 99%; table-layout:fixed;"> <tr> <th rowspan="2" style="width: 35%;">A</th> <th colspan="2" style="width ...

Instant webpage updates upon editing CSS/HTML live

I recently watched a tutorial where a designer was updating CSS with live browser refreshes. What stood out to me was that the browser instantly showed any changes made to the CSS or HTML without needing to manually refresh the page. I am using a Mac with ...

Is being unfazed by work a common occurrence?

After completing a complex cycle that processes data from the database and writes it to an array, I encounter a situation where the array processing function is triggered before the array is fully populated. This forces me to use setTimeout() for proper ti ...

Achieve full height Bootstrap styling by nesting it inside a row div

Is there a way to make the height of the left sidebar div equal to 100% within a row, based on the height of the right content? I have tried setting the height to 100%, but it doesn't seem to work. Any advice would be appreciated. <body> < ...

Discover the color value within an array that begins with the "#" symbol

In my PHP code, I have written a function that extracts values from a CSS file and creates an array. Now, I need to loop through this array and create another array that only contains color values (strings starting with #). The challenge is that the length ...