Good CSS practices for Responsive Height. Is it armengue or not?

8

I made this code that makes height responsive, it fits according to the size of the viewport. (Run the snippet and resize the screen.)

Since html and body have a height: 100% , I set up a basic skeleton with 3 divs and I have distributed that height:100% between them (as you can see in the snippet). After that, I gave position:absolute to each div and top according to the size of each.

Well, since I assign top to every div on the hand, I got the feeling that this could be a weapon, since if there are more divs , I'll have to do this calculation for top again. I think there are better ways to do this ...

So, in what other ways can I do this? This way I did, can it be considered an armengue?

html, body{
	width: 100%;
	height: 100%;
	margin: 0;
	padding: 0;
}

.div1{
	position: absolute;
	width: 100%;
	height: 10%;
	background: red;
}

.div2{
	position: absolute;
	top: 10%;
	width: 100%;
	height: 75%;
	background: green;
}

.div3{
	position: absolute;
	top: 85%;
	width: 100%;
	height: 15%;
	background: yellow;
}
<div class="principal">
	<div class="div1"></div>
	<div class="div2"></div>
	<div class="div3"></div>
</div>
    
asked by anonymous 03.08.2016 / 18:11

2 answers

12

There is no such thing as good practice, there are better ways, yes, but not all good practices.

Now the only thing I say I should avoid is to do integer layout based on position: absolute; , this is quite costly.

  

Note: what you really want is not necessarily responsive.

Apparently, the objective is simple and dispenses position , change height by min-height and so the content is larger it will adjust:

html, body{
    height: 100%;
    margin: 0;
    padding: 0;
}

.principal {
    height: 100%;
}

.div1{
    height: 10%;
    background: red;
}

.div2{
    min-height: 75%;
    background: green;
}

.div3{
    height: 15%;
    background: yellow;
}
<div class="principal">
    <div class="div1">a</div>
    <div class="div2">b</div>
    <div class="div3">c</div>
</div>

I've used min-height only in div2 which is where contents go, but if you need to adjust the others you can change the other attributes height by min-height , see result with lots of content:

html, body{
    height: 100%;
    margin: 0;
    padding: 0;
}

.principal {
    height: 100%;
}

.div1{
    height: 10%;
    background: red;
}

.div2{
    min-height: 75%;
    background: green;
}

.div3{
    height: 15%;
    background: yellow;
}
<div class="principal">
    <div class="div1">a</div>
    <div class="div2">
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
    </div>
    <div class="div3">c</div>
</div>

However this is not very responsive and it is complicated to set a height per pixel for example, so if you need to see the next ones (display: flex, display: table) suggestions

Using display: flex

In the case I would say that it would be best to use display: flex , this would be a functional example:

html,body {
    margin: 0;
    padding: 0;
    height: 100%;
}
body > .section {
   min-height: 100%;
}
.section {
    padding: 5px;
    box-sizing: border-box;
}
.header {
    padding: 5px;
    box-sizing: border-box;
    border: 2px #f00 solid;
    max-height: 46px;
}
.contents {
    border: 2px #fc0 solid;
}

.contents, .section {
    display: -webkit-flex;
    display: flex;
    flex-direction: column;
}

.header, .contents, .section {
    -webkit-flex: 1;  /* Safari 6.1+ */
        -ms-flex: 1;  /* IE 10 */
            flex: 1;
}
<div class="section">
    <div class="header">
        navbar, etc
    </div>
    <div class="contents">
        <h1>Teste</h1>

        <div class="section">
            <div class="header">
                navbar, etc
            </div>
            <div class="contents">
                <h1>Teste</h1>
            </div>
        </div>

    </div>
</div>

But the problem is that it is not supported by all browsers, see the support list on canIUse :

  • Safari 6, Safari iOS6: Supports only the old flexbox specification and does not support flex-wrap .
  • IE 10 Mobile: Supports only syntax 2012
  • IE 10 and IE 11 Partial support and several bugs
  • IE 8, IE 9 and Opera Mobile 12 do not support flex
  • Using display: table

    As an alternative to flex that works it would be interesting to use display: table , however this is more commonly used as a hack and the intended operation of display: table would actually be more to achieve effects as tabular data.

    The display: table also exhibits behavior that will limit or affect other elements, so it can not be used to pie and right

      

    Important note: Using display: table alone can lead to a number of unexpected behaviors (actually expected in tables), which will directly affect the content and make it much harder to work the layout, that to create other gambiarras in the attempt to correct this, so to avoid this type of situation always use table-row and table-cell .

    An example with

    html, body{
        margin: 0;
        padding: 0;
        height: 100%;
    }
    .section {
        width: 100%;
        height: 100%;
        border: 5px #00f solid;
        display: table;
        box-sizing: border-box;
    }
    .row {
        border: 5px #f00 solid;
        display: table-row;
    }
    .cell {
        display: table-cell;
    }
    .header {
        padding: 5px;
        box-sizing: border-box;
        border: 5px #000 solid;
        height: 46px;
    }
    .footer {
        padding: 5px;
        box-sizing: border-box;
        border: 5px #000 solid;
        height: 46px;
    }
    .contents {
        border: 5px #fc0 solid;
        height: 100%;
    }
    <div class="section">
        <div class="row">
            <div class="cell header">
            header
            </div>
        </div>
        <div class="row">
            <div class="cell contents">
    
                <div class="section">
                    <div class="row">
                        <div class="cell header">
                        header
                        </div>
                    </div>
                    <div class="row">
                        <div class="cell contents">
                        contents
                        </div>
                    </div>
                    <div class="row">
                        <div class="cell footer">
                        footer
                        </div>
                    </div>
                </div>
    
            </div>
        </div>
        <div class="row">
            <div class="cell footer">
            footer
            </div>
        </div>
    </div>

    Final grade

    There is no magic path or rule specifies, you define as you want and this will also vary from browser support, but I say one thing from my point of view, using 100% height may even look beautiful on a 15 screen and 17 inches, but larger screens may cause a weird emptiness effect, taking the main footer off the site (which would be cool to set at bottom) and background I would recommend not to worry about making the content stay 100% , something like this would suffice:

    html, body{
        margin: 0;
        padding: 0;
        height: 100%;
    }
    body > .main {
        position: relative;
        min-height: 100%;
    }
    body > .main > .footer {
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        background: #fc0;
    }
    .footer .content {
        padding: 15px;
    }
    <div class="main">
        <div class="section">
            <h1>teste</h1>
        </div>
        <div class="footer">
            <div class="content">teste</div>
        </div>
    </div>
        
    03.08.2016 / 18:49
    3

    You can optimize by doing this:

    html,
    body {
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
    }
    section {
      position: relative;
      display: table;
      height: 100%;
      width: 100%;
    }
    section div {
      float: left;
      width: 100%;
    }
    section div:first-child {
      height: 10%;
      background: red;
    }
    section div:nth-child(2) {
      height: 75%;
      background: green;
    }
    section div:last-child {
      height: 15%;
      background: yellow;
    }
    <section>
      <div></div>
      <div></div>
      <div></div>
    </section>
        
    03.08.2016 / 19:12