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>