Achieving a sticky scrollbar effect in CSS/JavaScript for scrolling within nested divs

I am trying to create a table with vertical scrolling for the entire table content. Additionally, I need two columns within the table to be scrollable horizontally, but the horizontal scrollbars disappear when the vertical scrollbar is present. How can I keep both vertical and horizontal scrollbars visible at all times?

For reference, here is an example on JSFiddle: Fiddle Example

https://i.sstatic.net/zpGqwz5n.png

#data {
  background: grey;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  
  height: 400px;
  width: 500px;
}

#splitter {
  display: flex;
  flex-direction: row;
  background: darkgrey;
  overflow-x: hidden;
  overflow-y: auto;
  align-items:start;
}

#right-content {
  background: Gainsboro;
  overflow-x: auto;
  overflow-y: hidden;
}

#left-content {
  background: Gainsboro;
  overflow-x: auto;
  overflow-y: hidden;
}

div {
  margin: 10px;
}

p {
  padding: 2px;
  margin: 0px;
}
<div id="data">
  <div id="splitter">
    <div id="left-content">
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
    </div>
    <div id="right-content">
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
    </div>
  </div>
</div>

Answer №1

Here is a code snippet that might be useful for you to experiment with:

<!DOCTYPE html>
<html>
<head>
    <style>
        html, body {
        height: 100%;
    }
body {
  display: flex;
  padding: 0;
  margin: 0;
}

.myDiv {
  height: 50%;
  overflow: scroll;
  background: LightGrey
}

span {
  width: 100vw;
  height: 150vh;
  display: block;
  background: darkslategrey;
}
</style>
</head>
<body>
<div class="myDiv" id="left-content" style="width:20%" >
      <p>Content on the left side</p>
      <p>Content on the left side</p>
      <p>Content on the left side</p>
      <p>Content on the left side</p>
      <p>Content on the left side</p>
      <span>     
    </div>
    <div class="myDiv" id="right-content" style="width:30%">
      <p>Content on the right side that should horizontally scroll</p>
      <p>Content on the right side that should horizontally scroll</p>
      <p>Content on the right side that should horizontally scroll</p>
      <span>     
    </div>

<script type="text/javascript">
    const divs = document.querySelectorAll('.myDiv');
    divs.forEach(div => div.addEventListener( 'scroll', e => {
    const offsetTop = div.scrollTop / (div.scrollHeight - div.clientHeight);
    const offsetLeft = div.scrollLeft / (div.scrollWidth - div.clientWidth);
    divs.forEach(d => {
       d.scrollTop = offsetTop * (d.scrollHeight - d.clientHeight);
      d.scrollLeft = offsetLeft * (d.scrollWidth - d.clientWidth);
    });
  }) );
</script>
</body>
</html>

Answer №2

Here is an example of how you can utilize this code:

#data {
  background: grey;
  overflow-x: auto;
  display: inline-block;
  flex-direction: column;
  width: 500px;
}

#splitter {
  display: flex;
  flex-direction: row;
  background: darkgrey;
  align-items:start;
  width:655px;
}

#right-content {
    background: Gainsboro;
    overflow-y: auto;
    width: 450px;
    height: 350px;
}

#left-content {
    background: Gainsboro;
    overflow-y: auto;
    width:180px;
    height: 350px;
}

div {
  margin: 10px;
}

p {
  padding: 2px;
  margin: 0px;
}
<div id="data">
  <div id="splitter">
    <div id="left-content">
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
      <p>LeftColumnLeftColumn</p>
    </div>
    <div id="right-content">
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>
      <p>RightColumnWithLongTextThatShouldBeScrollableHorizontally</p>          
    </div>
  </div>
</div>

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

Troubleshooting: Images not displaying on webpage due to Ajax, JQuery, and JavaScript integration

I'm currently working on building a dynamic photo gallery using Ajax and JQuery in Javascript. I have set up a directory named "images" in Visual Studio Code and it contains my selection of 5 images. However, when I click the "next" and "previous" but ...

What is the most effective way to reduce the spacing between columns in Bootstrap while maintaining consistent spacing on the outer edges?

I have set up my bootstrap columns as shown below: <div class="col-6"> <a href="gallerij/stockfotos/boeken" class="catphotowrap"> <div class="catphotodiv"> <img class=&quo ...

What could be the reason for my function throwing a TypeError with the message "<function> is not a function"?

Every time I try to call a function that clearly appears to be defined as a function, I continuously receive the error message: TypeError: [function name] is not a function. To demonstrate the issue, here is a simple example: main.ts import someFunction ...

