Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 3 of 3
  1. #1
    New to the CF scene
    Join Date
    Oct 2019
    Posts
    2
    Thanks
    1
    Thanked 0 Times in 0 Posts

    How to allow overflow-y scrolling on a sidebar drawer

    Hello,

    I'm new around here and figured your guys' expertise would be able to steer me in the correct direction. I'm currently developing a pullout side drawer shopping cart for an eCommerce website built on Shopify. As far as the data management goes I've got that all figured out using CartJS, CSS is clearly not my strong point.

    The cart button in the nav in the top right has a click listener bound to it, at that point the body of the document will translate -440px along the x axis pushing it all to the left revealing the side drawer that is 440px in width. Again, this is a shopping cart; users will add items to their cart and at a certain point the number of items will exceed the height of their browser and I'll need to allow the ability of scrolling of the y-axis overflow but only within that sidebar.

    The entire thing is inside of it's own div with the class cart-outter, within that is another div with the class cart-inner, and within that is another with the class cart-header and one more below that (still within cart-inner div) with the class cart-content. cart-content div is where the numerous divs exist with the product information. I essentially want only the cart-content div to be scrollable. I believe there might be conflicts the inherited properties of the div's that it's nested in causing me issues. I've attempted to simply allow overflow-y: scroll/visible on the cart-content div to no avail which is what leads me to think there's a property inheritance issue at hand.

    Please note that the poorly done HTML is for the simplicity of the codepen pen, the version I'm working on on my dev environment is a lot cleaner.

    Here's my code:

    HTML:

    Code:
    <body>
      <div id="cart-outter">
        <div id="cart-inner">
          <div class="cart-header">
            <p class="cart-header-text">Your Shopping Cart</p>
            <div class="cart-logo">
              <!-- SVG Logo sits here -->
              </div>
          </div>
          <br />
          <br />
          <p>
             Faux Item in the cart
          </p>  
            <br />
          <p>
             Faux Item in the cart
          </p> 
            <br />
          <p>
             Faux Item in the cart
          </p> 
            <br />
          <p>
             Faux Item in the cart
          </p> 
            <br />
          <p>
             Faux Item in the cart
          </p> 
            <br />
          <p>
             Faux Item in the cart
          </p> 
            <br />
          <p>
             Faux Item in the cart
          </p> 
            <br />
          <p>
             Faux Item in the cart
          </p> 
            <br />
          <p>
             Faux Item in the cart
          </p> 
            <br />
          <p>
             Faux Item in the cart
          </p> 
            <br />
          <p>
             Faux Item in the cart
          </p> 
        </div>
      </div>
      <div id="wrapper">
        <!-- Wrapper on DEV/LIVE would be class="product-template__container page-width" -->
        <button type="button" class="cart-toggle" id="cart-button">
          View Cart
        </button>
        <h1>
          Product One
        </h1>
        <button type="button" id="add-lens">Add Lens to Cart</button>
        <p>
          Variation One
        </p>
        <p>
          Variation Two
        </p>
      </div>
      <a class="cart-toggle" id="overlay"></a>
    </body>
    CSS:

    Code:
    body {
      transition: margin-right 500ms, margin-left 500ms;
    }
    
    body.cart-open {
      overflow: hidden;
      margin-right: 440px;
      margin-left: -440px;
      transition-duration: 500ms;
    }
    
    #cart-outter {
      background: #fff;
      bottom: 0;
      overflow-y: hidden;
      position: fixed;
      right: -440px;
      top: 0;
      width: 440px;
      -webkit-transition: all 500ms;
      transition: all 500ms;
      z-index: 9990;
    }
    
    .cart-open #cart-outter {
      -webkit-transform: translateX(-440px);
      transform: translateX(-440px);
      transition-duration: 500ms;
    }
    
    #overlay {
      background: rgba(0, 0, 0, 0.8);
      bottom: 0;
      cursor: pointer;
      display: block;
      left: 0;
      opacity: 0;
      position: fixed;
      right: 0;
      top: 0;
      visibility: hidden;
      -webkit-transition: all 500ms;
      transition: all 500ms;
    }
    
    .cart-open #overlay {
      opacity: 1;
      visibility: visible;
    }
    
    div.cart-header {
      position: relative;
    }
    
    p.cart-header-text {
      color: #f1c40f;
      background: #000;
      display: block;
      text-transform: uppercase;
      letter-spacing: 0.08em;
      font-size: 16px;
      text-align: center;
      font-weight: 600;
      border-bottom: 1px solid #f1c40f;
      padding: 12px 35px;
      margin: 0;
      font-family: 'Exo 2';
    }
    
    div.cart-logo {
      display: block;
      position: absolute;
      top: 0;
      padding: 16px 10px;
    }
    JavaScript & jQuery:

    Code:
    $(document).ready(function() {
      cartPullout();
      addLens();
    })
    
    var cartPullout = function() {
      $('body').on('click', '.cart-toggle', function(ev) {
        ev.preventDefault();
        $('body').toggleClass('cart-open');
        //alert(CartJS.cart.items);
      });
    };
    
    var addLens = function() {
      $('div#wrapper').on('click', '#add-lens', function(e) {
        e.preventDefault();
        CartJS.addItem(12345);
      })
    }
    Here's a direct link to the Codepen to see it in action. I've manually added the "Faux Line Item" in the cart to simulate X number of products on the customers end where being able to scroll is necessary.

    I appreciate any and all assistance!!

  2. #2
    Senior Coder deathshadow's Avatar
    Join Date
    Feb 2016
    Location
    Keene, NH
    Posts
    3,736
    Thanks
    5
    Thanked 535 Times in 521 Posts
    Quote Originally Posted by zombiegang View Post
    CSS is clearly not my strong point.
    As evidenced by your declaring things in the inaccessible "pixel" metric. If it's got text inside it, use EM, not PX... and the HTML is questionable too since you're using a P+class for what should likely be a H2. Best practice? Semantic markup of the content or a reasonable facsimile of future content BEFORE you even THINK about throwing style or behavior at it!

    You also seem to be using JavaScript for something we no longer need JavaScript to achieve.


    Sadly you're too new a member to post links, so the codepen isn't here...

    I'd have to see it live, but the first thing I'd do is likely axe around two thirds of your DIV as pointless and/or gibberish... and axe the JavaScript as a waste of code. Again not even JavaScript's job, much less the fat bloated train wreck of developer ignorance, incompetence, and outright ineptitude that is jQuery. Big tip, the ONLY thing you can learn from jQuery is how not to write --- or where to use -- JavaScript.

    As to the scrolling problem, axe ALL of your overflow-y states, that's what's screwing you over. The one you want to scroll set to overflow:auto and be done with it. EVERY other instance of overflow there is what's likely messing you up. At MOST for doing the animation you would want an overflow:hidden on the OUTER DIV, and then overflow:auto on the one around the content you want to scroll. TWO DIV, that's it. Everything else there should be some form of semantic markup. (aka tags other than DIV and SPAN)

    something like:

    Code:
    	<input type="checkbox" id="toggle_cart" class="toggle" hidden>
    	<label for="toggle_cart"></label>
    	<div id="cart">
    		<h2>Your Shopping Cart</h2>
    		<!-- apply the logo as generated content off the H2 -->
    		<ul><!-- a LIST of ITEMS -->
    			<li>
    				 Faux Item in the cart
    				 <!-- don't use breaks to do padding's job -->
    			</li><li>
    				 Faux Item in the cart
    			</li><li>
    				 Faux Item in the cart
    			</li><li>
    				 Faux Item in the cart
    			</li><li>
    				 Faux Item in the cart
    			</li><li>
    				 Faux Item in the cart
    			</li><li>
    				 Faux Item in the cart
    			</li><li>
    				 Faux Item in the cart
    			</li><li>
    				 Faux Item in the cart
    			</li><li>
    				 Faux Item in the cart
    			</li>
    		</ul>
    	<!-- #cart --></div>
    	
    	<div id="wrapper">
    		<label for="toggle_cart">View Cart</label>
    The big trick being something along the lines of:

    Code:
    .toggle + label {
    	position:fixed;
    	top:0;
    	left:-100%;
    	width:100%;
    	height:100%;
    
    }
    
    .toggle:checked + label {
    	left:0;
    }
    
    .toggle + label + div {
    	/*
    		use absolute positioning instead of display:none as setting 'none'
    		is harder to animate, and can cause screen readers and braille devices
    		to ignore the content!
    	*/
    	position:absolute;
    	left:-999em;
    }
    
    .toggle:checked + labediv {
    	left:0; /* or wherever you want it positioned */
    }
    
    #cart {
    	display:flex;
    	flex-direction:col;
    	max-height:50vh;
    }
    
    #cart ul {
    	flex:1 1 auto;
    	overflow:auto;
    }
    Untested, I'm on the laptop... but should give a general idea of the direction to head. SHOULD make the UL have a scrollbar if the content is taller than the container, which is set to half of the screen height. A slide-down animation could be simply added using transition and changing the max-height from 50% to 0, delaying the left transition.

    Oh, extra label after the input? Set to full screen behind the cart DIV makes it so clicking outside the cart closes it.

    See my tutorial on hamburger menus for more info on how all this works without the JS.

    https://cutcodedown.com/tutorial/mobileMenu
    “There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies.” – C.A.R. Hoare, The 1980 ACM Turing Award Lecture
    http://www.cutcodedown.com

  3. Users who have thanked deathshadow for this post:

    zombiegang (Oct 8th, 2019)

  4. #3
    New to the CF scene
    Join Date
    Oct 2019
    Posts
    2
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by deathshadow View Post
    As evidenced by your declaring things in the inaccessible "pixel" metric. If it's got text inside it, use EM, not PX... and the HTML is questionable too since you're using a P+class for what should likely be a H2. Best practice? Semantic markup of the content or a reasonable facsimile of future content BEFORE you even THINK about throwing style or behavior at it!

    You also seem to be using JavaScript for something we no longer need JavaScript to achieve.


    Sadly you're too new a member to post links, so the codepen isn't here...

    I'd have to see it live, but the first thing I'd do is likely axe around two thirds of your DIV as pointless and/or gibberish... and axe the JavaScript as a waste of code. Again not even JavaScript's job, much less the fat bloated train wreck of developer ignorance, incompetence, and outright ineptitude that is jQuery. Big tip, the ONLY thing you can learn from jQuery is how not to write --- or where to use -- JavaScript.

    As to the scrolling problem, axe ALL of your overflow-y states, that's what's screwing you over. The one you want to scroll set to overflow:auto and be done with it. EVERY other instance of overflow there is what's likely messing you up. At MOST for doing the animation you would want an overflow:hidden on the OUTER DIV, and then overflow:auto on the one around the content you want to scroll. TWO DIV, that's it. Everything else there should be some form of semantic markup. (aka tags other than DIV and SPAN)

    something like:

    Code:
    	<input type="checkbox" id="toggle_cart" class="toggle" hidden>
    	<label for="toggle_cart"></label>
    	<div id="cart">
    		<h2>Your Shopping Cart</h2>
    		<!-- apply the logo as generated content off the H2 -->
    		<ul><!-- a LIST of ITEMS -->
    			<li>
    				 Faux Item in the cart
    				 <!-- don't use breaks to do padding's job -->
    			</li><li>
    				 Faux Item in the cart
    			</li><li>
    				 Faux Item in the cart
    			</li><li>
    				 Faux Item in the cart
    			</li><li>
    				 Faux Item in the cart
    			</li><li>
    				 Faux Item in the cart
    			</li><li>
    				 Faux Item in the cart
    			</li><li>
    				 Faux Item in the cart
    			</li><li>
    				 Faux Item in the cart
    			</li><li>
    				 Faux Item in the cart
    			</li>
    		</ul>
    	<!-- #cart --></div>
    	
    	<div id="wrapper">
    		<label for="toggle_cart">View Cart</label>
    The big trick being something along the lines of:

    Code:
    .toggle + label {
    	position:fixed;
    	top:0;
    	left:-100%;
    	width:100%;
    	height:100%;
    
    }
    
    .toggle:checked + label {
    	left:0;
    }
    
    .toggle + label + div {
    	/*
    		use absolute positioning instead of display:none as setting 'none'
    		is harder to animate, and can cause screen readers and braille devices
    		to ignore the content!
    	*/
    	position:absolute;
    	left:-999em;
    }
    
    .toggle:checked + labediv {
    	left:0; /* or wherever you want it positioned */
    }
    
    #cart {
    	display:flex;
    	flex-direction:col;
    	max-height:50vh;
    }
    
    #cart ul {
    	flex:1 1 auto;
    	overflow:auto;
    }
    Untested, I'm on the laptop... but should give a general idea of the direction to head. SHOULD make the UL have a scrollbar if the content is taller than the container, which is set to half of the screen height. A slide-down animation could be simply added using transition and changing the max-height from 50% to 0, delaying the left transition.

    Oh, extra label after the input? Set to full screen behind the cart DIV makes it so clicking outside the cart closes it.

    See my tutorial on hamburger menus for more info on how all this works without the JS.

    https://cutcodedown.com/tutorial/mobileMenu
    Thank you for the reply and assistance! I followed your words and it was definitely the conflicting other overflow attributes on the parent elements. As for the questionable HTML & Unnecessary JS, I didn't really give too much information on the topic so I apologize. I'm no front end guy by any means, just wanted to get the basic animation & scrolling figured out before I started modifying the DOM using JS & jQuery. This is a shopping cart I'm developing for our Shopify website as our current 3rd part add-on cart is great for what it is but we've outgrown it. I'm utilizing CartJS on Shopify to add/remove/update items in the cart with it's included AJAX calls. Click listeners in jQuery for the Quantity change buttons (+/-) and the JS to rebuild the DOM within the cart-content class. The numerous <li>'s with forced line breaks rather than padding was just example of line items within the cart going off the page to achieve scrolling. I'm of course using margins on the line items to space them and padding within to keep everything in a nice lil rounded square.

    The scrolling within the cart now works when there's numerous line items when using overflow: auto

    Again, thank you so much for the help!


 

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •