3

How would one go about using CSS properties to allow a div with nested divs, which have absolute position defined, to be able to scroll once the defined position of those divs goes outside of their parent div?

I've stripped down my project to (hopefully) contain only what you need below, and I recognize that there are much cleaner ways to do this with the example that I'm presenting here, but figure it's worth asking because someone may have insight that I (and others) can learn from. In my example, there are div 'boxes' (they have class=stuffbox) being placed inside of a div (has class=innerstuffcols) and they overflow the vertical bounds of their parent div.

    #mainHeader {
     background-color: #999999;
     color: #ffffff;
     position: absolute;
     width: 100%;
     height: 5%;
     left: 0;
     top: 0;
    }

    #mainPlace {
        position:absolute;
     width:100%;
     height:95%;
     left:0;
     top:5%;
     overflow:hidden;
    }

    #mainTable {
     position:absolute;
     left:0;
     height:100%;
     width: 85%;
     overflow:hidden;
    }

    #mainMenu {
     position:absolute;
     left:85%;
     right:0;
     height:100%;
    }


    #tablebody {
     height: 100%;
     width: 100%;
    }

    th.tableheaders {
     border:1px solid black;
     height: 5%
    }

    td.someCols {
     border:1px solid black;
    }

    table, th, td {
     border-collapse: collapse;
    }

    div.innerstuffCols {
     height: 100%;
     width:100%;
     overflow-y: auto;
     overflow-x: hidden;
    }

    div.stuffbox {
     height:200px;
     position:absolute;
     width:200px;
     left:5px;
     text-align: center;
     background-color: #f1f1f1;
    }
<html lang="en-US">
 <head>
  <meta charset="utf-8">
  <title>stuff</title>
  <link rel="stylesheet" href="st.css">
 </head>
 <body>

  <div id="mainHeader">
   <p align="center"> random header here </p>
  </div>

  <div id="mainPlace">
   <div id="mainTable">
    <table style='width:100%;height:100%;position:absolute;top:0;bottom:0;left:0;border:1px solid black'>
     <tr id='tableheader'>
      <th class='tableheaders'>header 1</th>
      <th class='tableheaders'>header 2</th>
     </tr>

     <tr id='tablebody'>
      <td class='someCols'>
       <div class='innerstuffCols'>
        <div class='stuffbox' style='top:55px;'> stuff 1 </div>
        <div class='stuffbox' style='top:265px;'> stuff 2 </div> 
        <div class='stuffbox' style='top:475px;'> stuff 3 </div>
        <div class='stuffbox' style='top:685px;'> stuff 4 </div>
        <div class='stuffbox' style='top:895px;'> stuff 5 </div>
        <div class='stuffbox' style='top:1105px;'> stuff 6 </div> 
       </div>
      </td>
      <td class='someCols'>
       <div class='innerstuffCols'>
       some other stuff
       </div>
      </td>
     </tr>

    </table>

   </div>
   <div id="mainMenu"> 
    <p> some stuff here </p>
   </div>
    </div>
    </body>
    </html>

As mentioned, I know that within the scope of only what is presented in my example, there are better ways to do this (making position something other than absolute, etc..) but for various reasons related to the much larger project (and at this point - academic curiosity) I'd prefer to see an explanation of how to get the example above working while keeping those divs with their absolute position.

Apologies if the wording of the question is poor (let me know and I'll take another shot at it), but hopefully the example makes my intention clear.

Thanks in advance.

codeAndStuff
  • 507
  • 6
  • 19

1 Answers1

3

Use position:relative to cause the absolute-positioned elements to be positioned relative to that container, and overflow:scroll to make it scrollable. (You could also omit the div and do this directly on the table cel.)

#mainHeader {
  background-color: #999999;
  color: #ffffff;
  position: absolute;
  width: 100%;
  height: 5%;
  left: 0;
  top: 0;
}

#mainPlace {
  position: absolute;
  width: 100%;
  height: 95%;
  left: 0;
  top: 5%;
  overflow: hidden;
}

