Adaptive Table Layout that Creates a Page-breaking Design

I have a page layout with three columns: a fixed-width left-hand navigation, a responsive content column, and a fixed-width right-hand navigation. The issue arises when the content in the middle column includes HTML tables that sometimes exceed the available horizontal space. Ideally, these tables should scroll horizontally within the bounds of the content column.

However, what actually happens is that the tables expand to fill the entire width of the screen, causing the columns to stack vertically instead of appearing next to each other. To address this, I implemented a workaround by setting up a watcher on the window resize event to adjust the max-width of the tables dynamically. While functional, this solution is sluggish and not sustainable in the long run.

I've been attempting to tackle this problem using pure CSS but haven't had much success so far, aside from using max-width which is not an ideal fix. I suspect that this issue may be related to a similar challenge I faced previously.

new Vue({
  el: "#app",
  data: {}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="cba9a4a4bfb8bfb9aabbe6bdbeae8bf9e5fee5fb">[email protected]</a>/dist/bootstrap-vue.min.js"></script>
<link href="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d2b0bdbda6a1a6a0b3a292e6fce6fce3">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="25474a4a5156515744550853504065170b100b-15">[email protected]</a>/dist/bootstrap-vue.css" rel="stylesheet" />

<div id="app">
  <b-container fluid>
    <b-row>
      <b-col cols="auto">
        <div>left col</div>
      </b-col>
      <b-col>
        <b-button class="w-100" v-b-toggle="'collapse'">center col</b-button>
        <b-collapse id="collapse">
          <div class="w-100">
            <b-table-simple responsive>
              <b-thead>
                <b-tr>
                  <b-th>
                    Question:
                  </b-th>
                  <b-th v-for="i in 50" :key="i">{{ i }}
                  </b-th>
                </b-tr>
              </b-thead>
            </b-table-simple>
          </div>
        </b-collapse>
      </b-col>
      <b-col cols="auto">
        <div>right col</div>
      </b-col>
    </b-row>
  </b-container>
</div>

Answer №1

To improve your page layout, avoid using b-row and b-col. Instead, set a min-width for the side panels and make the middle container's width 100% with overflow-x: auto. Then, enclose everything in a container with display: flex.

I have tested this solution in Chrome, Chromium Edge, and Firefox.

new Vue({
  el: "#app"
});
.table-wrap {
  width: 100%;
  overflow-x: auto;
}

.side-panel {
  min-width: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a4c6cbcbd0d7d0d6c5d489d2d1c1e4968a918a94">[email protected]</a>/dist/bootstrap-vue.min.js"></script>
<link href="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="55373a3a2126212734257823203015677b657b657827367b6464">[email protected]</a>/dist/bootstrap-vue.css" rel="stylesheet" />
<link href="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bddfd2d2c9cec9cfdccdfd89938c938e">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet" />

<div id="app">
  <b-container fluid>
    <div class="d-flex">
      <div class="side-panel">
        <div>left col</div>
      </div>
      <div class="table-wrap">
        <b-button class="w-100" v-b-toggle="'collapse'">center col</b-button>
        <b-collapse id="collapse">
          <div class="w-100">
            <b-table-simple responsive>
              <b-thead>
                <b-tr>
                  <b-th>
                    Question:
                  </b-th>
                  <b-th v-for="i in 50" :key="i">{{ i }}
                  </b-th>
                </b-tr>
              </b-thead>
            </b-table-simple>
          </div>
        </b-collapse>
      </div>
      <div class="side-panel">
        <div>right col</div>
      </div>
    </div>
  </b-container>
</div>

Answer №2

After running into issues with using flex-box as recommended by Hiws's answer due to nesting problems in my code, I decided to focus on optimizing my brute-force solution since I was running out of ideas. Initially, I faced performance challenges because I had a watcher for the page width that I was passing to four table components on my page to dynamically set max-width. Instead of setting max-width individually on each table component, I opted to set it on the column containing all four, reducing four dynamic widths down to one. This change not only solved my problem but also improved the responsiveness and seamlessness of the design.

Column JavaScript:

  data() {
    return {
      windowWidth: window.innerWidth
    };
  },
  computed: {
    // magic number
    maxWidth() {
      return `${this.windowWidth - 612}px`;
    }
  },
  mounted() {
    window.addEventListener("resize", this.widthHandler);
  },
  destroyed() {
    window.removeEventListener("resize", this.widthHandler);
  },
  methods: {
    widthHandler() {
      this.windowWidth = window.innerWidth;
    }
  }

Column CSS:

<b-col :style="{ 'max-width': maxWidth }">

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

Assistance needed with CSS - making an element occupy the entire remaining vertical space

Although I'm quite confident in my CSS/XHTML abilities, this particular issue has me stumped. You can view the problem here: - (please note that the website is still under development, most features are not functional, and it's subject to frequ ...

The combination of VueJS and Webpack Dev Server is having trouble hot reloading URL subpaths

My application operates within the subdirectory http://localhost:8080/admin_suffix The variable suffix is an ENV variable that I can modify and define in a .env file. After starting the webpack dev server, accessing http://localhost:8080/admin_suffix fun ...

Next.js is refusing to render an array of HTML elements

Consider this scenario where I have a block of code in TypeScript that attempts to create and display a list of elements. Here is a sample implementation: const MenuList = ():ReactElement => { const router = useRouter(), liElements:any = []; con ...

Is there a way to occupy the extra space while working with an inline unordered list?

Using this unique CSS code, I've managed to give my unordered lists a touch of elegance: ul, li { padding: 0px; margin-left: 0px; margin-bottom: 0px; display: inline; } li { border: solid 1px #333333; margin-right: 5px; padding: 2p ...

"Add a touch of magic to your webpage with text effects that appear

I am looking to create a glowing text effect, and I stumbled upon this resource. http://jsfiddle.net/karim79/G3J6V/1/ However, the client prefers the text effect to appear after the page loads, rather than on hover. Unfortunately, I do not have experien ...

Guide on showcasing jQuery variable values in PHP on a single page

I have some JavaScript and PHP code that I need help with. I want to assign a jQuery variable value to a PHP variable called $nicks, and then echo the value of $nicks on the same page. <script type="text/javascript"> var axel = 131.5678466; < ...

How to align items to the left and center within a div?

How can I position the items inside a div in such a way that one element is centered and the other is aligned to the left? I attempted using flexbox, but found it difficult without introducing a hidden third element or justifying content. Another approac ...

swap between style sheets glitching

My website features two stylesheets, one for day mode and one for night mode. There is an image on the site that triggers a function with an onclick event to switch between the two stylesheets. However, when new visitors click the button for the first ti ...

Vue - Issue with passing props data to child component after fetching data

Struggling to pass the data retrieved from a JSON fetch to a child component in order to create v-cards. Despite investing hours into debugging, I am unable to identify the issue. The only noticeable observation is that the prop in the parent component fai ...

Is there a way to have a span update its color upon clicking a link?

I have 4 Spans and I'm looking to create an interactive feature where clicking a link in a span changes the color of that span. Additionally, when another link in a different span is clicked, the color of that span changes while reverting the previous ...

Add motion to the div element when hovering and moving the mouse away

Looking to add animation to a list moving from left to right and vice versa. Now, I want the list to animate from left to right when the mouse hovers over the div, and then animate from right to left when the mouse leaves the div. Can someone assist me wit ...

Using ASP.NET MVC to generate dynamic CSS styles

I am seeking a solution that will allow me to achieve the following objectives: Retrieve dynamically generated CSS from an action method Select a CSS file based on request parameters or cookies Utilize a tool for combining and compressing (minifying) CS ...

Update the headers of the axios.create instance that is exported by Axios

I have a single api.js file that exports an instance of axios.create() by default: import axios from 'axios' import Cookies from 'js-cookie' const api = axios.create({ baseURL: process.env.VUE_APP_API_URL, timeout: 10000, headers ...

Navigating in Vue.js using Ruby on Rails routes

I'm in the process of developing an application that utilizes a Ruby on Rails backend along with a Vue.js frontend. This application is designed as a single page app, and I am leveraging the webpacker gem to compile my main JS file. After integrating ...

Animated slide-out menu with icon using jQuery

I am in the process of creating a menu using CSS and jQuery that will display an icon for each menu item. When a user hovers over a menu item for 0.5 seconds, I want it to slide slowly to the left to show the name of the menu. This is similar to what you ...

Using Twitter bootstrap with Node.js and Express framework

Is it possible to integrate Twitter Bootstrap with Node.js and Express? I understand that I need to place CSS and Javascript files in the ./public directory (if it's set as default). However, when trying to implement Twitter Bootstrap on Node.js and ...

Like button for Facebook located at the bottom of a static webpage

I am facing an issue with my web application where it does not scroll properly, especially when there is a Facebook button at the bottom. The behavior in Chrome and Firefox is inconsistent and causing some trouble. In Chrome, the div repositions correctly ...

I am having trouble getting my custom CSS file to be applied to my website on Github pages

I attempted to upload a custom CSS file to apply on The raw CSS file is located at: https://raw.githubusercontent.com/themomoravi/SoundOff-Website/master/styles.css I used the following as my href since it directly links to the raw CSS file: href="http ...

Managing the vertical positioning of grid items: tips and tricks

Is there a way to make the hexagons in my grid responsive to the layout, so that their height and width remain fixed relative to their container? Currently, they are overflowing from the grid container as shown in this jsfiddle: https://jsfiddle.net/gv5wc1 ...

Customizing CSS in Angular Components: Taking Control of Style Overrides

I am new to working with Angular and HTML. Currently, I have two different components named componentA and componentB, each having their own .html, .css, and .ts files. In the componentA.css file, I have defined some styles like: .compA-style { font- ...