In JavaScript with Node.js, how can one verify a file's size and only download the initial kilobyte of the file?

When using Javascript/Node JS to download a file, you can check the file size and download only the first kilobyte of the file. This is useful if you want to hash the first kb and compare it with the hash of the complete file. If the hashes match and the ...

Developing a MySQL DB-driven Node.js dashboard without the need for a poller

After exploring various StackOverflow posts on the topic, I haven't been able to find a solution that fits my specific situation. We have multiple monitoring instances across our network, each monitoring different environments (such as Nagios, Icinga ...

Angular 6 issue: Bootstrap 4 carousel indicators not responsive to clicks

I am currently working on incorporating a Bootstrap 4 carousel into my application, but I seem to be encountering issues with the indicators. Ideally, clicking on any of them should navigate you to the corresponding photo, similar to this example: https:// ...

What is the best way to retrieve the current URL with a hashtag symbol using JavaScript?

I am attempting to display the current URL after the question mark with a hash symbol using PHP, but unfortunately, it is not achievable. Therefore, I need to utilize JavaScript for this task, even though I have limited knowledge of it. This is the specifi ...

What's the best way to rearrange Bootstrap cards from a horizontal layout to a vertical layout for improved responsiveness?

I'm currently working with Bootstrap to align two cards horizontally, but I also want to ensure that mobile users can view the cards stacked in a column layout. I've experimented with adding 'flex-direction' in combination with the @med ...

Retrieve class property in Angular by its name

How can I retrieve an array from a class like the one below without using a switch statement, dictionary, or other collection to look up the name passed into the method? export class ProcessOptions { Arm = [{ name: 'Expedited Review ("ER") ...

Issues with HTML keycodes not functioning properly in Firefox

Here is the code I am using: function restrictInput(e) { var charCode = (e.which) ? e.which : ((e.charCode) ? e.charCode : ((e.keyCode) ? e.keyCode : 0)); if((charCode < 48 || charCode > 57) && ( ...

Having trouble transforming the JSON object into a usable format

Although I'm still getting the hang of JSON, please bear with me if this seems like a rookie mistake. My approach involves sending a query to a local file that performs a cURL operation on an external site's API and returns a JSON object. Due to ...

Using ReactJS and Ruby on Rails to implement an AJAX delete request

There is a component named Items residing inside a parent component called ItemsContainer. A click on a button within the Items component triggers an Ajax function to delete that specific Item. However, I am encountering a 500 error message at the moment ...

Identifying dates in pandas index and header: A comprehensive guide

After utilizing the HTML parser to extract a table from a particular website, the current output looks similar to the following: Current Output: 1 Sep 2 Sep 3 Sep 4 Sep 00:00 11 47 54 10 ...

Leveraging Promises in AngularJS to create a chain between two separate controllers

I've developed a provider called MyRestServices to handle my REST-Services: app.provider('MyRestServices', function() { this.baseUrl = null; this.setBaseUrl = function(_baseUrl) { this.baseUrl = _baseUrl; }; this.$get = [' ...

Ways to move to the next line following the navigation bar text

Below is the code snippet that I am working with: <nav class="navbar navbar-expand-sm navbar-dark "> <div class="container-fluid"> <a class="navbar-brand" href="#">LOREM IPSUM</a&g ...

What steps can I take to stop the textfield from automatically changing the ID "myid" to "myid-tokenfield" when using Tokenfield for Bootstrap?

While utilizing Tokenfield for Bootstrap, I have encountered an issue where the id of my textfield gets modified from myid to myid-tokenfield. In order to properly interact with the search engine I am using, this textfield must maintain a specific id. The ...

I encountered an issue with Material UI tabs showing the error message: "Failed prop type: The prop `children` is not supported. Please remove it."

Recently, I started using Material UI tabs in my project for the first time. Everything seems to be working fine except for one issue that keeps showing up in the console while running the project: Failed prop type: The prop `children` is not supported. Pl ...

What is the best way to horizontally align a group of list elements while also displaying them side by side?

I've been working on creating a Sign Up page and here is the code I have so far: <div class="form"> <ul class="tab-group"> <li class="tabsignup"><a href="/signup.html">Sign Up</a ...

Positioning borders in an Outlook table

While experimenting with Mjml, I encountered an issue where I struggled to place the border exactly where it needed to be in order for my table to function correctly. It was a bit of a do-it-yourself solution, but it was the only way I managed to make it w ...

Encase React black box block components and incorporate DOM event listeners

In my React component, I am using a standard interface to wrap various other components that act as "blackbox" plugins, since I may not have authored them. These plugins must meet certain requirements outlined in the interface to work within the plugin wra ...