#mainTable {
  position: absolute;
  left: 0;
  height: 100%;
  width: 85%;
  overflow: hidden;
}

#mainMenu {
  position: absolute;
  left: 85%;
  right: 0;
  height: 100%;
}

#tablebody {
  height: 100%;
  width: 100%;
}

th.tableheaders {
  border: 1px solid black;
  height: 5%
}

td.someCols {
  border: 1px solid black;
}

table,
th,
td {
  border-collapse: collapse;
}

.innerstuffCols {
  position: relative;
  overflow-y: scroll;
  width: 100%; 
  height: 100%;
}

div.stuffbox {
  height: 200px;
  position: absolute;
  width: 200px;
  left: 5px;
  text-align: center;
  background-color: #f1f1f1;
}
<div id="mainHeader">
  <p align="center"> random header here </p>
</div>

<div id="mainPlace">
  <div id="mainTable">
    <table style='width:100%;height:100%;position:absolute;top:0;bottom:0;left:0;border:1px solid black'>
      <tr id='tableheader'>
        <th class='tableheaders'>header 1</th>
        <th class='tableheaders'>header 2</th>
      </tr>

      <tr id='tablebody'>
        <td class='someCols'>
          <div class='innerstuffCols'>
            <div class='stuffbox' style='top:55px;'> stuff 1 </div>
            <div class='stuffbox' style='top:265px;'> stuff 2 </div>
            <div class='stuffbox' style='top:475px;'> stuff 3 </div>
            <div class='stuffbox' style='top:685px;'> stuff 4 </div>
            <div class='stuffbox' style='top:895px;'> stuff 5 </div>
            <div class='stuffbox' style='top:1105px;'> stuff 6 </div>
          </div>
        </td>
        <td class='someCols'>
          <div class='innerstuffCols'>
            some other stuff
          </div>
        </td>
      </tr>

    </table>

  </div>
  <div id="mainMenu">
    <p> some stuff here </p>
  </div>
</div>
Daniel Beck
  • 20,653
  • 5
  • 38
  • 53
  • Thanks, this answered my question as posed. Is there a way to allow visible horizontal overflow (without scrolling) while preserving this vertical scrolling that you've presented? E.g. to allow the nested divs to visibly 'stick out' of the sides of their parent div? – codeAndStuff Jul 31 '18 at 17:33
  • 1
    That *should* be as simple as `overflow-y: scroll; overflow-x: visible`, but unfortunately a weird edge case in the html spec prevents that; see https://stackoverflow.com/a/6433475/3412322 – Daniel Beck Jul 31 '18 at 17:40
  • 1
    (It can be done using separate dom elements for each overflow, though; some examples on that same page.) – Daniel Beck Jul 31 '18 at 17:44
  • yes, thanks for the redirect to that SO post. This will give me what I need and was actually along the lines of what I'd already started putting together as a workaround to setting x/y overflow independent to one another not working the way I'd have expected/wanted. – codeAndStuff Jul 31 '18 at 17:53
  • actually - having issues making that type of solution work within the context of how this is set up. I've tried various nesting/config options and still run into the same roadblock. Do you see a straightforward way with this example to make that possible? – codeAndStuff Jul 31 '18 at 19:07
  • After some experimentation, I'm a bit ashamed to admit that the best I can figure is to set a width of greater than 100% on the element. It's stupid but it works ¯\\_(ツ)_/¯ – Daniel Beck Jul 31 '18 at 19:40
  • assuming you mean doing something like setting width=200% (or anything >100%) for innerstuffcols, how do you keep the scrollbar in a reasonable spot then? – codeAndStuff Jul 31 '18 at 20:08
  • Ah, good point, that's not a good solution at all then, sorry! – Daniel Beck Jul 31 '18 at 21:39
  • 1
    no worries at all thanks for the push in the right direction. I'm going to break this out into a new question. – codeAndStuff Jul 31 '18 at 22:53
  • question posed in this comments thread has been moved into its own question thread: https://stackoverflow.com/questions/51623273 – codeAndStuff Jul 31 '18 at 23:13