Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way I can place a space between my table and scrollbars when using overflow-x: auto;"

Tags:

html

css

I have a simple table like this:

<div id="table-overflow">
   <div>
      <table>
         ...
         ...
      </table>
   </div>
</div>

    #table-overflow {
        position: absolute;
        top: 10rem;
        right: 3rem;
        left: 3rem;
        bottom: 2rem;
        display: block;
        overflow-x: auto;
    }

When there are many rows and columns then scrollbars appear as expected. When the width is more than the table I see a vertical scrollbar on the right and the table data goes right up to this scrollbar. Is there some way I can have a space to the left of the vertical scroll bar and a space above the horizontal scrollbar without using a jQuery scrollbar plugin?

What I would like to see is something like this:

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx v
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx v
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx v
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx v

hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh

Where v is the vertical scrollbar, h is the horizontal scrollbar and x is the data

like image 760
Samantha J T Star Avatar asked Dec 09 '13 04:12

Samantha J T Star


4 Answers

Well, I've got some solution:

HTML:

<div id="table-overflow">
  <div class="screen">
    <div class="right"></div>
    <div class="bottom"></div>
  </div>

  <div class="table">
    <div>
      <table>
        <tr><td>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</td></tr>
        <tr><td>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1</td></tr>
        <tr><td>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1</td></tr>
      </table>
      <div class="fix-right"></div>
    </div>
  </div>
</div>

CSS:

#table-overflow {
  position: absolute;
  top: 10rem;
  right: 3rem;
  left: 3rem;
  bottom: 2rem;
  display: block;
  padding-right: 21px;
  padding-bottom: 21px;
}

#table-overflow > div.table {
  position: absolute;
  overflow: scroll;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 9;
  padding: 0 10px 8px 0;
}

#table-overflow > div.table > div {
  white-space: nowrap;
}

#table-overflow > div.table table {
  display: inline-block;
}

#table-overflow > div.table div.fix-right {
  display: inline-block;
  width: 10px;
  height: 10px;
}

div.screen {
  position: absolute;
  left: 0;
  top: 0;
  right: 21px;
  bottom: 21px;
}

div.right {
  background: red;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 10px;
  z-index: 10;
}

div.bottom {
  background: red;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 10px;
  z-index: 10;
}

See http://jsbin.com/OGuHagaz/3/edit?html,css,output for details (tested only in Chrome).

The idea is: there are created 2 divs which are absolutely positioned on the screen which is shown above the table, and this "screen" excludes 21px from bottom and right which are taken by scrollbars.

Then on it there are placed two divs: "bottom" and "right" which have height and width of your wish. I set up background red to show in more understandable way how it works.

Also "fix-right" and div."table" are fixing the problem of scrolling under the screen by padding (for bottom line) and "fix-right" width (for right line).

Unfortunately, this method has two problems:

  1. not working for "overflow: auto" but for "overflow: scroll", at least in the way it is not adapted with some JavaScript to detect if the width of table is greater than container div. Also, if the size is going to be changed, probably you should track for event "resize" and then change some numbers in css
  2. in different browsers the width of a scrollbar can differ: take this into account

Hope this helps you.

like image 65
smnbbrv Avatar answered Nov 07 '22 20:11

smnbbrv


Works but with consequences

See this fiddle (and resize to get to scroll or not scroll to see effect). It uses the following CSS:

#table-overflow {
    position: absolute;
    top: 10rem;
    right: 3rem;
    left: 3rem;
    bottom: 2rem;
}

#table-overflow > div {
    height: 100%;
    width: 100%;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    overflow-x: auto;
}
#table-overflow > div:after {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: -1; /*allow scroll bars to show */
/* the following hides table to create gap 
   10px is approx. desired gap
   16px is approx. scroll bar size
   approximations will work fine cross broswers
*/
border-right: 26px solid white; 
border-bottom: 26px solid white;
}
#table-overflow > div > table {
    position: relative;
    z-index: -1; /* push table below #table-overflow > div:after */
    /*The following = border width for hiding,
      10px is needed for full scroll to offset "gap"
      16px is needed for full visibility of table 
      when no scroll bars are needed
    */
    padding-right: 26px; 
    padding-bottom: 26px;
}

The problem is, css has not way of knowing "when" something is in an overflow state or not (else we could adjust things to work better). So this solution has to incorporate a constant bottom and right side spacing (whether in the overflow state or not). Also, it has to push the table behind the :after element making the gap. This results in the following limitations:

  1. If anything in the table needs to be clicked, it cannot be (could be biggest killer).
  2. There is always an extra amount within the scrolling table that is just "wasted space" to the right and bottom (here 26px).
  3. Nice looking borders on the table will be challenging (if not impossible to really get nice), if that is wanted.
  4. A solid color background is needed for it to look good.

With some creative javascript implementations, some of these things could be minimized in their negative effects (resizing the offsets based off overflow state or not).

like image 34
ScottS Avatar answered Nov 07 '22 19:11

ScottS


#table-overflow {
    padding: 20px;
}

or

#table-overflow table {
    padding: 20px;
}

Depends on your layout and how would you like it to look.


Since I got no reply, see it here: http://jsfiddle.net/MDgb9/

And the bigger version here: http://jsfiddle.net/MDgb9/2/

like image 33
Shomz Avatar answered Nov 07 '22 19:11

Shomz


Sorry, I over thought the whole thing on the first attempt...

I think you can get the desired look with a little padding and a box-shadow alone... Its really very similar to ScottS' approach, its a little more simplified and uses the pointer-events property to resolve the issue with mouse events on the table.

Working Example

#table-overflow {
    pointer-events: none; /* allow pointer events to pass through */
    position: absolute;
    top: 10rem;
    right: 3rem;
    left: 3rem;
    bottom: 2rem;
    display: block;
    overflow-x: auto;
    box-shadow: -30px -30px blue inset;
}
table {
    pointer-events: auto; /* reset the pointer-event property to handle inheritance */
    padding:0px 20px 20px 0px;
    position:relative;
    z-index: -1; /* places the table beneath #table-overflow */
}

<div id="table-overflow">
    <table>
        <tr>
            <td>XXXXXXXXXXXX...
like image 38
apaul Avatar answered Nov 07 '22 18:11

apaul