agapetos agapetos - 3 months ago 7
CSS Question

CSS layout fixed bottom, variable height

this is the problem that I have been struggling with:

the example

So, I have this right bar with three sections ("Arhiva", "Naznake" and "Svi Ĩlanci"). The first and second one have static positioning and have variable height (based on the data). The second one does have a maximum height.
The third one gives me problems. I want to fix it's bottom to the bottom of the right bar, and the top to the bottom of the "Naznake" (the second section). So far it has only two small boxes inside, but as soon as I will the database it will overflow beneat the right bar.
Here is the problem:
- if I use height:100% - it will still overflow underneat for the height of the first two elements.
- if I use calc(height:100% - some falue) it would solve this problem, but as soon as either first or second section change their height, it will again stop working the way it should.

So, this is my dillema - how to fix bottom of the lowest section to the bottom of its parrent div, and the top to the bottom of the preceeding sibbling div and still be able to scroll it when it is larger than the available area?

Here is my relevant HTML:

<div id="articlebar">
<h1><?php echo lang('ARCHIVE_TITLE');?></h1>
<section id="archiveSpace"><?php echo $godine->prepare_years($db); ?><div style="clear:both"></div></section>
<h1><?php echo lang('TAGS');?></h1>
<section id="tagSpace"><?php echo $tagovi->prepare_tags($db); ?><div style="clear:both"></section>
<h1><?php echo lang('ALL_ARTICLES');?></h1>
<section id="artList"><?php echo $others->prepare_others($db); ?><div style="clear:both"></section>
</div>


Here is my relevant CSS:

#articlebar {
position:absolute;
top:0;
bottom:0;
right:0;
width:200px;
background: #595959;
color:#f8f8f8;
overflow-y: hidden;
}
#archiveSpace, #tagSpace, #artList {
background:#d6d6d6;
margin:0 5px;
padding: 3px 2px;
max-height:150px;
overflow-y: auto;
}
#artList {
overflow-y:auto;
max-height: none;
clear:both;
}
#artList a:hover, #artList a:active {
background: #ffffff;
}
#archiveSpace a, #tagSpace a {
background: #f8f8f8;
color: #363636;
padding: 3px 10px;
margin: 3px;
font-size: 12pt;
height:18px;
float:left;
display:block;
text-decoration: none;
}
#archiveSpace a:hover, #archiveSpace a:active, #tagSpace a:hover, #tagSpace a:active {
background:#ffffff;
text-decoration: underline;
}


Here is my complete project on the GitHub for fuller refference:
https://github.com/DavidSili/MySITE
The files cited here are views/blog.php and css/style.css

Thank you in advance.

Answer

I'd suggest using CSS Flexbox. This allows for a very versatile layout, and is new but widelyy supported.

It requires a combination of flex-shrink (everything you want to "shrink" to its calculated height) for the top two divs and the headers with flex-grow for the last one (everything you want to "grow" or expand to fill the space).

See the example below for a full working example.

/* flex-box specific properties */
#parent {
  display: flex;
  flex-direction: column;
}
#child1, #child2 {
  flex-shrink: 1;
  flex-basis: auto;
}
#child3 {
  flex-grow: 1;
}

/* other properties to make this snippet look good */
* {
  box-sizing: border-box;
}
html, body, #parent {
  height: 100%;
  padding: 0;
  margin: 0;
}
#parent {
  background-color: grey;
}
#parent > div {
  background-color: lightgrey;
  margin: 10px;
}
#child1, #child2 {
  resize: vertical;
  overflow: auto;
}
<div id="parent">
  <div id="child1">Resize this</div>
  <div id="child2">Resize this</div>
  <div id="child3">This will take up rest of space</div>
</div>

Comments