bootstrap-vue / bootstrap-vue

BootstrapVue provides one of the most comprehensive implementations of Bootstrap v4 for Vue.js. With extensive and automated WAI-ARIA accessibility markup.
https://bootstrap-vue.org
MIT License
14.51k stars 1.88k forks source link

b-table sticky-header creates a fixed table max-height, this looks bad on different screen sizes #5842

Closed vsirghii closed 3 years ago

vsirghii commented 4 years ago

Hello, I need a table header to be freeze and content scroll-able. sticky-header property works fine, but it sets fixed table height which makes the table either unnecessary short on bigger height screens, or scrolls the whole page content on smaller height screens. As I understand from docs, I can only set sticky-header property to a hard-codded height in pixels, nothing else is working there (ex, 'auto', '100%', 'inherit' - this would have no effect) Is there a way to make the table with sticky-header some kind of a responsive max-height relative to the current screen height?

Thank you

Long Short
G-IV commented 4 years ago

I reread this a couple times because I was a little confused -> the sticky header takes a "{n}px" argument and uses it as a max-height property.

From your screenshots, it looks like you are using a modal window. I have a working modal window with a scrolling table set up (you can see the options I used below my answer). I am using Vue, there may be some translation needed if you are using a different front end development framework or just straight bootstrap.

I'm sorry if I misunderstood your question `<b-modal id="myModal" :title="title" size="xl" centered :hide-footer="true" :hide-header-close="true"

<b-table striped hover small ref="tableRef" :fields="tableFields" :items="tableItems" no-border-collapse sticky-header="600px"

`

I clearly don't know how to make the code pretty here... sorry about that.

Also, here is what is rendered in HTML (just to indicate that the sticky-header value is treated as a max-height): 2020-10-19 16_35_37-Window

vsirghii commented 4 years ago

Thanks George for your answer! Yes, I also use Vue. Sorry for the confusion I brought here. In short, to clarify my question. I understand that sticky header takes a "{n}px" as a max-height css property. And that's exactly the problem, because max-height makes the table height either too short on longer screens, or it scrolls up the header on screens that are shorter than the table's max-height (when you switch the application from one mobile screen to another). Currently, as a work around, I'm just dynamically binding a calculated value to the "sticky-header" property when the current screen height changes (say users rotate their device from portrait to landscape orientation). But that doesn't fit the table height exactly by the screen height. It would be way cleaner if "sticky-header" could take some other css max-height values like "100%", "auto" etc., wouldn't be?

funkyfisch commented 4 years ago

@vsirghii

Providing other css max-height values will not help the problem AFAIK, since then you have to delegate the code stating the height in pixels into the container of the table. For example:

<div style="height: 450px;">
  <b-table sticky="100%">
  </b-table>
</div>

So setting the table to 100% wouldn't do anything if the parent container has no hard-defined height, or if its container in turn has no hard-defined height.

I am working on a similar problem, where my table is in the main content container, and a navbar is pushing the main content down.

<div id="app">
  <b-navbar>
  ...
  </b-navbar>

  <b-container flex>
    <b-table>
    </b-table>
  </b-container>
</div>

Ideally the best option would be to have the to somehow be set to the height that remains after subtracting the and then center the table into the .

However right now, I use a window listener to dynamically calculate 3/4ths of the window.innerHeight and apply that as a table height or if the height is less than 400 px, apply a static 300px height.

Maybe you need to read window.innerWidth when you change orientation if it overflows, not sure how device orientation affects what is considered the width and height of the window

vsirghii commented 3 years ago

Thanks @funkyfisch for your input. Yeah, window.innerHeight(), that's exactly what I'm currently using for my dynamic calculations. Something along these lines, as an example in case somebody else will be wondering around the same question:

mounted () {
    var self = this
    // to update b-table max-height to have a freeze header (sticky-header makes fixed max-height only regardless the screen height)
    // placed a new issue in Git, see if we get any response.
    self.$nextTick(() => {
       window.addEventListener('resize', () => {
         // debugger
         self.btableMaxHeight = (window.innerHeight - offset).toString() + 'px' // where offset is some kind of constant margin you need from the top
       })
     })
  },
  beforeDestroy() {
    window.removeEventListener('resize', () => {})
  }

I just thought that I might missing some simpler solution (like a CSS for example). But it appears it's has to be handled manually.

Thank you all responding here.

andysgithub commented 3 years ago

Try: sticky-header="70vh" Adjust the value according to the percentage viewport height occupied by the table.

jamxval commented 2 years ago

why it doesn't supports CSS calc like 'max-height: calc(70vh - 10rem)' ?