3

The goal

Set a div having 80% of the height of the parent that does not have a defined height. To be more specific, I want a responsive-effect.

The problem

I have five layers: .header, .site > .container > .right sidebar and .left content.

The height of the header is 50 pixels. The site's height is the viewport height - 50 pixels (from the header). Inside of the site's div, there is a container. I want to set his height to 80% of viewport height - 50 pixels from the header - the site's div offset (1.5em padding) and I'm not getting to work with percentage, only pixels — what I need to do?

The FiddleJS

The problem is illustrated here.

Technical details

Seems to work perfect, right? Yes, works perfeclty...... with pixels. Try to change the height of .left-content to 80% and you will see what is my problem.

The code (is the same of the FiddleJS)

HTML:

<div class="header">
</div>
<div class="site">
    <div class="container">
        <div class="container-head">
        </div>
        <div class="container-body">
            <div class="right-sidebar">
                Just a menu will be right here.
            </div>
            <div class="left-content">
                <ul>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                </ul>
            </div>
        </div>
    </div>
</div>

CSS:

body {
    font-family: Tahoma
}

.header {
    background-color: #49c98e;
    width: 100%;
    height: 50px;
}

.site {
    padding: 1.5em 0;
}

.container {
    background-color: #c7c7c7;
    width: 95%;
    margin: 0 auto;
    position: relative;
}

.right-sidebar {
    background-color: #a94cd5;
    width: 300px;
    height: 100%;
    position: absolute;
    right: 0;
}

.left-content {
    background-color: #dbdbdb;
    width: 100%;
    height: 500px;
    overflow-y: scroll;
}

.left-content ul {
    padding: 25px 0;
    float: left;
}

.left-content ul li {
    background-color: #a94cd5;
    width: 150px;
    height: 100px;
    float: left;
    margin: 15px;
    list-style: none;
}

jQuery/JavaScript:

function calculateResponsiveWidth() {
    $realWidth = $(".container").width() - $(".right-sidebar").outerWidth(),
    $containerContent = $(".left-content");

    $containerContent.css({
        "width": $realWidth
    });
}

$(window).on("resize", function () {
    calculateResponsiveWidth();
});

calculateResponsiveWidth();

Thanks in advance.

Update v1

I'm beginning to think that using percentage is not the best option. After the container area I want a spacing of 25 pixels — and with percentage it was not maintained in the different resolutions.

There was a Media Query suggestion, but I need an alternative to Internet Explorer 8 — Someone have a guess? Maybe JavaScript could resolve my problem?

Update v2

The problem was resolved with a bit of JavaScript, math and logic. Thanks to all who contributed!

Guilherme Oderdenge
  • 4,935
  • 6
  • 61
  • 96

3 Answers3

1

You need to set height:100%; on the html, body, and site div in order for the height:80% to be understood when applied to the container div. When you do this, the fiddle works for me.

http://jsfiddle.net/fvU5d/3/

Unless you meant that you want the container div to be 80% of the site div, not 80% of viewport.

EDIT

Try this (http://jsfiddle.net/fvU5d/5/):

var newHeight = $(window).height() - 50;
newHeight = newHeight + 'px';
$('.site').css('height',newHeight);
smilebomb
  • 5,123
  • 8
  • 49
  • 81
0

No heights are set for it's parent, It's 80% of ???. The css doesn't know what 100% is.

I changed the height to 80% and added a height to it's parent.

http://jsfiddle.net/fvU5d/1/

.container-body{
    height: 600px;
}
.left-content {
    background-color: #dbdbdb;
    width: 100%;
    height: 80%;
    overflow-y: scroll;
}
Smeegs
  • 9,151
  • 5
  • 42
  • 78
0

FOR REACT

If the parent div has an unknown height, your best bet is to calculate the height of the parent before using percentages. This then means that you have control of the height of the parent, so can size the child accordingly.

JS Fiddle:

https://jsfiddle.net/SNicholson99/hbw83z5L/

Calculate the height of the parent:

document.getElementById('div-to-calculate').clientHeight

This line alone will only get the height of the div on the first render. In order to recalculate the height of the div on resize of the window, we need to do some more work.

  1. Store the height in state.
  2. Create an addEventListener which listens to the resize of the window and updates the height state on change.
  3. Set the height on the height of the parent that you are calculating, so that it has a defined height.

Your code should look something like this:

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      height: null
    }
  }

  calculateHeight = () => {
    this.setState({height: null}, () => {
      const height = document.getElementById('div-to-calculate').clientHeight;
      this.setState({ height })
    });
  }

  componentDidMount() {
    this.calculateHeight();
    window.addEventListener("resize", this.calculateHeight);
  }

   componentWillUnmount() {
     window.removeEventListener("resize", this.calculateHeight);
   }


  render() {
    return (
      <div style={{display: 'flex', flexDirection: 'column', minHeight: '100vh'}}>
        <div style={{flex: '0 0 50px', backgroundColor: 'blue'}}>Header</div>
        <div id="div-to-calculate" style={{
          flex: '1 0 auto',
          height: this.state.height ? `${this.state.height}px` : null
        }}>

          <div style={{ display: 'flex', height: '100%' }}>
            <div style={{ flex: '1 0 auto', backgroundColor: 'yellow' }}>
              <div style={{
                textAlign: 'center',
                width: '250px',
                margin: '0 auto',
                border: '1px solid black',
                position: 'relative',
                top: '50%',
                transform:'translateY(-50%)'
              }}>
                Middle Section
              </div>
            </div>
          </div>
        </div>
        <div style={{ flex: '0 0 50px', backgroundColor: 'blue'}}>Footer</div>
      </div>
    );
  }
}