6

I've a div that I'd like to maximise the size of, within a parent that's based on a 100vh.

The problem being that I have two p divs that can also change their height based on the width of the window, leading to a varying size.

Now the quick and dirty solution might simply be to run a jQuery snippet to detect the sizes of the parent div and p divs and set the div's height based on these, running the function on doc.ready and on window.onresize.

But that feels unnecessary, and I'm wondering if there's a neater solution using only CSS that I'm unaware of?

I've set a simplified, but non-working version of the problem below to see if you can get a clearer idea than what I'm referring to.

Any tips would be great, thanks!

*{
  margin: 0;
  padding: 0;
  font-family: Arial, san-serif;
}

#parent{
  height: 100vh;
  background: lightblue;
}

p{
  font-size: 40px; 
  background: yellow;
 }

#p1{
  top: 0;
}

#p2{
  bottom: 0;
  position: absolute;
}

div{
  background-color: red;
  height: 100%;
}
<div id="parent">
  <p id="p1">Long block that only appears on the top</p>
  <div>Maximising Div</div>
  <p id="p2">Long block that only appears on the bottom</p>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Finnb
  • 65
  • 5
  • 3
    have you checked out flexbox? I'm not sure if I understand what you are asking well enough to propose that as an answer, but I think that's what you are looking for. – kgiff Oct 13 '16 at 21:25
  • 1
    Flex box gives you this functionality - depends on what kind of browser support you need. Have a look at http://www.w3schools.com/css/css3_flexbox.asp. I can do an example if you need. – Craig Oct 13 '16 at 21:28

3 Answers3

3

You can achieve what you want with flexbox.

Since there are a lot of resources about how to use flexbox, it will not be included in the scope of this answer. However, I'll explain the basics so that you can understand what is going on here.

  1. You define a container, in this case #parent with the property display: flex;, this makes it a flex-container.
  2. This container's child elements are now flex-items, in your case the <p> elements and the <div> in the middle.
  3. We then let the middle <div> grow to fill the available space of the container with the shorthand property flex: 1;.

Code Snippet:

* {
  margin: 0;
  padding: 0;
  font-family: Arial, san-serif;
}
#parent {
  height: 100vh;
  background: lightblue;
  display: flex;
  flex-direction: column;
}
p {
  font-size: 40px;
  background: yellow;
}
div > div {
  background-color: red;
  flex: 1;
}
<div id="parent">
  <p id="p1">Long block that only appears on the top</p>
  <div>Maximising Div</div>
  <p id="p2">Long block that only appears on the bottom</p>
</div>

Notes:

  • Check Michael's answer for current browser support.
Community
  • 1
  • 1
Ricky Ruiz
  • 25,455
  • 6
  • 44
  • 53
  • This'll do nicely, thanks to all the responses with the same! – Finnb Oct 13 '16 at 21:43
  • 1
    You're welcome! Make sure to look for Michael's posts about `flexbox` here in SO. He's a great contributor in this subject, as in many others. – Ricky Ruiz Oct 13 '16 at 21:45
2

*{
  margin: 0;
  padding: 0;
  font-family: Arial, san-serif;
}

#parent{
  height: 100vh;
  display: flex;              /* establish flex container */
  flex-direction: column;     /* stack child elements ("flex items") vertically */
  background: lightblue;
}

p{
  font-size: 40px; 
  background: yellow;
 }

#p1 { /* can be variable height */}

#p2 { /* can be variable height */ }

div {
  background-color: red;
  flex: 1;                    /* consume free space in container;
                                 will force p elements to top and bottom */
}
<div id="parent">
  <p id="p1">Long block that only appears on the top</p>
  <div>Maximising Div</div>
  <p id="p2">Long block that only appears on the bottom</p>
</div>

Browser support: Flexbox is supported by all major browsers, except IE < 10. Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes. For a quick way to add prefixes use Autoprefixer. More details in this answer.

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
0

Adding width: 100% to the <p> elements and setting body { overflow: hidden } to your current code provides the functionality you want if you can't use flexbox.

body{
  overflow: hidden;
}
*{
  margin: 0;
  padding: 0;
  font-family: Arial, san-serif;
}
#parent{
  height: 100vh;
  background: lightblue;
}
p{
  font-size: 40px; 
  background: yellow;
  width: 100%;
}
#p1{
  top: 0;
}
#p2{
  bottom: 0;
  position: absolute;
}
div{
  background-color: red;
  height: 100%;
}
<div id="parent">
  <p id="p1">Long block that only appears on the top</p>
  <div class="maximising">Maximising Div</div>
  <p id="p2">Long block that only appears on the bottom</p>
</div>
A1rPun
  • 16,287
  • 7
  • 57
  • 90